From f7ff1f675069b15f42ab4129979350b745b90616 Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Sat, 14 Dec 2024 14:44:37 +0000 Subject: [PATCH] Move implementation-specific logging code to separate classes --- .../org/apache/jena/atlas/logging/LogCtl.java | 60 ++---- .../apache/jena/atlas/logging/LogCtlJUL.java | 26 +++ .../jena/atlas/logging/LogCtlLog4j2.java | 201 +++++++++++------- .../jena/fuseki/servlets/FusekiFilter.java | 4 +- 4 files changed, 161 insertions(+), 130 deletions(-) diff --git a/jena-base/src/main/java/org/apache/jena/atlas/logging/LogCtl.java b/jena-base/src/main/java/org/apache/jena/atlas/logging/LogCtl.java index e721d3b7c23..36a81903946 100644 --- a/jena-base/src/main/java/org/apache/jena/atlas/logging/LogCtl.java +++ b/jena-base/src/main/java/org/apache/jena/atlas/logging/LogCtl.java @@ -38,10 +38,11 @@ * This needs access to log4j2 binaries including log4j-core, which is encapsulated in LogCtlLog4j2. */ public class LogCtl { - private static final boolean hasLog4j2 = hasClass("org.apache.logging.slf4j.Log4jLoggerFactory"); - private static final boolean hasLog4j1 = hasClass("org.slf4j.impl.Log4jLoggerFactory"); - private static final boolean hasJUL = hasClass("org.slf4j.impl.JDK14LoggerFactory"); + private static final boolean hasLog4j2 = hasClass("org.apache.logging.slf4j.Log4jLoggerFactory"); + private static final boolean hasLog4j1 = hasClass("org.slf4j.impl.Log4jLoggerFactory"); // JUL always present but needs slf4j adapter. + private static final boolean hasJUL = hasClass("org.slf4j.impl.JDK14LoggerFactory"); + private static final boolean hasLogback = hasClass("ch.qos.logback.core.LogbackException"); // Put per-logging system code in separate classes to avoid needing them on the classpath. private static boolean hasClass(String className) { @@ -83,67 +84,34 @@ public static String getLevel(String logger) { String s2 = getLevelLog4j2(logger); if ( s2 != null ) return s2; - // Always present. String s3 = getLevelJUL(logger); if ( s3 != null ) return s3; return null; } - static private String getLevelJUL(String logger) { - java.util.logging.Level level = java.util.logging.Logger.getLogger(logger).getLevel(); - if ( level == null ) + static private String getLevelLog4j2(String logger) { + if ( !hasLog4j2 ) return null; - if ( level == java.util.logging.Level.SEVERE ) - return "ERROR"; - return level.getName(); + return LogCtlLog4j2.getLoggerlevel(logger); } - static private String getLevelLog4j2(String logger) { - if ( !hasLog4j2 ) + static private String getLevelJUL(String logger) { + if ( ! hasJUL ) return null; - org.apache.logging.log4j.Level level = org.apache.logging.log4j.LogManager.getLogger(logger).getLevel(); - if ( level != null ) - return level.toString(); - return null; + return LogCtlJUL.getLevelJUL(logger); } private static void setLevelJUL(String logger, String levelName) { - java.util.logging.Level level = java.util.logging.Level.ALL; - if ( levelName == null ) - level = null; - else if ( levelName.equalsIgnoreCase("info") ) - level = java.util.logging.Level.INFO; - else if ( levelName.equalsIgnoreCase("debug") ) - level = java.util.logging.Level.FINE; - else if ( levelName.equalsIgnoreCase("warn") || levelName.equalsIgnoreCase("warning") ) - level = java.util.logging.Level.WARNING; - else if ( levelName.equalsIgnoreCase("error") || levelName.equalsIgnoreCase("severe") ) - level = java.util.logging.Level.SEVERE; - else if ( levelName.equalsIgnoreCase("OFF") ) - level = java.util.logging.Level.OFF; - java.util.logging.Logger.getLogger(logger).setLevel(level); + if ( ! hasJUL ) + return ; + LogCtlJUL.setLevelJUL(logger, levelName); } private static void setLevelLog4j2(String logger, String levelName) { if ( !hasLog4j2 ) return; - org.apache.logging.log4j.Level level = org.apache.logging.log4j.Level.ALL; - if ( levelName == null ) - level = null; - else if ( levelName.equalsIgnoreCase("info") ) - level = org.apache.logging.log4j.Level.INFO; - else if ( levelName.equalsIgnoreCase("debug") ) - level = org.apache.logging.log4j.Level.DEBUG; - else if ( levelName.equalsIgnoreCase("warn") || levelName.equalsIgnoreCase("warning") ) - level = org.apache.logging.log4j.Level.WARN; - else if ( levelName.equalsIgnoreCase("error") || levelName.equalsIgnoreCase("severe") ) - level = org.apache.logging.log4j.Level.ERROR; - else if ( levelName.equalsIgnoreCase("fatal") ) - level = org.apache.logging.log4j.Level.FATAL; - else if ( levelName.equalsIgnoreCase("OFF") ) - level = org.apache.logging.log4j.Level.OFF; - LogCtlLog4j2.setLoggerlevel(logger, level); + LogCtlLog4j2.setLoggerlevel(logger, levelName); } /** diff --git a/jena-base/src/main/java/org/apache/jena/atlas/logging/LogCtlJUL.java b/jena-base/src/main/java/org/apache/jena/atlas/logging/LogCtlJUL.java index 56611cd31c9..8870457ec3f 100644 --- a/jena-base/src/main/java/org/apache/jena/atlas/logging/LogCtlJUL.java +++ b/jena-base/src/main/java/org/apache/jena/atlas/logging/LogCtlJUL.java @@ -54,6 +54,32 @@ public class LogCtlJUL { private LogCtlJUL() {} + /*package*/ static String getLevelJUL(String logger) { + java.util.logging.Level level = java.util.logging.Logger.getLogger(logger).getLevel(); + if ( level == null ) + return null; + if ( level == java.util.logging.Level.SEVERE ) + return "ERROR"; + return level.getName(); + } + + /*package*/ static void setLevelJUL(String logger, String levelName) { + java.util.logging.Level level = java.util.logging.Level.ALL; + if ( levelName == null ) + level = null; + else if ( levelName.equalsIgnoreCase("info") ) + level = java.util.logging.Level.INFO; + else if ( levelName.equalsIgnoreCase("debug") ) + level = java.util.logging.Level.FINE; + else if ( levelName.equalsIgnoreCase("warn") || levelName.equalsIgnoreCase("warning") ) + level = java.util.logging.Level.WARNING; + else if ( levelName.equalsIgnoreCase("error") || levelName.equalsIgnoreCase("severe") ) + level = java.util.logging.Level.SEVERE; + else if ( levelName.equalsIgnoreCase("OFF") ) + level = java.util.logging.Level.OFF; + java.util.logging.Logger.getLogger(logger).setLevel(level); + } + /** * Reset java.util.logging - this overrides the previous configuration, if any. */ diff --git a/jena-base/src/main/java/org/apache/jena/atlas/logging/LogCtlLog4j2.java b/jena-base/src/main/java/org/apache/jena/atlas/logging/LogCtlLog4j2.java index fc976bc66b4..ff7a7081aca 100644 --- a/jena-base/src/main/java/org/apache/jena/atlas/logging/LogCtlLog4j2.java +++ b/jena-base/src/main/java/org/apache/jena/atlas/logging/LogCtlLog4j2.java @@ -52,10 +52,7 @@ public class LogCtlLog4j2 { /** Default log4j2 setup */ - public static String log4j2setup = String.join(log4jSetupSep(), - log4j2setupBase(), - log4j2setupJenaLib(), - log4j2setupFuseki()); + public static String log4j2setup = Log4j2Setup.log4j2setup(); /** * Reset logging for log4j2. @@ -82,7 +79,36 @@ public static void resetLogging(InputStream inputStream, SyntaxHint syntaxHint) reconfigureLog4j(config); } - /** Check logging level of a Logger */ + /** get logging level of a Logger as a string */ + /* package */ static String getLoggerlevel(String logger) { + Level level = org.apache.logging.log4j.LogManager.getLogger(logger).getLevel(); + if ( level != null ) + return level.toString(); + return null; + + } + + /** Set logging level of a Logger */ + /*package*/ static void setLoggerlevel(String logger, String levelName) { + org.apache.logging.log4j.Level level = org.apache.logging.log4j.Level.ALL; + if ( levelName == null ) + level = null; + else if ( levelName.equalsIgnoreCase("info") ) + level = org.apache.logging.log4j.Level.INFO; + else if ( levelName.equalsIgnoreCase("debug") ) + level = org.apache.logging.log4j.Level.DEBUG; + else if ( levelName.equalsIgnoreCase("warn") || levelName.equalsIgnoreCase("warning") ) + level = org.apache.logging.log4j.Level.WARN; + else if ( levelName.equalsIgnoreCase("error") || levelName.equalsIgnoreCase("severe") ) + level = org.apache.logging.log4j.Level.ERROR; + else if ( levelName.equalsIgnoreCase("fatal") ) + level = org.apache.logging.log4j.Level.FATAL; + else if ( levelName.equalsIgnoreCase("OFF") ) + level = org.apache.logging.log4j.Level.OFF; + LogCtlLog4j2.setLoggerlevel(logger, level); + } + + /** Set logging level of a Logger */ /*package*/ static void setLoggerlevel(String logger, Level level) { try { if ( !logger.equals("") ) @@ -94,7 +120,7 @@ public static void resetLogging(InputStream inputStream, SyntaxHint syntaxHint) } } - /** Check logging level of a Logger */ + /** Set logging level of a Logger */ /*package*/ static void setLoggerlevel(Logger logger, Level level) { try { org.apache.logging.log4j.core.config.Configurator.setLevel(logger, level); @@ -103,7 +129,6 @@ public static void resetLogging(InputStream inputStream, SyntaxHint syntaxHint) } } - /** * Enum for possible syntax of a Log4j configuration file. *

@@ -259,81 +284,93 @@ private static SyntaxHint determineSyntax(String filename) { return hint; } - /** Line separate/blank line for concatenating log4j syntax fragments. */ - private static String log4jSetupSep() { return "\n"; } + // Hide constants. + static class Log4j2Setup { + + private static String log4j2setup() { + return String.join(log4jSetupSep(), + log4j2setupBase(), + log4j2setupJenaLib(), + log4j2setupFuseki()); + } + + /** Line separate/blank line for concatenating log4j syntax fragments. */ + private static String log4jSetupSep() { return "\n"; } + + /** + * A basic logging setup. Time and level INFO. + */ + private static String log4j2setupBase() { + return """ + ## Log4j2 properties syntax. + status = error + name = JenaLoggingDft + + # filters = threshold + # filter.threshold.type = ThresholdFilter + # filter.threshold.level = ALL + + appender.console.type = Console + appender.console.name = OUT + appender.console.target = SYSTEM_OUT + appender.console.layout.type = PatternLayout + appender.console.layout.pattern = %d{HH:mm:ss} %-5p %-15c{1} :: %m%n + # appender.console.layout.pattern = [%d{yyyy-MM-dd HH:mm:ss}] %-5p %-15c{1} :: %m%n + + rootLogger.level = INFO + rootLogger.appenderRef.stdout.ref = OUT + """; + } + /** Default log4j fragment needed for Jena command line tools. */ + private static String log4j2setupJenaLib() { + return """ + logger.jena.name = org.apache.jena + logger.jena.level = INFO + + logger.arq-exec.name = org.apache.jena.arq.exec + logger.arq-exec.level = INFO + + logger.riot.name = org.apache.jena.riot + logger.riot.level = INFO + """; + } + /** Additional log4j fragment for Fuseki in case the general default is used with embedded Fuseki. */ + private static String log4j2setupFuseki() { + return """ + # Fuseki. In case this logging setup gets install for embedded Fuseki. + + logger.fuseki.name = org.apache.jena.fuseki + logger.fuseki.level = INFO + logger.fuseki-fuseki.name = org.apache.jena.fuseki.Fuseki + logger.fuseki-fuseki.level = INFO + + logger.fuseki-server.name = org.apache.jena.fuseki.Server + logger.fuseki-server.level = INFO + + logger.fuseki-config.name = org.apache.jena.fuseki.Config + logger.fuseki-config.level = INFO + + logger.fuseki-admin.name = org.apache.jena.fuseki.Admin + logger.fuseki-admin.level = INFO + + logger.jetty.name = org.eclipse.jetty + logger.jetty.level = WARN + + logger.shiro.name = org.apache.shiro + logger.shiro.level = WARN + + # This goes out in NCSA format + appender.plain.type = Console + appender.plain.name = PLAIN + appender.plain.layout.type = PatternLayout + appender.plain.layout.pattern = %m%n + + logger.fuseki-request.name = org.apache.jena.fuseki.Request + logger.fuseki-request.additivity = false + logger.fuseki-request.level = OFF + logger.fuseki-request.appenderRef.plain.ref = PLAIN + """; + } - /** - * A basic logging setup. Time and level INFO. - */ - private static String log4j2setupBase() { - return """ - ## Log4j2 properties syntax. - status = error - name = JenaLoggingDft - - # filters = threshold - # filter.threshold.type = ThresholdFilter - # filter.threshold.level = ALL - - appender.console.type = Console - appender.console.name = OUT - appender.console.target = SYSTEM_OUT - appender.console.layout.type = PatternLayout - appender.console.layout.pattern = %d{HH:mm:ss} %-5p %-15c{1} :: %m%n - # appender.console.layout.pattern = [%d{yyyy-MM-dd HH:mm:ss}] %-5p %-15c{1} :: %m%n - - rootLogger.level = INFO - rootLogger.appenderRef.stdout.ref = OUT - """; - } - /** Default log4j fragment needed for Jena command line tools. */ - private static String log4j2setupJenaLib() { - return """ - logger.jena.name = org.apache.jena - logger.jena.level = INFO - - logger.arq-exec.name = org.apache.jena.arq.exec - logger.arq-exec.level = INFO - - logger.riot.name = org.apache.jena.riot - logger.riot.level = INFO - """; - } - /** Additional log4j fragment for Fuseki in case the general default is used with embedded Fuseki. */ - private static String log4j2setupFuseki() { - return """ - # Fuseki. In case this logging setup gets install for embedded Fuseki. - - logger.fuseki.name = org.apache.jena.fuseki - logger.fuseki.level = INFO - logger.fuseki-fuseki.name = org.apache.jena.fuseki.Fuseki - logger.fuseki-fuseki.level = INFO - - logger.fuseki-server.name = org.apache.jena.fuseki.Server - logger.fuseki-server.level = INFO - - logger.fuseki-config.name = org.apache.jena.fuseki.Config - logger.fuseki-config.level = INFO - - logger.fuseki-admin.name = org.apache.jena.fuseki.Admin - logger.fuseki-admin.level = INFO - - logger.jetty.name = org.eclipse.jetty - logger.jetty.level = WARN - - logger.shiro.name = org.apache.shiro - logger.shiro.level = WARN - - # This goes out in NCSA format - appender.plain.type = Console - appender.plain.name = PLAIN - appender.plain.layout.type = PatternLayout - appender.plain.layout.pattern = %m%n - - logger.fuseki-request.name = org.apache.jena.fuseki.Request - logger.fuseki-request.additivity = false - logger.fuseki-request.level = OFF - logger.fuseki-request.appenderRef.plain.ref = PLAIN - """; } } diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/FusekiFilter.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/FusekiFilter.java index 86412a8c75d..268dab81134 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/FusekiFilter.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/FusekiFilter.java @@ -34,7 +34,7 @@ * for any service. */ public class FusekiFilter implements Filter { - private static Logger log = Fuseki.serverLog; + private static Logger LOG = Fuseki.serverLog; @Override public void init(FilterConfig filterConfig) {} @@ -50,7 +50,7 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha if ( handled ) return; } catch (Throwable ex) { - log.info("Filter: unexpected exception: "+ex.getMessage(),ex); + LOG.info("Filter: unexpected exception: "+ex.getMessage(),ex); } // Not found - continue.