All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.swirlds.logging.api.internal.level.HandlerLoggingLevelConfig Maven / Gradle / Ivy

Go to download

Swirlds is a software platform designed to build fully-distributed applications that harness the power of the cloud without servers. Now you can develop applications with fairness in decision making, speed, trust and reliability, at a fraction of the cost of traditional server-based platforms.

There is a newer version: 0.56.5
Show newest version
/*
 * Copyright (C) 2023-2024 Hedera Hashgraph, LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.swirlds.logging.api.internal.level;

import static com.swirlds.logging.utils.ConfigUtils.configValueOrElse;

import com.swirlds.config.api.Configuration;
import com.swirlds.logging.api.Level;
import com.swirlds.logging.api.Marker;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * This configuration class enables the customization of logging levels for loggers, allowing users to specify levels
 * for either packages or individual classes. The configuration is read from the {@link Configuration} object.
 * 

* Like for example in spring boot a configuration like this can be used: *

* {@code logging.level.com.swirlds=DEBUG} *

* In that case all packages and classes under the package {@code com.swirlds} will be configured to use the level * DEBUG. If a more specific configuration is defined, that configuration will be used instead. For example: *

* {@code logging.level.com.swirlds.logging.api=INFO} *

* In that case all packages and classes under the package {@code com.swirlds.logging.api} will be configured to use the * level INFO. */ public class HandlerLoggingLevelConfig { private static final String PROPERTY_LOGGING_LEVEL = "logging.level"; private static final String PROPERTY_LOGGING_HANDLER_LEVEL = "logging.handler.%s.level"; private static final String PROPERTY_PACKAGE_LEVEL = "%s."; private static final String PROPERTY_LOGGING_MARKER = "logging.marker"; private static final String PROPERTY_LOGGING_HANDLER_MARKER = "logging.handler.%s.marker"; private static final String PROPERTY_LOGGING_HANDLER_INHERIT_LEVELS = "logging.handler.%s.inheritLevels"; private static final Level DEFAULT_LEVEL = Level.INFO; /** * The cache for the levels. */ private final Map levelCache = new ConcurrentHashMap<>(); /** * The cache for the markers. */ private final Map markerConfigCache; /** * The configuration properties. */ private final Map levelConfigProperties; private HandlerLoggingLevelConfig( Map markerConfigCache, Map levelConfigProperties) { this.markerConfigCache = Collections.unmodifiableMap(markerConfigCache); this.levelConfigProperties = Collections.unmodifiableMap(levelConfigProperties); } /** * Creates a new logging level configuration based on the given configuration and handler name. * * @param configuration The configuration. */ public static HandlerLoggingLevelConfig create(final Configuration configuration) { return create(configuration, null); } /** * Extracts the configuration for the given handler name based on the given configuration. * * @param configuration The configuration. * @param handlerName The name of the handler. */ @NonNull public static HandlerLoggingLevelConfig create( @NonNull final Configuration configuration, @Nullable final String handlerName) { Objects.requireNonNull(configuration, "configuration must not be null"); final ConfigLevel defaultLevel = configValueOrElse(configuration, PROPERTY_LOGGING_LEVEL, ConfigLevel.class, ConfigLevel.UNDEFINED); final Boolean inheritLevels = configValueOrElse( configuration, PROPERTY_LOGGING_HANDLER_INHERIT_LEVELS.formatted(handlerName), Boolean.class, Boolean.TRUE); final String propertyHandler = PROPERTY_LOGGING_HANDLER_LEVEL.formatted(handlerName); final ConfigLevel defaultHandlerLevel; if (handlerName != null) { defaultHandlerLevel = configValueOrElse(configuration, propertyHandler, ConfigLevel.class, ConfigLevel.UNDEFINED); } else { defaultHandlerLevel = ConfigLevel.UNDEFINED; } final Map levelConfigProperties = new HashMap<>(); final Map markerConfigStore = new HashMap<>(); if (defaultLevel == ConfigLevel.UNDEFINED && defaultHandlerLevel == ConfigLevel.UNDEFINED) { levelConfigProperties.put("", DEFAULT_LEVEL); } else if (defaultHandlerLevel != ConfigLevel.UNDEFINED) { levelConfigProperties.put("", defaultHandlerLevel.level()); } else { if (Boolean.TRUE.equals(inheritLevels)) { levelConfigProperties.put("", defaultLevel.level()); } else { levelConfigProperties.put("", DEFAULT_LEVEL); } } if (Boolean.TRUE.equals(inheritLevels)) { levelConfigProperties.putAll(readLevels(PROPERTY_LOGGING_LEVEL, configuration)); markerConfigStore.putAll(readMarkers(PROPERTY_LOGGING_MARKER, configuration)); } if (handlerName != null) { levelConfigProperties.putAll(readLevels(propertyHandler, configuration)); markerConfigStore.putAll( readMarkers(PROPERTY_LOGGING_HANDLER_MARKER.formatted(handlerName), configuration)); } return new HandlerLoggingLevelConfig(markerConfigStore, levelConfigProperties); } @NonNull private static Map readMarkers( @NonNull final String prefix, @NonNull final Configuration configuration) { final Map result = new HashMap<>(); final String fullPrefix = PROPERTY_PACKAGE_LEVEL.formatted(prefix); configuration.getPropertyNames().filter(n -> n.startsWith(fullPrefix)).forEach(configPropertyName -> { final String name = configPropertyName.substring(fullPrefix.length()); final MarkerState markerState = configuration.getValue(configPropertyName, MarkerState.class, MarkerState.UNDEFINED); result.put(name, markerState); }); return result; } /** * Reads the levels from the given configuration. * * @param prefix prefix of the configuration property * @param configuration current configuration * @return map of levels and package names */ @NonNull private static Map readLevels( @NonNull final String prefix, @NonNull final Configuration configuration) { final Map result = new HashMap<>(); final String fullPrefix = PROPERTY_PACKAGE_LEVEL.formatted(prefix); configuration.getPropertyNames().filter(n -> n.startsWith(fullPrefix)).forEach(configPropertyName -> { final String name = configPropertyName.substring(fullPrefix.length()); final ConfigLevel level = configuration.getValue(configPropertyName, ConfigLevel.class, ConfigLevel.UNDEFINED); if (level != null && level != ConfigLevel.UNDEFINED) { result.put(name, level.level()); } }); return Collections.unmodifiableMap(result); } /** * Returns true if the given level is enabled for the given name. * * @param name The name of the logger. * @param level The level. * @return True if the given level is enabled for the given name. */ public boolean isEnabled(@NonNull final String name, @NonNull final Level level) { final Level enabledLevel = levelCache.computeIfAbsent(name, this::getConfiguredLevel); return enabledLevel.enabledLoggingOfLevel(level); } public boolean isEnabled(@NonNull final String name, @NonNull final Level level, @Nullable final Marker marker) { if (marker != null) { final List allMarkerNames = marker.getAllMarkerNames(); boolean isEnabled = false; boolean found = false; for (String markerName : allMarkerNames) { final MarkerState markerState = markerConfigCache.get(markerName); if (MarkerState.ENABLED.equals(markerState)) { isEnabled = true; found = true; break; } else if (MarkerState.DISABLED.equals(markerState)) { found = true; } } if (found) { return isEnabled; } } return isEnabled(name, level); } @NonNull private Level getConfiguredLevel(@NonNull final String name) { Level configLevel = levelConfigProperties.get(name); if (configLevel != null) { return configLevel; } final StringBuilder buffer = new StringBuilder(name); for (int i = buffer.length() - 1; i > 0; i--) { if ('.' == buffer.charAt(i)) { buffer.setLength(i); configLevel = levelConfigProperties.get(buffer.toString()); if (configLevel != null) { return configLevel; } } } return levelConfigProperties.get(""); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy