From 73ea6c7b60bdcdc2705f1fb48b09eff5347c201b Mon Sep 17 00:00:00 2001 From: Stephan Schnabel Date: Tue, 13 Sep 2022 14:13:01 +0200 Subject: [PATCH] Update to version 4.x and update to SLF4J 2.x and Logback 1.4 --- README.md | 4 +- docs/features/logback_appender.md | 4 +- docs/features/logback_default.md | 6 +- pom.xml | 13 +- .../configurator/DefaultConfigurator.java | 6 +- .../MicronautJoranConfigurator.java | 6 +- .../RootAutoSelectAppenderAction.java | 117 ++++++++++++++---- .../io/kokuwa/logback/appender-console.xml | 4 +- src/main/resources/io/kokuwa/logback/base.xml | 8 -- .../io/kokuwa/logback/logback-default.xml | 2 - .../io/kokuwa/logback/logback-example.xml | 4 +- 11 files changed, 121 insertions(+), 53 deletions(-) delete mode 100644 src/main/resources/io/kokuwa/logback/base.xml diff --git a/README.md b/README.md index 45088a2..728889f 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,8 @@ Include in your `pom.xml`: ## Features +* Version [3.x](https://github.com/kokuwaio/micronaut-logging/tree/3.x) is based on SLF4J 1.7 & Logback 1.2 +* Version [4.x](https://github.com/kokuwaio/micronaut-logging/tree/main) is based on SLF4J 2.0 & Logback 1.4 * [set log level based on MDC values](docs/features/logback_mdc_level.md) * [add default xml](docs/features/logback_default.md) * [preconfigured appender for different environments](docs/features/logback_appender.md) @@ -33,5 +35,3 @@ Include in your `pom.xml`: * configure mdc on refresh event * read **serviceName** and **serviceVersion** from yaml -* support auto select appender with custom `logback.xml` -* add maven site with jacoco / dependency updates for snapshot build diff --git a/docs/features/logback_appender.md b/docs/features/logback_appender.md index 1975e8b..604a26d 100644 --- a/docs/features/logback_appender.md +++ b/docs/features/logback_appender.md @@ -2,7 +2,7 @@ ## Available Appender -* console with jansi for developers +* console for developers * gcp logging format (with support for error reporting) * json @@ -12,5 +12,3 @@ 2. if GCP is detected gcp appender will be used 3. if Kubernetes is detected json appender will be used 4. console appender else - -*IMPORTENT*: only works without custom `logback.xml` diff --git a/docs/features/logback_default.md b/docs/features/logback_default.md index 98ccbc5..122f83a 100644 --- a/docs/features/logback_default.md +++ b/docs/features/logback_default.md @@ -4,14 +4,12 @@ If no `logback.xml` by user is provided a default [logback.xml](../../src/main/r ```xml - - - + - + diff --git a/pom.xml b/pom.xml index fef007e..75b283f 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ io.kokuwa.micronaut micronaut-logging - 3.0.6-SNAPSHOT + 4.0.0-SNAPSHOT Logging Support for Micronaut Enhanced logging using MDC or request header. @@ -105,9 +105,10 @@ - 1.2.11 + 1.4.0 0.1.5 3.6.1 + 2.0.0 @@ -123,6 +124,13 @@ import + + + org.slf4j + slf4j-api + ${version.org.slf4j.api} + + ch.qos.logback @@ -193,7 +201,6 @@ ch.qos.logback.contrib logback-jackson - runtime diff --git a/src/main/java/io/kokuwa/micronaut/logging/configurator/DefaultConfigurator.java b/src/main/java/io/kokuwa/micronaut/logging/configurator/DefaultConfigurator.java index 1d808a9..f3ecb7d 100644 --- a/src/main/java/io/kokuwa/micronaut/logging/configurator/DefaultConfigurator.java +++ b/src/main/java/io/kokuwa/micronaut/logging/configurator/DefaultConfigurator.java @@ -14,12 +14,12 @@ import ch.qos.logback.core.spi.ContextAwareBase; public class DefaultConfigurator extends ContextAwareBase implements Configurator { @Override - public void configure(LoggerContext loggerContext) { + public ExecutionStatus configure(LoggerContext loggerContext) { var base = DefaultConfigurator.class.getResource("/io/kokuwa/logback/logback-default.xml"); if (base == null) { addError("Failed to find logback.xml from io.kokuwa:micronaut-logging"); - return; + return ExecutionStatus.NEUTRAL; } try { @@ -29,8 +29,10 @@ public class DefaultConfigurator extends ContextAwareBase implements Configurato configurator.doConfigure(base); } catch (JoranException e) { addError("Failed to load logback.xml from io.kokuwa:micronaut-logging", e); + return ExecutionStatus.NEUTRAL; } loggerContext.getLogger("io.micronaut.logging.PropertiesLoggingLevelsConfigurer").setLevel(Level.WARN); + return ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY; } } diff --git a/src/main/java/io/kokuwa/micronaut/logging/configurator/MicronautJoranConfigurator.java b/src/main/java/io/kokuwa/micronaut/logging/configurator/MicronautJoranConfigurator.java index f89db16..a1010d7 100644 --- a/src/main/java/io/kokuwa/micronaut/logging/configurator/MicronautJoranConfigurator.java +++ b/src/main/java/io/kokuwa/micronaut/logging/configurator/MicronautJoranConfigurator.java @@ -12,8 +12,8 @@ import ch.qos.logback.core.joran.spi.RuleStore; public class MicronautJoranConfigurator extends JoranConfigurator { @Override - public void addInstanceRules(RuleStore rs) { - super.addInstanceRules(rs); - rs.addRule(new ElementSelector("configuration/root/autoAppender"), new RootAutoSelectAppenderAction()); + public void addElementSelectorAndActionAssociations(RuleStore rs) { + super.addElementSelectorAndActionAssociations(rs); + rs.addRule(new ElementSelector("configuration/root/autoAppender"), () -> new RootAutoSelectAppenderAction()); } } diff --git a/src/main/java/io/kokuwa/micronaut/logging/configurator/RootAutoSelectAppenderAction.java b/src/main/java/io/kokuwa/micronaut/logging/configurator/RootAutoSelectAppenderAction.java index b490a35..50bbb70 100644 --- a/src/main/java/io/kokuwa/micronaut/logging/configurator/RootAutoSelectAppenderAction.java +++ b/src/main/java/io/kokuwa/micronaut/logging/configurator/RootAutoSelectAppenderAction.java @@ -1,16 +1,21 @@ package io.kokuwa.micronaut.logging.configurator; -import java.util.Map; +import java.util.Optional; import org.xml.sax.Attributes; import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.PatternLayout; import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.Appender; +import ch.qos.logback.contrib.jackson.JacksonJsonFormatter; +import ch.qos.logback.contrib.json.classic.JsonLayout; +import ch.qos.logback.core.ConsoleAppender; +import ch.qos.logback.core.Layout; +import ch.qos.logback.core.encoder.LayoutWrappingEncoder; import ch.qos.logback.core.joran.action.Action; -import ch.qos.logback.core.joran.action.ActionConst; -import ch.qos.logback.core.joran.spi.InterpretationContext; +import ch.qos.logback.core.joran.spi.SaxEventInterpretationContext; +import io.kokuwa.micronaut.logging.layout.GcpJsonLayout; import io.micronaut.core.util.StringUtils; /** @@ -27,9 +32,16 @@ public class RootAutoSelectAppenderAction extends Action { private static final String APPENDER_JSON = "JSON"; private static final String APPENDER_GCP = "GCP"; private static final String LOGBACK_APPENDER = "LOGBACK_APPENDER"; + private static final String LOGBACK_PATTERN = "LOGBACK_PATTERN"; + private static final String LOGBACK_PATTERN_DEFAULT = "%cyan(%d{HH:mm:ss.SSS})" + + " %gray(%-6.6thread)" + + " %highlight(%-5level)" + + " %magenta(%32logger{32})" + + " %mdc" + + " %msg%n}"; @Override - public void begin(InterpretationContext ic, String name, Attributes attributes) { + public void begin(SaxEventInterpretationContext ic, String name, Attributes attributes) { var rootLogger = LoggerContext.class.cast(context).getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); var rootLoggerAppenders = rootLogger.iteratorForAppenders(); @@ -38,36 +50,95 @@ public class RootAutoSelectAppenderAction extends Action { return; } - var envAppender = System.getenv(LOGBACK_APPENDER); - if (envAppender != null && setAppender(ic, rootLogger, envAppender)) { + var envAppender = env(LOGBACK_APPENDER, null); + if (envAppender != null) { + setAppender(rootLogger, envAppender); return; } - if (IS_KUBERNETES && setAppender(ic, rootLogger, APPENDER_JSON)) { + if (IS_KUBERNETES) { + setAppender(rootLogger, APPENDER_JSON); return; } - if (IS_GCP && setAppender(ic, rootLogger, APPENDER_GCP)) { + if (IS_GCP) { + setAppender(rootLogger, APPENDER_GCP); return; } - setAppender(ic, rootLogger, APPENDER_CONSOLE); + setAppender(rootLogger, APPENDER_CONSOLE); } @Override - public void end(InterpretationContext ic, String name) {} - - private boolean setAppender(InterpretationContext ic, Logger rootLogger, String appenderName) { - - @SuppressWarnings("unchecked") - var appenderBag = (Map>) ic.getObjectMap().get(ActionConst.APPENDER_BAG); - var appender = appenderBag.get(appenderName); - if (appender == null) { - addError("Could not find an appender named [" + appenderName - + "]. Did you define it below instead of above in the configuration file?"); - return false; - } + public void end(SaxEventInterpretationContext ic, String name) {} + private void setAppender(Logger rootLogger, String appenderName) { addInfo("Use appender: " + appenderName); + + Layout layout; + switch (appenderName) { + case APPENDER_JSON: + layout = json(); + break; + case APPENDER_GCP: + layout = gcp(); + break; + case APPENDER_CONSOLE: + layout = console(); + break; + default: + addError("Appender " + appenderName + " not found. Using console ..."); + layout = console(); + } + layout.start(); + + var encoder = new LayoutWrappingEncoder(); + encoder.setContext(context); + encoder.setLayout(layout); + encoder.start(); + + var appender = new ConsoleAppender(); + appender.setContext(context); + appender.setName(appenderName); + appender.setEncoder(encoder); + appender.start(); + rootLogger.addAppender(appender); - return true; + } + + private Layout console() { + var layout = new PatternLayout(); + layout.setContext(context); + layout.setPattern(env(LOGBACK_PATTERN, LOGBACK_PATTERN_DEFAULT)); + return layout; + } + + private Layout json() { + var layout = new GcpJsonLayout(); + layout.setContext(context); + layout.setJsonFormatter(new JacksonJsonFormatter()); + layout.setAppendLineSeparator(true); + layout.setIncludeContextName(false); + layout.setServiceName(env("SERVICE_NAME", null)); + layout.setServiceVersion(env("SERVICE_VERSION", null)); + return layout; + } + + private Layout gcp() { + var layout = new JsonLayout(); + layout.setContext(context); + layout.setJsonFormatter(new JacksonJsonFormatter()); + layout.setAppendLineSeparator(true); + layout.setIncludeContextName(false); + return layout; + } + + private String env(String name, String defaultValue) { + var envValue = Optional.ofNullable(System.getenv(name)).map(String::trim).filter(String::isEmpty); + var finalValue = envValue.orElse(defaultValue); + if (envValue.isPresent()) { + addInfo("Use provided config: " + name + "=" + finalValue); + } else { + addInfo("Use default config: " + name + "=" + finalValue); + } + return finalValue; } } diff --git a/src/main/resources/io/kokuwa/logback/appender-console.xml b/src/main/resources/io/kokuwa/logback/appender-console.xml index e4bfb1d..906b86f 100644 --- a/src/main/resources/io/kokuwa/logback/appender-console.xml +++ b/src/main/resources/io/kokuwa/logback/appender-console.xml @@ -2,8 +2,8 @@ - ${CONSOLE_LOG_JANSI:-true} - + ${CONSOLE_LOG_JANSI:-false} + ${CONSOLE_LOG_PATTERN:-%cyan(%d{HH:mm:ss.SSS}) %gray(%-6.6thread) %highlight(%-5level) %magenta(%32logger{32}) %mdc %msg%n} ${CONSOLE_LOG_CHARSET:-default} diff --git a/src/main/resources/io/kokuwa/logback/base.xml b/src/main/resources/io/kokuwa/logback/base.xml deleted file mode 100644 index 24ae946..0000000 --- a/src/main/resources/io/kokuwa/logback/base.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/src/main/resources/io/kokuwa/logback/logback-default.xml b/src/main/resources/io/kokuwa/logback/logback-default.xml index 1092ea9..78fe3f0 100644 --- a/src/main/resources/io/kokuwa/logback/logback-default.xml +++ b/src/main/resources/io/kokuwa/logback/logback-default.xml @@ -1,8 +1,6 @@ - - diff --git a/src/main/resources/io/kokuwa/logback/logback-example.xml b/src/main/resources/io/kokuwa/logback/logback-example.xml index 47deab2..996e1a1 100644 --- a/src/main/resources/io/kokuwa/logback/logback-example.xml +++ b/src/main/resources/io/kokuwa/logback/logback-example.xml @@ -1,7 +1,9 @@ - + + +