You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by dk...@apache.org on 2022/01/31 14:02:17 UTC

[sling-org-apache-sling-commons-log] 01/01: SLING-11104 - Adding basic support for JSON logging using Logback Commons JSON + Jackson

This is an automated email from the ASF dual-hosted git repository.

dklco pushed a commit to branch SLING-11104
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-log.git

commit f053f1ea9fda4834b3c7592343fe5af50286bed3
Author: Dan Klco <kl...@adobe.com>
AuthorDate: Mon Jan 31 09:01:55 2022 -0500

    SLING-11104 - Adding basic support for JSON logging using Logback Commons JSON + Jackson
---
 bnd.bnd                                            |  2 ++
 pom.xml                                            | 13 ++++++++
 .../commons/log/logback/internal/LogConfig.java    | 36 ++++++++++++++++++++--
 .../log/logback/internal/LogConfigManager.java     | 13 +++++++-
 .../log/logback/internal/SlingLogPanel.java        |  2 +-
 src/main/resources/logback.xml                     | 21 +++++++------
 .../log/logback/internal/TestLogConfig.java        |  5 +--
 7 files changed, 75 insertions(+), 17 deletions(-)

diff --git a/bnd.bnd b/bnd.bnd
index f6b7764..662d8b6 100644
--- a/bnd.bnd
+++ b/bnd.bnd
@@ -25,6 +25,8 @@ DynamicImport-Package: org.osgi.service.cm;version=1.2, \
               javax.xml.transform.sax, \
               javax.xml.transform.stream
 Export-Package: ch.qos.logback.classic*, \
+              ch.qos.logback.contrib.json*, \
+              ch.qos.logback.contrib.jackson*, \
               ch.qos.logback.core*, \
               org.slf4j.impl;version=${slf4j.version}, \
               org.apache.sling.commons.log.logback, \
diff --git a/pom.xml b/pom.xml
index f59914c..75beb95 100644
--- a/pom.xml
+++ b/pom.xml
@@ -199,6 +199,19 @@
       <scope>compile</scope>
     </dependency>
 
+    <dependency>
+        <groupId>ch.qos.logback.contrib</groupId>
+        <artifactId>logback-json-classic</artifactId>
+        <version>0.1.5</version>
+        <scope>compile</scope>
+    </dependency>
+    <dependency>
+        <groupId>ch.qos.logback.contrib</groupId>
+        <artifactId>logback-jackson</artifactId>
+        <version>0.1.5</version>
+        <scope>compile</scope>
+    </dependency>
+
     <!-- OSGi Libraries not included here -->
     <dependency>
       <groupId>org.osgi</groupId>
diff --git a/src/main/java/org/apache/sling/commons/log/logback/internal/LogConfig.java b/src/main/java/org/apache/sling/commons/log/logback/internal/LogConfig.java
index ea13ce9..842936e 100644
--- a/src/main/java/org/apache/sling/commons/log/logback/internal/LogConfig.java
+++ b/src/main/java/org/apache/sling/commons/log/logback/internal/LogConfig.java
@@ -20,17 +20,23 @@ package org.apache.sling.commons.log.logback.internal;
 
 import java.text.MessageFormat;
 import java.util.Collections;
+import java.util.Map;
 import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import ch.qos.logback.classic.Level;
 import ch.qos.logback.classic.LoggerContext;
 import ch.qos.logback.classic.PatternLayout;
 import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.contrib.jackson.JacksonJsonFormatter;
