diff --git a/rlib-logger-api/src/main/java/javasabr/rlib/logger/api/Logger.java b/rlib-logger-api/src/main/java/javasabr/rlib/logger/api/Logger.java index 7dacd5ec..195b7af2 100644 --- a/rlib-logger-api/src/main/java/javasabr/rlib/logger/api/Logger.java +++ b/rlib-logger-api/src/main/java/javasabr/rlib/logger/api/Logger.java @@ -431,26 +431,66 @@ default void info(A arg1, B arg2, C arg3, D arg4, @NonNull N4Factor } /** - * Check of enabling the logger level. + * Checks whether logging is enabled at the specified level. + * + * @param level the log level + * @return true if logging is enabled, false otherwise + * @since 10.0.0 */ default boolean enabled(@NonNull LoggerLevel level) { return level.enabled(); } /** - * Check of enabling the warning level. + * Checks whether logging is enabled at the error level. + * + * @return true if logging is enabled, false otherwise + * @since 10.0.0 + */ + default boolean errorEnabled() { + return enabled(LoggerLevel.ERROR); + } + + /** + * Checks whether logging is enabled at the warning level. + * + * @return true if logging is enabled, false otherwise + * @since 10.0.0 */ - default boolean warningEnabled() { + default boolean warnEnabled() { return enabled(LoggerLevel.WARNING); } /** - * Check of enabling the debug level. + * Checks whether logging is enabled at the info level. + * + * @return true if logging is enabled, false otherwise + * @since 10.0.0 + */ + default boolean infoEnabled() { + return enabled(LoggerLevel.INFO); + } + + /** + * Checks whether logging is enabled at the debug level. + * + * @return true if logging is enabled, false otherwise + * @since 10.0.0 */ default boolean debugEnabled() { return enabled(LoggerLevel.DEBUG); } + /** + * Checks whether logging is enabled at the trace level. + * + * @return true if logging is enabled, false otherwise + * @since 10.0.0 + */ + default boolean traceEnabled() { + return enabled(LoggerLevel.TRACE); + } + /** * Override the enabling status of the logger level. */ diff --git a/rlib-logger-api/src/main/java/javasabr/rlib/logger/api/LoggerManager.java b/rlib-logger-api/src/main/java/javasabr/rlib/logger/api/LoggerManager.java index 859e03cd..aa8cf36c 100644 --- a/rlib-logger-api/src/main/java/javasabr/rlib/logger/api/LoggerManager.java +++ b/rlib-logger-api/src/main/java/javasabr/rlib/logger/api/LoggerManager.java @@ -16,7 +16,7 @@ public class LoggerManager { static { - String className = System.getProperty("com.ss.rlib.logger.factory", ""); + String className = System.getProperty("javasabr.rlib.logger.factory", ""); Class implementation = null; if (!className.isEmpty()) { diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/DefaultLogger.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/DefaultLogger.java index 5e1a75c3..ce9b5d1f 100644 --- a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/DefaultLogger.java +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/DefaultLogger.java @@ -6,7 +6,7 @@ import javasabr.rlib.logger.api.Logger; import javasabr.rlib.logger.api.LoggerLevel; import javasabr.rlib.logger.api.LoggerService; -import javasabr.rlib.logger.impl.config.LogMessageConsumer; +import javasabr.rlib.logger.impl.config.consumer.LogMessageConsumer; import lombok.AccessLevel; import lombok.experimental.FieldDefaults; import org.jspecify.annotations.Nullable; diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/DefaultLoggerFactory.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/DefaultLoggerFactory.java index d532f2c3..263d0e9a 100644 --- a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/DefaultLoggerFactory.java +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/DefaultLoggerFactory.java @@ -3,7 +3,7 @@ import javasabr.rlib.logger.api.Logger; import javasabr.rlib.logger.api.LoggerFactory; import javasabr.rlib.logger.api.LoggerService; -import javasabr.rlib.logger.impl.config.LoggerConfigResolver; +import javasabr.rlib.logger.impl.config.loader.LoggerConfigResolver; import lombok.AccessLevel; import lombok.experimental.FieldDefaults; diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/DefaultLoggerService.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/DefaultLoggerService.java index 11c513e3..48221594 100644 --- a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/DefaultLoggerService.java +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/DefaultLoggerService.java @@ -8,8 +8,8 @@ import javasabr.rlib.logger.api.Logger; import javasabr.rlib.logger.api.LoggerLevel; import javasabr.rlib.logger.api.LoggerService; -import javasabr.rlib.logger.impl.config.LogMessageConsumer; import javasabr.rlib.logger.impl.config.LoggerConfig; +import javasabr.rlib.logger.impl.config.consumer.LogMessageConsumer; import lombok.AccessLevel; import lombok.experimental.FieldDefaults; diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/LoggerConfig.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/LoggerConfig.java index 833e8d43..4a126207 100644 --- a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/LoggerConfig.java +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/LoggerConfig.java @@ -3,6 +3,7 @@ import javasabr.rlib.collections.array.UnsafeArray; import javasabr.rlib.logger.api.Logger; import javasabr.rlib.logger.api.LoggerLevel; +import javasabr.rlib.logger.impl.config.consumer.LogMessageConsumer; /** * Configuration contract for logger levels and message consumers. diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/LoggerConfigResolver.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/LoggerConfigResolver.java deleted file mode 100644 index 1ddf7a5b..00000000 --- a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/LoggerConfigResolver.java +++ /dev/null @@ -1,36 +0,0 @@ -package javasabr.rlib.logger.impl.config; - -import java.util.Comparator; -import java.util.Optional; -import javasabr.rlib.collections.array.Array; -import javasabr.rlib.collections.array.ArrayCollectors; -import javasabr.rlib.logger.impl.config.impl.DefaultLoggerConfigLoader; - -/** - * Resolver of logger configuration from available loaders. - * - * @since 10.0.0 - */ -public class LoggerConfigResolver { - - private static final Array LOADERS = Array - .of(new DefaultLoggerConfigLoader()) - .stream() - .sorted(Comparator.comparingInt(LoggerConfigLoader::order)) - .collect(ArrayCollectors.toArray(LoggerConfigLoader.class)); - - /** - * Loads logger configuration. - * - * @return the loaded logger configuration - * @since 10.0.0 - */ - public static LoggerConfig load() { - return LOADERS - .stream() - .map(LoggerConfigLoader::tryToLoad) - .flatMap(Optional::stream) - .findFirst() - .orElseThrow(); - } -} diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/LogMessageConsumer.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/consumer/LogMessageConsumer.java similarity index 89% rename from rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/LogMessageConsumer.java rename to rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/consumer/LogMessageConsumer.java index c29c8f3c..ed6b6a02 100644 --- a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/LogMessageConsumer.java +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/consumer/LogMessageConsumer.java @@ -1,4 +1,4 @@ -package javasabr.rlib.logger.impl.config; +package javasabr.rlib.logger.impl.config.consumer; import javasabr.rlib.logger.api.Logger; import javasabr.rlib.logger.api.LoggerLevel; diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/impl/ConsoleMessageConsumer.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/consumer/impl/ConsoleMessageConsumer.java similarity index 78% rename from rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/impl/ConsoleMessageConsumer.java rename to rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/consumer/impl/ConsoleMessageConsumer.java index 08780274..81be6c05 100644 --- a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/impl/ConsoleMessageConsumer.java +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/consumer/impl/ConsoleMessageConsumer.java @@ -1,9 +1,9 @@ -package javasabr.rlib.logger.impl.config.impl; +package javasabr.rlib.logger.impl.config.consumer.impl; import javasabr.rlib.logger.api.Logger; import javasabr.rlib.logger.api.LoggerLevel; -import javasabr.rlib.logger.impl.config.LogMessageConsumer; -import javasabr.rlib.logger.impl.config.LogMessageRender; +import javasabr.rlib.logger.impl.config.consumer.LogMessageConsumer; +import javasabr.rlib.logger.impl.config.render.LogMessageRender; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import lombok.experimental.FieldDefaults; diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/consumer/impl/package-info.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/consumer/impl/package-info.java new file mode 100644 index 00000000..9f143992 --- /dev/null +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/consumer/impl/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package javasabr.rlib.logger.impl.config.consumer.impl; + +import org.jspecify.annotations.NullMarked; diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/consumer/package-info.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/consumer/package-info.java new file mode 100644 index 00000000..40e7516e --- /dev/null +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/consumer/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package javasabr.rlib.logger.impl.config.consumer; + +import org.jspecify.annotations.NullMarked; diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/impl/DefaultLoggerConfig.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/impl/DefaultLoggerConfig.java index 36b7890f..19074272 100644 --- a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/impl/DefaultLoggerConfig.java +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/impl/DefaultLoggerConfig.java @@ -7,8 +7,8 @@ import javasabr.rlib.logger.api.Logger; import javasabr.rlib.logger.api.LoggerLevel; import javasabr.rlib.logger.impl.DefaultLoggerService; -import javasabr.rlib.logger.impl.config.LogMessageConsumer; import javasabr.rlib.logger.impl.config.LoggerConfig; +import javasabr.rlib.logger.impl.config.consumer.LogMessageConsumer; public class DefaultLoggerConfig implements LoggerConfig { diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/impl/LoggerConfigBuilder.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/impl/LoggerConfigBuilder.java new file mode 100644 index 00000000..7dbff13b --- /dev/null +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/impl/LoggerConfigBuilder.java @@ -0,0 +1,46 @@ +package javasabr.rlib.logger.impl.config.impl; + +import javasabr.rlib.collections.array.Array; +import javasabr.rlib.collections.array.ArrayFactory; +import javasabr.rlib.collections.array.MutableArray; +import javasabr.rlib.collections.dictionary.DictionaryFactory; +import javasabr.rlib.collections.dictionary.MutableRefToRefDictionary; +import javasabr.rlib.logger.api.LoggerLevel; +import javasabr.rlib.logger.impl.config.LoggerConfig; +import javasabr.rlib.logger.impl.config.consumer.LogMessageConsumer; +import javasabr.rlib.logger.impl.config.impl.DefaultLoggerConfig.LoggerConsumersKey; +import javasabr.rlib.logger.impl.config.render.LogMessageRender; + +public class LoggerConfigBuilder { + + final MutableRefToRefDictionary loggerLevels; + final MutableRefToRefDictionary renders; + final MutableRefToRefDictionary consumers; + final MutableRefToRefDictionary> loggerConsumers; + + public LoggerConfigBuilder() { + this.loggerLevels = DictionaryFactory.mutableRefToRefDictionary(); + this.renders = DictionaryFactory.mutableRefToRefDictionary(); + this.consumers = DictionaryFactory.mutableRefToRefDictionary(); + this.loggerConsumers = DictionaryFactory.mutableRefToRefDictionary(); + } + + public void registerLoggerLevel(String loggerName, LoggerLevel level) { + loggerLevels.put(loggerName, level); + } + + public void registerLoggerConsumer(String loggerName, LoggerLevel level, LogMessageConsumer consumer) { + var key = new LoggerConsumersKey(loggerName, level); + loggerConsumers + .getOrCompute(key, () -> ArrayFactory.mutableArray(LogMessageConsumer.class)) + .add(consumer); + } + + public LoggerConfig build() { + var tempDictionary = DictionaryFactory + .>mutableRefToRefDictionary(); + loggerConsumers.forEach((key, consumers) -> + tempDictionary.put(key, Array.copyOf(consumers))); + return new DefaultLoggerConfig(loggerLevels.toReadOnly(), tempDictionary.toReadOnly()); + } +} diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/LoggerConfigLoader.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/loader/LoggerConfigLoader.java similarity index 69% rename from rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/LoggerConfigLoader.java rename to rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/loader/LoggerConfigLoader.java index e9bff195..702ddd1c 100644 --- a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/LoggerConfigLoader.java +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/loader/LoggerConfigLoader.java @@ -1,6 +1,7 @@ -package javasabr.rlib.logger.impl.config; +package javasabr.rlib.logger.impl.config.loader; import java.util.Optional; +import javasabr.rlib.logger.impl.config.LoggerConfig; /** * Loader of logger configuration. @@ -9,6 +10,10 @@ */ public interface LoggerConfigLoader { + int ORDER_NORMAL = 100; + int ORDER_LOW = 1000; + int ORDER_HIGH = 0; + /** * Tries to load logger configuration. * diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/loader/LoggerConfigLoadersProvider.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/loader/LoggerConfigLoadersProvider.java new file mode 100644 index 00000000..26691d3d --- /dev/null +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/loader/LoggerConfigLoadersProvider.java @@ -0,0 +1,19 @@ +package javasabr.rlib.logger.impl.config.loader; + +import javasabr.rlib.collections.array.Array; + +/** + * Provider of additional logger configuration loaders. + * + * @since 10.0.0 + */ +public interface LoggerConfigLoadersProvider { + + /** + * Returns additional logger configuration loaders. + * + * @return the logger configuration loaders + * @since 10.0.0 + */ + Array getLoggerConfigLoaders(); +} diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/loader/LoggerConfigResolver.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/loader/LoggerConfigResolver.java new file mode 100644 index 00000000..1e363748 --- /dev/null +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/loader/LoggerConfigResolver.java @@ -0,0 +1,48 @@ +package javasabr.rlib.logger.impl.config.loader; + +import java.util.Comparator; +import java.util.Optional; +import java.util.ServiceLoader; +import javasabr.rlib.collections.array.Array; +import javasabr.rlib.collections.array.ArrayCollectors; +import javasabr.rlib.collections.array.ArrayFactory; +import javasabr.rlib.logger.impl.config.LoggerConfig; +import javasabr.rlib.logger.impl.config.loader.impl.DefaultLoggerConfigLoader; +import javasabr.rlib.logger.impl.config.loader.impl.PropertyLoggerConfigLoader; + +/** + * Resolver of logger configuration from available loaders. + * + * @since 10.0.0 + */ +public class LoggerConfigResolver { + + private static final Array LOADERS; + + static { + var registeredProviders = ArrayFactory.mutableArray(LoggerConfigLoader.class); + registeredProviders.add(new DefaultLoggerConfigLoader()); + registeredProviders.add(new PropertyLoggerConfigLoader()); + for (var provider : ServiceLoader.load(LoggerConfigLoadersProvider.class)) { + registeredProviders.addAll(provider.getLoggerConfigLoaders()); + } + LOADERS = registeredProviders.stream() + .sorted(Comparator.comparingInt(LoggerConfigLoader::order)) + .collect(ArrayCollectors.toArray(LoggerConfigLoader.class)); + } + + /** + * Loads logger configuration. + * + * @return the loaded logger configuration + * @since 10.0.0 + */ + public static LoggerConfig load() { + return LOADERS + .stream() + .map(LoggerConfigLoader::tryToLoad) + .flatMap(Optional::stream) + .findFirst() + .orElseThrow(); + } +} diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/impl/DefaultLoggerConfigLoader.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/loader/impl/DefaultLoggerConfigLoader.java similarity index 72% rename from rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/impl/DefaultLoggerConfigLoader.java rename to rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/loader/impl/DefaultLoggerConfigLoader.java index 659f7e48..725bad75 100644 --- a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/impl/DefaultLoggerConfigLoader.java +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/loader/impl/DefaultLoggerConfigLoader.java @@ -1,14 +1,17 @@ -package javasabr.rlib.logger.impl.config.impl; +package javasabr.rlib.logger.impl.config.loader.impl; import java.util.Optional; import javasabr.rlib.collections.array.Array; import javasabr.rlib.collections.dictionary.RefToRefDictionary; import javasabr.rlib.logger.api.LoggerLevel; import javasabr.rlib.logger.impl.DefaultLoggerService; -import javasabr.rlib.logger.impl.config.LogMessageConsumer; import javasabr.rlib.logger.impl.config.LoggerConfig; -import javasabr.rlib.logger.impl.config.LoggerConfigLoader; +import javasabr.rlib.logger.impl.config.consumer.LogMessageConsumer; +import javasabr.rlib.logger.impl.config.consumer.impl.ConsoleMessageConsumer; +import javasabr.rlib.logger.impl.config.impl.DefaultLoggerConfig; import javasabr.rlib.logger.impl.config.impl.DefaultLoggerConfig.LoggerConsumersKey; +import javasabr.rlib.logger.impl.config.loader.LoggerConfigLoader; +import javasabr.rlib.logger.impl.config.render.impl.SimpleLogMessageRender; public class DefaultLoggerConfigLoader implements LoggerConfigLoader { @@ -17,11 +20,9 @@ public Optional tryToLoad() { RefToRefDictionary loggerLevels = RefToRefDictionary.of( DefaultLoggerService.ROOT_LOGGER_NAME, LoggerLevel.INFO); - RefToRefDictionary> loggerConsumers = RefToRefDictionary.of( DefaultLoggerConfig.ROOT_INFO_CONSUMERS_KEY, Array.of(new ConsoleMessageConsumer(new SimpleLogMessageRender()))); - return Optional.of(new DefaultLoggerConfig(loggerLevels, loggerConsumers)); } diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/loader/impl/PropertyLoggerConfigLoader.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/loader/impl/PropertyLoggerConfigLoader.java new file mode 100644 index 00000000..2d1d4d04 --- /dev/null +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/loader/impl/PropertyLoggerConfigLoader.java @@ -0,0 +1,72 @@ +package javasabr.rlib.logger.impl.config.loader.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Optional; +import java.util.Properties; +import javasabr.rlib.logger.api.LoggerLevel; +import javasabr.rlib.logger.impl.DefaultLoggerService; +import javasabr.rlib.logger.impl.config.LoggerConfig; +import javasabr.rlib.logger.impl.config.consumer.impl.ConsoleMessageConsumer; +import javasabr.rlib.logger.impl.config.impl.LoggerConfigBuilder; +import javasabr.rlib.logger.impl.config.loader.LoggerConfigLoader; +import javasabr.rlib.logger.impl.config.render.LogMessageRender; +import javasabr.rlib.logger.impl.config.render.impl.SimpleLogMessageRender; +import javasabr.rlib.logger.impl.config.render.impl.pattern.PatternLogMessageRender; + +public class PropertyLoggerConfigLoader implements LoggerConfigLoader { + + public static final String FILE_MAIN = "rlib.logger.properties"; + public static final String FILE_TEST = "rlib.logger-test.properties"; + + @Override + public Optional tryToLoad() { + ClassLoader classLoader = Thread + .currentThread() + .getContextClassLoader(); + InputStream propertiesStream = classLoader.getResourceAsStream(FILE_TEST); + if (propertiesStream == null) { + propertiesStream = classLoader.getResourceAsStream(FILE_MAIN); + } + if (propertiesStream == null) { + return Optional.empty(); + } + Properties properties = new Properties(); + try (var source = propertiesStream) { + properties.load(source); + } catch (IOException ex) { + return Optional.empty(); + } + LoggerConfig loggerConfig = loadFromProperties(properties); + properties.clear(); + return Optional.of(loggerConfig); + } + + LoggerConfig loadFromProperties(Properties properties) { + var builder = new LoggerConfigBuilder(); + LogMessageRender messageRender = null; + for (Object key : properties.keySet()) { + String stringKey = (String) key; + if (stringKey.startsWith("logger.level.")) { + LoggerLevel level = LoggerLevel.valueOf(properties.getProperty(stringKey)); + String loggerName = stringKey.substring("logger.level.".length()); + builder.registerLoggerLevel(loggerName, level); + } else if (stringKey.equals("logger.message.pattern")) { + messageRender = new PatternLogMessageRender(properties.getProperty(stringKey)); + } + } + if (messageRender == null) { + messageRender = new SimpleLogMessageRender(); + } + builder.registerLoggerConsumer( + DefaultLoggerService.ROOT_LOGGER_NAME, + LoggerLevel.TRACE, + new ConsoleMessageConsumer(messageRender)); + return builder.build(); + } + + @Override + public int order() { + return LoggerConfigLoader.ORDER_NORMAL; + } +} diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/loader/impl/package-info.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/loader/impl/package-info.java new file mode 100644 index 00000000..2c2cc3d6 --- /dev/null +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/loader/impl/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package javasabr.rlib.logger.impl.config.loader.impl; + +import org.jspecify.annotations.NullMarked; diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/loader/package-info.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/loader/package-info.java new file mode 100644 index 00000000..a52efece --- /dev/null +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/loader/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package javasabr.rlib.logger.impl.config.loader; + +import org.jspecify.annotations.NullMarked; diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/LogMessageRender.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/LogMessageRender.java similarity index 90% rename from rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/LogMessageRender.java rename to rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/LogMessageRender.java index 285430e9..696adde1 100644 --- a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/LogMessageRender.java +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/LogMessageRender.java @@ -1,4 +1,4 @@ -package javasabr.rlib.logger.impl.config; +package javasabr.rlib.logger.impl.config.render; import javasabr.rlib.logger.api.Logger; import javasabr.rlib.logger.api.LoggerLevel; diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/impl/SimpleLogMessageRender.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/SimpleLogMessageRender.java similarity index 81% rename from rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/impl/SimpleLogMessageRender.java rename to rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/SimpleLogMessageRender.java index ea5705a7..003eeb07 100644 --- a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/impl/SimpleLogMessageRender.java +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/SimpleLogMessageRender.java @@ -1,10 +1,10 @@ -package javasabr.rlib.logger.impl.config.impl; +package javasabr.rlib.logger.impl.config.render.impl; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import javasabr.rlib.logger.api.Logger; import javasabr.rlib.logger.api.LoggerLevel; -import javasabr.rlib.logger.impl.config.LogMessageRender; +import javasabr.rlib.logger.impl.config.render.LogMessageRender; import lombok.AccessLevel; import lombok.experimental.FieldDefaults; @@ -20,9 +20,9 @@ public SimpleLogMessageRender() { @Override public String render(LoggerLevel level, Logger logger, String message) { var timestamp = timeFormatter.format(LocalDateTime.now()); - return level.title() + return timestamp + ' ' + + level.title() + level.offset() + ' ' - + timestamp + ' ' + logger.shortName() + ": " + message; } diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/package-info.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/package-info.java new file mode 100644 index 00000000..9ee0d1ef --- /dev/null +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package javasabr.rlib.logger.impl.config.render.impl; + +import org.jspecify.annotations.NullMarked; diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/PatternLogMessageRender.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/PatternLogMessageRender.java new file mode 100644 index 00000000..5e2e8fe7 --- /dev/null +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/PatternLogMessageRender.java @@ -0,0 +1,37 @@ +package javasabr.rlib.logger.impl.config.render.impl.pattern; + +import javasabr.rlib.collections.array.UnsafeArray; +import javasabr.rlib.logger.api.Logger; +import javasabr.rlib.logger.api.LoggerLevel; +import javasabr.rlib.logger.impl.config.render.LogMessageRender; +import javasabr.rlib.logger.impl.config.render.impl.pattern.node.PatternRenderNode; +import lombok.AccessLevel; +import lombok.experimental.FieldDefaults; + +@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) +public class PatternLogMessageRender implements LogMessageRender { + + UnsafeArray renderNodes; + int initBufferSize; + + public PatternLogMessageRender(String pattern) { + this(pattern, 256); + } + + public PatternLogMessageRender(String pattern, int initBufferSize) { + this.initBufferSize = initBufferSize; + this.renderNodes = PatternRenderNodesParser + .parse(pattern) + .asUnsafe(); + } + + @Override + public String render(LoggerLevel level, Logger logger, String message) { + var buffer = new StringBuilder(initBufferSize); + for (PatternRenderNode renderNode : renderNodes.wrapped()) { + //noinspection DataFlowIssue + renderNode.append(level, logger, message, buffer); + } + return buffer.toString(); + } +} diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/PatternRenderNodesParser.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/PatternRenderNodesParser.java new file mode 100644 index 00000000..4073d1d3 --- /dev/null +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/PatternRenderNodesParser.java @@ -0,0 +1,89 @@ +package javasabr.rlib.logger.impl.config.render.impl.pattern; + +import javasabr.rlib.collections.array.Array; +import javasabr.rlib.collections.array.ArrayFactory; +import javasabr.rlib.logger.impl.config.render.impl.pattern.node.DateTimePatternRenderNode; +import javasabr.rlib.logger.impl.config.render.impl.pattern.node.LevelPatternRenderNode; +import javasabr.rlib.logger.impl.config.render.impl.pattern.node.MessagePatternRenderNode; +import javasabr.rlib.logger.impl.config.render.impl.pattern.node.PatternRenderNode; +import javasabr.rlib.logger.impl.config.render.impl.pattern.node.ShortLoggerPatternRenderNode; +import javasabr.rlib.logger.impl.config.render.impl.pattern.node.StringPatternRenderNode; + +public class PatternRenderNodesParser { + + public static Array parse(String pattern) { + var parsedNodes = ArrayFactory.mutableArray(PatternRenderNode.class); + var stringBuffer = new StringBuilder(); + for(int i = 0, length = pattern.length(); i < length; i++) { + char nextChar = pattern.charAt(i); + if (nextChar != '%') { + stringBuffer.append(nextChar); + continue; + } + if (!stringBuffer.isEmpty()) { + parsedNodes.add(new StringPatternRenderNode(stringBuffer.toString())); + stringBuffer.setLength(0); + } + var nodeName = resolveNodeName(pattern, i + 1); + var afterNameIndex = i + 1 + nodeName.length(); + ParsedNode parsedNode = parse(nodeName, pattern, afterNameIndex); + parsedNodes.add(parsedNode.renderNode); + i = parsedNode.finishedIndex - 1; + } + if (!stringBuffer.isEmpty()) { + parsedNodes.add(new StringPatternRenderNode(stringBuffer.toString())); + stringBuffer.setLength(0); + } + return Array.copyOf(parsedNodes); + } + + private static String resolveNodeName(String pattern, int startIndex) { + var result = new StringBuilder(); + for (int i = startIndex, length = pattern.length(); i < length; i++) { + char nextChar = pattern.charAt(i); + if (nextChar == '{' || nextChar == ' ' || nextChar == '\t') { + return result.toString(); + } + result.append(nextChar); + } + return result.toString(); + } + + private static ParsedNode parse(String nodeName, String pattern, int afterNameIndex) { + return switch (nodeName) { + case LevelPatternRenderNode.NODE_NAME -> new ParsedNode(new LevelPatternRenderNode(), afterNameIndex); + case MessagePatternRenderNode.NODE_NAME -> new ParsedNode(new MessagePatternRenderNode(), afterNameIndex); + case ShortLoggerPatternRenderNode.NODE_NAME -> new ParsedNode(new ShortLoggerPatternRenderNode(), afterNameIndex); + case DateTimePatternRenderNode.NODE_NAME -> { + var dateTimePattern = extractArgumentsString(pattern, afterNameIndex); + int finishedIndex = afterNameIndex + dateTimePattern.length() + 2; + yield new ParsedNode(new DateTimePatternRenderNode(dateTimePattern), finishedIndex); + } + default -> throw new IllegalArgumentException("Unexpected node name:[%s]".formatted(nodeName)); + }; + } + + private static String extractArgumentsString(String pattern, int afterNameIndex) { + if (pattern.length() <= afterNameIndex || pattern.charAt(afterNameIndex) != '{') { + throw new IllegalArgumentException("Missed '{' at position:[%d] in pattern:[%s]" + .formatted(afterNameIndex, pattern)); + } + var result = new StringBuilder(); + int closingBraceIndex = -1; + for (int i = afterNameIndex + 1, length = pattern.length(); i < length; i++) { + char nextChar = pattern.charAt(i); + if (nextChar == '}') { + closingBraceIndex = i; + break; + } + result.append(nextChar); + } + if (closingBraceIndex < 0) { + throw new IllegalArgumentException("Missed closing '}' in pattern:[%s]" + .formatted(pattern)); + } + return result.toString(); + } + + private record ParsedNode(PatternRenderNode renderNode, int finishedIndex) {} +} diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/DateTimePatternRenderNode.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/DateTimePatternRenderNode.java new file mode 100644 index 00000000..c82eac1f --- /dev/null +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/DateTimePatternRenderNode.java @@ -0,0 +1,29 @@ +package javasabr.rlib.logger.impl.config.render.impl.pattern.node; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import javasabr.rlib.logger.api.Logger; +import javasabr.rlib.logger.api.LoggerLevel; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.experimental.FieldDefaults; + +@EqualsAndHashCode(of = "pattern") +@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) +public class DateTimePatternRenderNode implements PatternRenderNode { + + public static final String NODE_NAME = "dateTime"; + + String pattern; + DateTimeFormatter formatter; + + public DateTimePatternRenderNode(String pattern) { + this.formatter = DateTimeFormatter.ofPattern(pattern); + this.pattern = pattern; + } + + @Override + public void append(LoggerLevel level, Logger logger, String message, StringBuilder buffer) { + buffer.append(formatter.format(LocalDateTime.now())); + } +} diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/LevelPatternRenderNode.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/LevelPatternRenderNode.java new file mode 100644 index 00000000..d70697c7 --- /dev/null +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/LevelPatternRenderNode.java @@ -0,0 +1,19 @@ +package javasabr.rlib.logger.impl.config.render.impl.pattern.node; + +import javasabr.rlib.logger.api.Logger; +import javasabr.rlib.logger.api.LoggerLevel; +import lombok.AccessLevel; +import lombok.experimental.FieldDefaults; + +@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) +public class LevelPatternRenderNode implements PatternRenderNode { + + public static final String NODE_NAME = "level"; + + @Override + public void append(LoggerLevel level, Logger logger, String message, StringBuilder buffer) { + buffer + .append(level.title()) + .append(level.offset()); + } +} diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/MessagePatternRenderNode.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/MessagePatternRenderNode.java new file mode 100644 index 00000000..f1bc17c0 --- /dev/null +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/MessagePatternRenderNode.java @@ -0,0 +1,17 @@ +package javasabr.rlib.logger.impl.config.render.impl.pattern.node; + +import javasabr.rlib.logger.api.Logger; +import javasabr.rlib.logger.api.LoggerLevel; +import lombok.AccessLevel; +import lombok.experimental.FieldDefaults; + +@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) +public class MessagePatternRenderNode implements PatternRenderNode { + + public static final String NODE_NAME = "msg"; + + @Override + public void append(LoggerLevel level, Logger logger, String message, StringBuilder buffer) { + buffer.append(message); + } +} diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/PatternRenderNode.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/PatternRenderNode.java new file mode 100644 index 00000000..f3b982aa --- /dev/null +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/PatternRenderNode.java @@ -0,0 +1,9 @@ +package javasabr.rlib.logger.impl.config.render.impl.pattern.node; + +import javasabr.rlib.logger.api.Logger; +import javasabr.rlib.logger.api.LoggerLevel; + +public interface PatternRenderNode { + + void append(LoggerLevel level, Logger logger, String message, StringBuilder buffer); +} diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/ShortLoggerPatternRenderNode.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/ShortLoggerPatternRenderNode.java new file mode 100644 index 00000000..1e42149f --- /dev/null +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/ShortLoggerPatternRenderNode.java @@ -0,0 +1,17 @@ +package javasabr.rlib.logger.impl.config.render.impl.pattern.node; + +import javasabr.rlib.logger.api.Logger; +import javasabr.rlib.logger.api.LoggerLevel; +import lombok.AccessLevel; +import lombok.experimental.FieldDefaults; + +@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) +public class ShortLoggerPatternRenderNode implements PatternRenderNode { + + public static final String NODE_NAME = "shortLogger"; + + @Override + public void append(LoggerLevel level, Logger logger, String message, StringBuilder buffer) { + buffer.append(logger.shortName()); + } +} diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/StringPatternRenderNode.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/StringPatternRenderNode.java new file mode 100644 index 00000000..300478c2 --- /dev/null +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/StringPatternRenderNode.java @@ -0,0 +1,21 @@ +package javasabr.rlib.logger.impl.config.render.impl.pattern.node; + +import javasabr.rlib.logger.api.Logger; +import javasabr.rlib.logger.api.LoggerLevel; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.RequiredArgsConstructor; +import lombok.experimental.FieldDefaults; + +@EqualsAndHashCode +@RequiredArgsConstructor +@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) +public class StringPatternRenderNode implements PatternRenderNode { + + String string; + + @Override + public void append(LoggerLevel level, Logger logger, String message, StringBuilder buffer) { + buffer.append(string); + } +} diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/package-info.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/package-info.java new file mode 100644 index 00000000..bfbc7838 --- /dev/null +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package javasabr.rlib.logger.impl.config.render.impl.pattern.node; + +import org.jspecify.annotations.NullMarked; diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/package-info.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/package-info.java new file mode 100644 index 00000000..d4ab06ee --- /dev/null +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/impl/pattern/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package javasabr.rlib.logger.impl.config.render.impl.pattern; + +import org.jspecify.annotations.NullMarked; diff --git a/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/package-info.java b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/package-info.java new file mode 100644 index 00000000..4d14873b --- /dev/null +++ b/rlib-logger-impl/src/main/java/javasabr/rlib/logger/impl/config/render/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package javasabr.rlib.logger.impl.config.render; + +import org.jspecify.annotations.NullMarked; diff --git a/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/DefaultLoggerTest.java b/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/DefaultLoggerTest.java index 70f5c333..8a1d5ac9 100644 --- a/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/DefaultLoggerTest.java +++ b/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/DefaultLoggerTest.java @@ -9,7 +9,7 @@ import javasabr.rlib.logger.api.Logger; import javasabr.rlib.logger.api.LoggerLevel; import javasabr.rlib.logger.api.LoggerManager; -import javasabr.rlib.logger.impl.config.LogMessageConsumer; +import javasabr.rlib.logger.impl.config.consumer.LogMessageConsumer; import javasabr.rlib.logger.impl.config.impl.DefaultLoggerConfig; import javasabr.rlib.logger.impl.config.impl.DefaultLoggerConfig.LoggerConsumersKey; import org.junit.jupiter.api.AfterEach; diff --git a/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/loader/impl/PropertyLoggerConfigLoaderTest.java b/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/loader/impl/PropertyLoggerConfigLoaderTest.java new file mode 100644 index 00000000..0ee88e25 --- /dev/null +++ b/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/loader/impl/PropertyLoggerConfigLoaderTest.java @@ -0,0 +1,295 @@ +package javasabr.rlib.logger.impl.config.loader.impl; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Map; +import java.util.Optional; +import java.util.Properties; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import javasabr.rlib.collections.array.Array; +import javasabr.rlib.collections.array.UnsafeArray; +import javasabr.rlib.logger.api.Logger; +import javasabr.rlib.logger.api.LoggerLevel; +import javasabr.rlib.logger.impl.DefaultLogger; +import javasabr.rlib.logger.impl.DefaultLoggerService; +import javasabr.rlib.logger.impl.config.LoggerConfig; +import javasabr.rlib.logger.impl.config.consumer.LogMessageConsumer; +import javasabr.rlib.logger.impl.config.consumer.impl.ConsoleMessageConsumer; +import javasabr.rlib.logger.impl.config.impl.DefaultLoggerConfig; +import javasabr.rlib.logger.impl.config.render.impl.SimpleLogMessageRender; +import javasabr.rlib.logger.impl.config.render.impl.pattern.PatternLogMessageRender; +import javasabr.rlib.logger.impl.config.render.impl.pattern.node.DateTimePatternRenderNode; +import javasabr.rlib.logger.impl.config.render.impl.pattern.node.LevelPatternRenderNode; +import javasabr.rlib.logger.impl.config.render.impl.pattern.node.MessagePatternRenderNode; +import javasabr.rlib.logger.impl.config.render.impl.pattern.node.PatternRenderNode; +import javasabr.rlib.logger.impl.config.render.impl.pattern.node.StringPatternRenderNode; +import org.junit.jupiter.api.Test; + +class PropertyLoggerConfigLoaderTest { + + @Test + void shouldLoadLoggerConfigCorrectly() throws IOException { + // given: + var loader = new PropertyLoggerConfigLoader(); + var in = PropertyLoggerConfigLoaderTest.class.getResourceAsStream("/property-loader-test-1.properties"); + var properties = new Properties(); + properties.load(in); + + // when: + LoggerConfig loggerConfig = loader.loadFromProperties(properties); + + // then: + assertThat(loggerConfig) + .isInstanceOf(DefaultLoggerConfig.class); + + // when: + var defaultLoggerConfig = (DefaultLoggerConfig) loggerConfig; + var loggerService = new DefaultLoggerService(loggerConfig); + DefaultLogger logger = loggerService.getLogger( + "javasabr.rlib.logger.impl.config.loader.impl.PropertyLoggerConfigLoaderTest"); + UnsafeArray consumers = defaultLoggerConfig.resolveConsumers( + logger, + LoggerLevel.TRACE); + + // then: + assertThat(consumers.size()) + .isEqualTo(1); + assertThat(consumers.get(0)) + .isInstanceOf(ConsoleMessageConsumer.class) + .extracting("logMessageRender") + .isInstanceOf(PatternLogMessageRender.class) + .extracting("renderNodes") + .extracting(object -> (UnsafeArray) object) + .returns(5, Array::size) + .returns(new DateTimePatternRenderNode("d.MM.yyyy HH:mm:ss:SSS"), nodes -> nodes.get(0)) + .returns(new StringPatternRenderNode(" "), nodes -> nodes.get(1)) + .returns(LevelPatternRenderNode.class, nodes -> nodes.get(2).getClass()) + .returns(new StringPatternRenderNode(" : "), nodes -> nodes.get(3)) + .returns(MessagePatternRenderNode.class, nodes -> nodes.get(4).getClass()); + + // when: + DefaultLogger loggerA = loggerService.getLogger( + "javasabr.rlib.logger.impl.config.loader.impl.PropertyLoggerConfigLoaderTest.A"); + DefaultLogger loggerB = loggerService.getLogger( + "javasabr.rlib.logger.impl.config.loader.impl.PropertyLoggerConfigLoaderTest.B"); + DefaultLogger loggerC = loggerService.getLogger( + "javasabr.rlib.logger.impl.config.loader.impl.PropertyLoggerConfigLoaderTest.C"); + DefaultLogger loggerD = loggerService.getLogger( + "javasabr.rlib.logger.impl.config.loader.impl.PropertyLoggerConfigLoaderTest.D"); + + // then: + assertThat(loggerA) + .returns(false, Logger::traceEnabled) + .returns(false, Logger::debugEnabled) + .returns(true, Logger::infoEnabled) + .returns(true, Logger::warnEnabled) + .returns(true, Logger::errorEnabled); + assertThat(loggerB) + .returns(false, Logger::traceEnabled) + .returns(true, Logger::debugEnabled) + .returns(true, Logger::infoEnabled) + .returns(true, Logger::warnEnabled) + .returns(true, Logger::errorEnabled); + assertThat(loggerC) + .returns(true, Logger::traceEnabled) + .returns(true, Logger::debugEnabled) + .returns(true, Logger::infoEnabled) + .returns(true, Logger::warnEnabled) + .returns(true, Logger::errorEnabled); + assertThat(loggerD) + .returns(false, Logger::traceEnabled) + .returns(false, Logger::debugEnabled) + .returns(false, Logger::infoEnabled) + .returns(false, Logger::warnEnabled) + .returns(true, Logger::errorEnabled); + } + + @Test + void shouldPreferTestPropertiesOverMainProperties() { + // given: + var loader = new PropertyLoggerConfigLoader(); + var contextClassLoader = new ResourceClassLoader(Map.of( + PropertyLoggerConfigLoader.FILE_TEST, "logger.level.ROOT=TRACE", + PropertyLoggerConfigLoader.FILE_MAIN, "logger.level.ROOT=ERROR")); + + // when: + Optional loadedConfig = withContextClassLoader(contextClassLoader, loader::tryToLoad); + + // then: + assertThat(loadedConfig).isPresent(); + + // when: + var loggerService = new DefaultLoggerService(loadedConfig.orElseThrow()); + DefaultLogger logger = loggerService.getLogger("example.logger"); + + // then: + assertThat(logger) + .returns(true, Logger::traceEnabled) + .returns(true, Logger::debugEnabled) + .returns(true, Logger::infoEnabled) + .returns(true, Logger::warnEnabled) + .returns(true, Logger::errorEnabled); + } + + @Test + void shouldFallbackToMainPropertiesWhenTestMissing() { + // given: + var loader = new PropertyLoggerConfigLoader(); + var contextClassLoader = new ResourceClassLoader(Map.of( + PropertyLoggerConfigLoader.FILE_MAIN, "logger.level.ROOT=ERROR")); + + // when: + Optional loadedConfig = withContextClassLoader(contextClassLoader, loader::tryToLoad); + + // then: + assertThat(loadedConfig).isPresent(); + + // when: + var loggerService = new DefaultLoggerService(loadedConfig.orElseThrow()); + DefaultLogger logger = loggerService.getLogger("example.logger"); + + // then: + assertThat(logger) + .returns(false, Logger::traceEnabled) + .returns(false, Logger::debugEnabled) + .returns(false, Logger::infoEnabled) + .returns(false, Logger::warnEnabled) + .returns(true, Logger::errorEnabled); + } + + @Test + void shouldReturnEmptyWhenNoPropertiesFound() { + // given: + var loader = new PropertyLoggerConfigLoader(); + var contextClassLoader = new ResourceClassLoader(Map.of()); + + // when: + Optional loadedConfig = withContextClassLoader(contextClassLoader, loader::tryToLoad); + + // then: + assertThat(loadedConfig).isEmpty(); + } + + @Test + void shouldUseRootLevelForUnconfiguredLogger() { + // given: + var loader = new PropertyLoggerConfigLoader(); + var contextClassLoader = new ResourceClassLoader(Map.of( + PropertyLoggerConfigLoader.FILE_MAIN, + "logger.level.ROOT=WARNING\nlogger.level.configured.logger=TRACE")); + + // when: + Optional loadedConfig = withContextClassLoader(contextClassLoader, loader::tryToLoad); + + // then: + assertThat(loadedConfig).isPresent(); + + // when: + var loggerService = new DefaultLoggerService(loadedConfig.orElseThrow()); + DefaultLogger unconfiguredLogger = loggerService.getLogger("unknown.logger"); + DefaultLogger configuredLogger = loggerService.getLogger("configured.logger"); + + // then: + assertThat(unconfiguredLogger) + .returns(false, Logger::traceEnabled) + .returns(false, Logger::debugEnabled) + .returns(false, Logger::infoEnabled) + .returns(true, Logger::warnEnabled) + .returns(true, Logger::errorEnabled); + assertThat(configuredLogger) + .returns(true, Logger::traceEnabled) + .returns(true, Logger::debugEnabled) + .returns(true, Logger::infoEnabled) + .returns(true, Logger::warnEnabled) + .returns(true, Logger::errorEnabled); + } + + @Test + void shouldUseSimpleMessageRenderWhenPatternIsAbsent() { + // given: + var loader = new PropertyLoggerConfigLoader(); + var properties = new Properties(); + properties.setProperty("logger.level.ROOT", "INFO"); + + // when: + LoggerConfig loggerConfig = loader.loadFromProperties(properties); + + // then: + assertThat(loggerConfig) + .isInstanceOf(DefaultLoggerConfig.class); + + // when: + var defaultLoggerConfig = (DefaultLoggerConfig) loggerConfig; + var loggerService = new DefaultLoggerService(loggerConfig); + DefaultLogger logger = loggerService.getLogger("example.logger"); + UnsafeArray consumers = defaultLoggerConfig.resolveConsumers( + logger, + LoggerLevel.TRACE); + + // then: + assertThat(consumers.size()) + .isEqualTo(1); + assertThat(consumers.get(0)) + .isInstanceOf(ConsoleMessageConsumer.class) + .extracting("logMessageRender") + .isInstanceOf(SimpleLogMessageRender.class); + } + + @Test + void shouldThrowExceptionWhenLevelValueIsInvalid() { + // given: + var loader = new PropertyLoggerConfigLoader(); + var properties = new Properties(); + properties.setProperty("logger.level.ROOT", "INF0"); + + // when/then: + assertThatThrownBy(() -> loader.loadFromProperties(properties)) + .isInstanceOf(IllegalArgumentException.class); + } + + private static T withContextClassLoader(ClassLoader contextClassLoader, Supplier action) { + Thread currentThread = Thread.currentThread(); + ClassLoader previousClassLoader = currentThread.getContextClassLoader(); + try { + currentThread.setContextClassLoader(contextClassLoader); + return action.get(); + } finally { + currentThread.setContextClassLoader(previousClassLoader); + } + } + + private static class ResourceClassLoader extends ClassLoader { + + private final Map resources; + + private ResourceClassLoader(Map resources) { + super(Thread + .currentThread() + .getContextClassLoader()); + this.resources = resources + .entrySet() + .stream() + .collect(Collectors.toUnmodifiableMap( + Map.Entry::getKey, + entry -> entry.getValue().getBytes(StandardCharsets.UTF_8))); + } + + @Override + public InputStream getResourceAsStream(String name) { + byte[] loaded = resources.get(name); + if (loaded != null) { + return new ByteArrayInputStream(loaded); + } + if (PropertyLoggerConfigLoader.FILE_TEST.equals(name) || PropertyLoggerConfigLoader.FILE_MAIN.equals(name)) { + return null; + } + return super.getResourceAsStream(name); + } + } +} diff --git a/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/render/impl/pattern/PatternRenderNodesParserTest.java b/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/render/impl/pattern/PatternRenderNodesParserTest.java new file mode 100644 index 00000000..032f6dd8 --- /dev/null +++ b/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/render/impl/pattern/PatternRenderNodesParserTest.java @@ -0,0 +1,144 @@ +package javasabr.rlib.logger.impl.config.render.impl.pattern; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import javasabr.rlib.collections.array.Array; +import javasabr.rlib.logger.impl.config.render.impl.pattern.node.DateTimePatternRenderNode; +import javasabr.rlib.logger.impl.config.render.impl.pattern.node.LevelPatternRenderNode; +import javasabr.rlib.logger.impl.config.render.impl.pattern.node.MessagePatternRenderNode; +import javasabr.rlib.logger.impl.config.render.impl.pattern.node.PatternRenderNode; +import javasabr.rlib.logger.impl.config.render.impl.pattern.node.ShortLoggerPatternRenderNode; +import javasabr.rlib.logger.impl.config.render.impl.pattern.node.StringPatternRenderNode; +import org.junit.jupiter.api.Test; + +class PatternRenderNodesParserTest { + + @Test + void shouldParseCorrectlyPattern1() { + // given: + var pattern = " %dateTime{d.MM.yyyy HH:mm:ss:SSS} %level %shortLogger : %msg"; + + // when: + Array parsed = PatternRenderNodesParser.parse(pattern); + + // then: + assertThat(parsed.size()).isEqualTo(8); + assertThat(parsed.get(0)) + .isInstanceOf(StringPatternRenderNode.class) + .isEqualTo(new StringPatternRenderNode(" ")); + assertThat(parsed.get(1)) + .isInstanceOf(DateTimePatternRenderNode.class) + .isEqualTo(new DateTimePatternRenderNode("d.MM.yyyy HH:mm:ss:SSS")); + assertThat(parsed.get(2)) + .isInstanceOf(StringPatternRenderNode.class) + .isEqualTo(new StringPatternRenderNode(" ")); + assertThat(parsed.get(3)) + .isInstanceOf(LevelPatternRenderNode.class); + assertThat(parsed.get(4)) + .isInstanceOf(StringPatternRenderNode.class) + .isEqualTo(new StringPatternRenderNode(" ")); + assertThat(parsed.get(5)) + .isInstanceOf(ShortLoggerPatternRenderNode.class); + assertThat(parsed.get(6)) + .isInstanceOf(StringPatternRenderNode.class) + .isEqualTo(new StringPatternRenderNode(" : ")); + assertThat(parsed.get(7)) + .isInstanceOf(MessagePatternRenderNode.class); + } + + @Test + void shouldParsePatternWithOnlyLiteralText() { + // given: + var pattern = "just a literal string"; + + // when: + Array parsed = PatternRenderNodesParser.parse(pattern); + + // then: + assertThat(parsed.size()) + .isEqualTo(1); + assertThat(parsed.get(0)) + .isInstanceOf(StringPatternRenderNode.class) + .isEqualTo(new StringPatternRenderNode("just a literal string")); + } + + @Test + void shouldParsePatternWithMessageBetweenLiteralTexts() { + // given: + var pattern = "prefix %msg suffix"; + + // when: + Array parsed = PatternRenderNodesParser.parse(pattern); + + // then: + assertThat(parsed.size()) + .isEqualTo(3); + assertThat(parsed.get(0)) + .isInstanceOf(StringPatternRenderNode.class) + .isEqualTo(new StringPatternRenderNode("prefix ")); + assertThat(parsed.get(1)) + .isInstanceOf(MessagePatternRenderNode.class); + assertThat(parsed.get(2)) + .isInstanceOf(StringPatternRenderNode.class) + .isEqualTo(new StringPatternRenderNode(" suffix")); + } + + @Test + void shouldParsePatternWithSimpleNodeSequence() { + // given: + var pattern = "%level %msg %shortLogger"; + + // when: + Array parsed = PatternRenderNodesParser.parse(pattern); + + // then: + assertThat(parsed.size()) + .isEqualTo(5); + assertThat(parsed.get(0)) + .isInstanceOf(LevelPatternRenderNode.class); + assertThat(parsed.get(1)) + .isInstanceOf(StringPatternRenderNode.class) + .isEqualTo(new StringPatternRenderNode(" ")); + assertThat(parsed.get(2)) + .isInstanceOf(MessagePatternRenderNode.class); + assertThat(parsed.get(3)) + .isInstanceOf(StringPatternRenderNode.class) + .isEqualTo(new StringPatternRenderNode(" ")); + assertThat(parsed.get(4)) + .isInstanceOf(ShortLoggerPatternRenderNode.class); + } + + @Test + void shouldThrowWhenNodeNameIsUnknown() { + // given: + var pattern = "%unknown"; + + // when/then: + assertThatThrownBy(() -> PatternRenderNodesParser.parse(pattern)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("Unexpected node name:[unknown]"); + } + + @Test + void shouldThrowWhenDateTimeNodeHasNoOpeningBrace() { + // given: + var pattern = "%dateTime yyyy-MM-dd"; + + // when/then: + assertThatThrownBy(() -> PatternRenderNodesParser.parse(pattern)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("Missed '{'"); + } + + @Test + void shouldThrowWhenDateTimeNodeHasNoClosingBrace() { + // given: + var pattern = "%dateTime{yyyy-MM-dd"; + + // when/then: + assertThatThrownBy(() -> PatternRenderNodesParser.parse(pattern)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("Missed closing '}'"); + } +} diff --git a/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/DateTimePatternRenderNodeTest.java b/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/DateTimePatternRenderNodeTest.java new file mode 100644 index 00000000..b1745297 --- /dev/null +++ b/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/DateTimePatternRenderNodeTest.java @@ -0,0 +1,23 @@ +package javasabr.rlib.logger.impl.config.render.impl.pattern.node; + +import static org.assertj.core.api.Assertions.assertThat; + +import javasabr.rlib.logger.api.LoggerLevel; +import org.junit.jupiter.api.Test; + +class DateTimePatternRenderNodeTest { + + @Test + void shouldAppendCurrentDateTimeUsingProvidedPattern() { + // given: + var node = new DateTimePatternRenderNode("yyyy-MM-dd HH:mm:ss"); + var buffer = new StringBuilder("prefix:"); + + // when: + node.append(LoggerLevel.INFO, PatternRenderNodeTestUtils.LOGGER, "ignored-message", buffer); + + // then: + assertThat(buffer.toString()) + .matches("prefix:\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}"); + } +} diff --git a/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/LevelPatternRenderNodeTest.java b/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/LevelPatternRenderNodeTest.java new file mode 100644 index 00000000..ed10fe1a --- /dev/null +++ b/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/LevelPatternRenderNodeTest.java @@ -0,0 +1,23 @@ +package javasabr.rlib.logger.impl.config.render.impl.pattern.node; + +import static org.assertj.core.api.Assertions.assertThat; + +import javasabr.rlib.logger.api.LoggerLevel; +import org.junit.jupiter.api.Test; + +class LevelPatternRenderNodeTest { + + @Test + void shouldAppendLevelTitleWithOffset() { + // given: + var node = new LevelPatternRenderNode(); + var buffer = new StringBuilder("prefix:"); + + // when: + node.append(LoggerLevel.WARNING, PatternRenderNodeTestUtils.LOGGER, "ignored-message", buffer); + + // then: + assertThat(buffer.toString()) + .isEqualTo("prefix:WARN "); + } +} diff --git a/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/MessagePatternRenderNodeTest.java b/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/MessagePatternRenderNodeTest.java new file mode 100644 index 00000000..5d6b972d --- /dev/null +++ b/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/MessagePatternRenderNodeTest.java @@ -0,0 +1,23 @@ +package javasabr.rlib.logger.impl.config.render.impl.pattern.node; + +import static org.assertj.core.api.Assertions.assertThat; + +import javasabr.rlib.logger.api.LoggerLevel; +import org.junit.jupiter.api.Test; + +class MessagePatternRenderNodeTest { + + @Test + void shouldAppendMessageToBuffer() { + // given: + var node = new MessagePatternRenderNode(); + var buffer = new StringBuilder("prefix:"); + + // when: + node.append(LoggerLevel.ERROR, PatternRenderNodeTestUtils.LOGGER, "actual-message", buffer); + + // then: + assertThat(buffer.toString()) + .isEqualTo("prefix:actual-message"); + } +} diff --git a/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/PatternRenderNodeTestUtils.java b/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/PatternRenderNodeTestUtils.java new file mode 100644 index 00000000..af79af86 --- /dev/null +++ b/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/PatternRenderNodeTestUtils.java @@ -0,0 +1,30 @@ +package javasabr.rlib.logger.impl.config.render.impl.pattern.node; + +import javasabr.rlib.logger.api.Logger; +import javasabr.rlib.logger.api.LoggerLevel; + +final class PatternRenderNodeTestUtils { + + static final Logger LOGGER = new Logger() { + @Override + public String name() { + return "example.logger.PatternRenderNodeTest"; + } + + @Override + public String shortName() { + return "PatternRenderNodeTest"; + } + + @Override + public void print(LoggerLevel level, String message) {} + + @Override + public void print(LoggerLevel level, Throwable exception) {} + + @Override + public void print(LoggerLevel level, String message, Throwable exception) {} + }; + + private PatternRenderNodeTestUtils() {} +} diff --git a/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/ShortLoggerPatternRenderNodeTest.java b/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/ShortLoggerPatternRenderNodeTest.java new file mode 100644 index 00000000..746a9711 --- /dev/null +++ b/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/ShortLoggerPatternRenderNodeTest.java @@ -0,0 +1,23 @@ +package javasabr.rlib.logger.impl.config.render.impl.pattern.node; + +import static org.assertj.core.api.Assertions.assertThat; + +import javasabr.rlib.logger.api.LoggerLevel; +import org.junit.jupiter.api.Test; + +class ShortLoggerPatternRenderNodeTest { + + @Test + void shouldAppendLoggerShortNameToBuffer() { + // given: + var node = new ShortLoggerPatternRenderNode(); + var buffer = new StringBuilder("prefix:"); + + // when: + node.append(LoggerLevel.INFO, PatternRenderNodeTestUtils.LOGGER, "ignored-message", buffer); + + // then: + assertThat(buffer.toString()) + .isEqualTo("prefix:PatternRenderNodeTest"); + } +} diff --git a/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/StringPatternRenderNodeTest.java b/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/StringPatternRenderNodeTest.java new file mode 100644 index 00000000..d4082a61 --- /dev/null +++ b/rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/config/render/impl/pattern/node/StringPatternRenderNodeTest.java @@ -0,0 +1,23 @@ +package javasabr.rlib.logger.impl.config.render.impl.pattern.node; + +import static org.assertj.core.api.Assertions.assertThat; + +import javasabr.rlib.logger.api.LoggerLevel; +import org.junit.jupiter.api.Test; + +class StringPatternRenderNodeTest { + + @Test + void shouldAppendConfiguredStringToBuffer() { + // given: + var node = new StringPatternRenderNode("configured-value"); + var buffer = new StringBuilder("prefix:"); + + // when: + node.append(LoggerLevel.DEBUG, PatternRenderNodeTestUtils.LOGGER, "ignored-message", buffer); + + // then: + assertThat(buffer.toString()) + .isEqualTo("prefix:configured-value"); + } +} diff --git a/rlib-logger-impl/src/test/resources/example-rlib.logger.properties b/rlib-logger-impl/src/test/resources/example-rlib.logger.properties new file mode 100644 index 00000000..6aea4b90 --- /dev/null +++ b/rlib-logger-impl/src/test/resources/example-rlib.logger.properties @@ -0,0 +1,4 @@ +logger.level.example.logger.1=INFO +logger.level.example.logger.2=DEBUG +logger.level.ROOT=WARNING +logger.message.pattern=%dateTime{d.MM.yyyy HH:mm:ss:SSS} %level %shortLogger : %msg diff --git a/rlib-logger-impl/src/test/resources/property-loader-test-1.properties b/rlib-logger-impl/src/test/resources/property-loader-test-1.properties new file mode 100644 index 00000000..27e094ca --- /dev/null +++ b/rlib-logger-impl/src/test/resources/property-loader-test-1.properties @@ -0,0 +1,6 @@ +logger.level.javasabr.rlib.logger.impl.config.loader.impl.PropertyLoggerConfigLoaderTest.A=INFO +logger.level.javasabr.rlib.logger.impl.config.loader.impl.PropertyLoggerConfigLoaderTest.B=DEBUG +logger.level.javasabr.rlib.logger.impl.config.loader.impl.PropertyLoggerConfigLoaderTest.C=TRACE +logger.level.javasabr.rlib.logger.impl.config.loader.impl.PropertyLoggerConfigLoaderTest.D=ERROR +logger.level.ROOT=WARNING +logger.message.pattern=%dateTime{d.MM.yyyy HH:mm:ss:SSS} %level : %msg diff --git a/rlib-logger-slf4j-impl/src/test/java/javasabr/rlib/logger/slf4j/impl/Slf4jLoggerImplTest.java b/rlib-logger-slf4j-impl/src/test/java/javasabr/rlib/logger/slf4j/impl/Slf4jLoggerImplTest.java index 412538d2..a6528c63 100644 --- a/rlib-logger-slf4j-impl/src/test/java/javasabr/rlib/logger/slf4j/impl/Slf4jLoggerImplTest.java +++ b/rlib-logger-slf4j-impl/src/test/java/javasabr/rlib/logger/slf4j/impl/Slf4jLoggerImplTest.java @@ -9,7 +9,7 @@ import javasabr.rlib.logger.api.Logger; import javasabr.rlib.logger.api.LoggerLevel; import javasabr.rlib.logger.impl.DefaultLoggerService; -import javasabr.rlib.logger.impl.config.LogMessageConsumer; +import javasabr.rlib.logger.impl.config.consumer.LogMessageConsumer; import javasabr.rlib.logger.impl.config.impl.DefaultLoggerConfig; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/rlib-network/src/main/java/javasabr/rlib/network/packet/impl/AbstractNetworkPacket.java b/rlib-network/src/main/java/javasabr/rlib/network/packet/impl/AbstractNetworkPacket.java index 88f91dab..54cfb9d7 100644 --- a/rlib-network/src/main/java/javasabr/rlib/network/packet/impl/AbstractNetworkPacket.java +++ b/rlib-network/src/main/java/javasabr/rlib/network/packet/impl/AbstractNetworkPacket.java @@ -20,7 +20,7 @@ public abstract class AbstractNetworkPacket> implements */ protected void handleException(C connection, ByteBuffer buffer, Exception exception) { log.warn(exception); - if (!log.warningEnabled()) { + if (!log.warnEnabled()) { return; }