From 51caaf207d2603fe8b6ba39f8db16970008f0c09 Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Fri, 10 May 2024 18:28:37 +0100 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 +++++++++++------- 3 files changed, 159 insertions(+), 128 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 ccc898d56ae..0a5354dfe4f 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 @@ -53,6 +53,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 - """; } }