+import ch.qos.logback.contrib.json.JsonFormatter;
+import ch.qos.logback.contrib.json.classic.JsonLayout;
+import ch.qos.logback.core.LayoutBase;
 import ch.qos.logback.core.pattern.PostCompileProcessor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 public class LogConfig {
     private static final String[] LEGACY_MARKERS = {
@@ -104,7 +110,8 @@ public class LogConfig {
         return resetToDefault;
     }
 
-    public PatternLayout createLayout() {
+    private PatternLayout getPatternLayout(){
+
         // The java.util.MessageFormat pattern to use for formatting log
         // messages with the root logger.
         // This is a java.util.MessageFormat pattern supporting up to six
@@ -158,6 +165,29 @@ public class LogConfig {
         return pl;
     }
 
+    private JsonLayout getJsonLayout(){
+        JsonLayout jl = new JsonLayout();
+        JsonFormatter newlineFormatter = new JsonFormatter() {
+            private final JacksonJsonFormatter jacksonFormatter = new JacksonJsonFormatter();
+            @Override
+            public String toJsonString(Map m) throws Exception {
+                return jacksonFormatter.toJsonString(m) + System.lineSeparator();
+            }
+        };
+        jl.setJsonFormatter(newlineFormatter);
+        jl.setContext(loggerContext);
+        jl.start();
+        return jl;
+    }
+
+    public LayoutBase<ILoggingEvent> createLayout() {
+        if("json".equalsIgnoreCase(pattern)){
+            return getJsonLayout();
+        } else {
+            return getPatternLayout();
+        }
+    }
+
     @Override
     public String toString() {
         return "LogConfig{" + "configPid='" + configPid + '\'' + ", categories=" + categories + ", logLevel="
diff --git a/src/main/java/org/apache/sling/commons/log/logback/internal/LogConfigManager.java b/src/main/java/org/apache/sling/commons/log/logback/internal/LogConfigManager.java
index 1f153f6..ee5e92d 100644
--- a/src/main/java/org/apache/sling/commons/log/logback/internal/LogConfigManager.java
+++ b/src/main/java/org/apache/sling/commons/log/logback/internal/LogConfigManager.java
@@ -26,6 +26,7 @@ import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -511,8 +512,11 @@ public class LogConfigManager implements LogbackResetListener, LogConfig.LogWrit
 
         if (configuration != null) {
 
+            contextUtil.addInfo("updating: "+pid+" to: "+configuration);
+
             String pattern = (String) configuration.get(LogConfigManager.LOG_PATTERN);
-            final String level = (String) configuration.get(LogConfigManager.LOG_LEVEL);
+            final String level = Optional.ofNullable(configuration.get(LogConfigManager.LOG_LEVEL))
+                    .map(String.class::cast).orElse(Level.INFO.toString());
             String fileName = (String) configuration.get(LogConfigManager.LOG_FILE);
             final Set<String> categories = toCategoryList(configuration.get(LogConfigManager.LOG_LOGGERS));
             final boolean additiv;
@@ -571,9 +575,16 @@ public class LogConfigManager implements LogbackResetListener, LogConfig.LogWrit
                 fileName = getAbsoluteFilePath(fileName);
             }
 
+            contextUtil.addInfo(String.format(
+                    "Loaded settings: additiv=%s, categories=%s, logLevel=%s, pattern=%s, fileName=%s", additiv,
+                    categories, logLevel, pattern, fileName));
+
             // create or modify existing configuration object
             final LogConfig newConfig = new LogConfig(this, pattern, categories, logLevel, fileName, additiv,
                     pid, loggerContext, resetToDefault);
+            contextUtil.addInfo("Created configuration: " + newConfig);
+            contextUtil.addInfo("Using layout: " + newConfig.createLayout());
+
             if (isPackagingDataEnabled()) {
                 newConfig.setPostProcessor(new OSGiAwareExceptionHandling(logbackManager.getPackageInfoCollector()));
             }
diff --git a/src/main/java/org/apache/sling/commons/log/logback/internal/SlingLogPanel.java b/src/main/java/org/apache/sling/commons/log/logback/internal/SlingLogPanel.java
index ac0004b..b6962d9 100644
--- a/src/main/java/org/apache/sling/commons/log/logback/internal/SlingLogPanel.java
+++ b/src/main/java/org/apache/sling/commons/log/logback/internal/SlingLogPanel.java
@@ -785,7 +785,7 @@ public class SlingLogPanel implements LogPanel {
     }
 
     private static String getPath(String path, final String rootPath, final boolean shortenPaths) {
-        if (shortenPaths && path != null) {
+        if (shortenPaths && path != null && path.startsWith(rootPath)) {
             // if the shortenPath parameter is set (all log files are in the same folder)
             // remove the root path (root log file folder) from the paths
             path = path.substring(rootPath.length() + 1);
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
index 28eeea9..323403a 100644
--- a/src/main/resources/logback.xml
+++ b/src/main/resources/logback.xml
@@ -19,15 +19,16 @@
 -->
 <configuration>
 
-  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
-    <!-- encoders are assigned the type
-         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
-    <encoder>
-      <pattern>%d{dd.MM.yyyy HH:mm:ss.SSS} *%level* [%thread] %logger %message%n</pattern>
-    </encoder>
-  </appender>
+    <appender name="json" class="ch.qos.logback.core.ConsoleAppender">
+        <layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
+            <jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
+                <prettyPrint>true</prettyPrint>
+            </jsonFormatter>
+            <timestampFormat>yyyy-MM-dd' 'HH:mm:ss.SSS</timestampFormat>
+        </layout>
+    </appender>
 
-  <root level="info">
-    <appender-ref ref="CONSOLE" />
-  </root>
+    <logger name="jsonLogger" level="INFO">
+        <appender-ref ref="json" />
+    </logger>
 </configuration>
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/commons/log/logback/internal/TestLogConfig.java b/src/test/java/org/apache/sling/commons/log/logback/internal/TestLogConfig.java
index 408cc88..50a5cc9 100644
--- a/src/test/java/org/apache/sling/commons/log/logback/internal/TestLogConfig.java
+++ b/src/test/java/org/apache/sling/commons/log/logback/internal/TestLogConfig.java
@@ -28,6 +28,7 @@ import org.slf4j.LoggerFactory;
 
 import ch.qos.logback.classic.Level;
 import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.PatternLayout;
 
 public class TestLogConfig {
 
@@ -36,7 +37,7 @@ public class TestLogConfig {
         String pattern = "{0,date,dd.MM.yyyy HH:mm:ss.SSS} *{4}* [{2}] {3} {5}";
         String convertedPattern = "%d{dd.MM.yyyy HH:mm:ss.SSS} *%level* [%thread] %logger %message%n";
         LogConfig logConfig = createConfig(pattern);
-        assertEquals(convertedPattern, logConfig.createLayout().getPattern());
+        assertEquals(convertedPattern, ((PatternLayout)logConfig.createLayout()).getPattern());
     }
 
     @Test
@@ -44,7 +45,7 @@ public class TestLogConfig {
         String convertedPattern = "%d{dd.MM.yyyy HH:mm:ss.SSS} *%level* [%thread] %logger %message%n";
         LogConfig logConfig = createConfig(convertedPattern);
         // Test that valid LogBack pattern are not tampered
-        assertEquals(convertedPattern, logConfig.createLayout().getPattern());
+        assertEquals(convertedPattern, ((PatternLayout)logConfig.createLayout()).getPattern());
     }
 
     private LogConfig createConfig(String pattern) {