diff --git a/.gitignore b/.gitignore index 5d0ac80..425f5b4 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,4 @@ target out/ bin/ .*.swp -ecplise/ \ No newline at end of file +eclipse/ diff --git a/jul-helper-api/pom.xml b/jul-helper-api/pom.xml index 96f4e17..ddbc286 100644 --- a/jul-helper-api/pom.xml +++ b/jul-helper-api/pom.xml @@ -6,7 +6,7 @@ org.iglooproject.components igloo-logging - 1.0.2 + 1.1.0 jul-helper-api @@ -37,4 +37,4 @@ - \ No newline at end of file + diff --git a/jul-helper/pom.xml b/jul-helper/pom.xml index da49efb..ec115df 100644 --- a/jul-helper/pom.xml +++ b/jul-helper/pom.xml @@ -6,7 +6,7 @@ org.iglooproject.components igloo-logging - 1.0.2 + 1.1.0 jul-helper @@ -24,6 +24,11 @@ javax.servlet-api provided + + jakarta.servlet + jakarta.servlet-api + provided + org.slf4j jul-to-slf4j @@ -71,4 +76,4 @@ - \ No newline at end of file + diff --git a/jul-helper/src/main/java/igloo/julhelper/internal/AbstractJulLoggingListener.java b/jul-helper/src/main/java/igloo/julhelper/internal/AbstractJulLoggingListener.java new file mode 100644 index 0000000..533a211 --- /dev/null +++ b/jul-helper/src/main/java/igloo/julhelper/internal/AbstractJulLoggingListener.java @@ -0,0 +1,128 @@ +package igloo.julhelper.internal; + +import java.util.Optional; +import java.util.logging.Level; +import java.util.logging.LogManager; + +import javax.management.ObjectName; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.bridge.SLF4JBridgeHandler; + +import igloo.julhelper.jmx.JulLoggingManagerMBean; + +/** + * # Usage + * + * Conditionally install {@link SLF4JBridgeHandler} and `igloo:type=LoggingManager,name=JulLoggingManager` JMX Bean. + * + * Behavior can be controlled with `skipJulSlf4jBridgeHandler` and `skipJulJmxHelper` init parameters. + * Default behavior is to add both helpers. + * + * `julKnownLoggersResourcePath` init parameter allows to point a resource for loading well-known JUL logger names. + * This file must contain a line by JUL logger. This list is used to conditionally apply logger updates from + * third-party components (like Log4j2LoggingManager), so that JUL logger configuration is applied only for loggers + * and children from this list. By default, `jul-helper/well-known-jul-loggers.txt` is used. You can disable + * this loading with the value `none`. Effective configuration can be retrieve from JMX bean. + * + * This listener can be added in `web.xml` by adding this extract among the first listeners (`context-param` may be + * omitted if default values are convenient): + * + *
{@code
+ * 
+ *   igloo.julhelper.servlet.JulLoggingListener
+ * 
+ * 
+ *   skipJulSlf4jBridgeHandler
+ *   false
+ * 
+ * 
+ *   skipJulJmxHelper
+ *   false
+ * 
+ * }
+ * + * # About SLF4JBridgeHandler + * + * Purpose of SLF4JBridgeHandler is to install a handler on the `java.util.logging` root logger. All event that can be + * forwarded from child logger and accepted by root logger level can then be handled by SLF4J. + * + * It implies that level must be set accordingly so that log event can be propagated to SLF4J bridge handler. Either: + * + * * Set a catch-all root level, and do not set level on any child. This configuration implies a performance hit as + * all log event are propagated; + * * Set a catch-all root level, set warning or error level to limit propagation of unwanted loggers. This allows to + * limit log event volume. This configuration needs to configure both JUL and SLF4J backend consistently; + * * Set a WARN root level, and attach {@link SLF4JBridgeHandler} on each targeted child logger. JUL and SLF4J + * backend need to be configured consistently. + * + * # About JUL JMX helper + * + * This JMX MBean allows to bind {@link SLF4JBridgeHandler} and set level on arbitrary loggers to activate logging + * during runtime. + */ +public abstract class AbstractJulLoggingListener { + + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractJulLoggingListener.class); + + private static final String PARAMETER_SKIP_JUL_SLF4J_BRIDGE_HANDLER = "skipJulSlf4jBridgeHandler"; + private static final String PARAMETER_SKIP_JUL_JMX_HELPER = "skipJulJmxHelper"; + private static final String PARAMETER_JUL_KNOWN_LOGGERS_RESOURCE_PATH = "julKnownLoggersResourcePath"; + + private ObjectName mbeanObjectName; + + /** + * @see AbstractJulLoggingListener + */ + public void contextInitialized(CommonContextEvent sce) { + // "" triggers default loading + String julKnownLoggersResourcePath = Optional.ofNullable(sce.getInitParameter(PARAMETER_JUL_KNOWN_LOGGERS_RESOURCE_PATH)).orElse(""); + if ("none".equalsIgnoreCase(julKnownLoggersResourcePath)) { + // disable loading + julKnownLoggersResourcePath = null; + } + + if (!getBooleanParameter(sce, PARAMETER_SKIP_JUL_SLF4J_BRIDGE_HANDLER)) { + initSlf4jBridgeHandler(); + } + + if (!getBooleanParameter(sce, PARAMETER_SKIP_JUL_JMX_HELPER)) { + mbeanObjectName = JulLoggingManagerMBean.registerMBean(julKnownLoggersResourcePath); + } + + LOGGER.info("jul-to-slf4j installed"); + } + + /** + * Install jul-to-slf4j bridge handler. + */ + private void initSlf4jBridgeHandler() { + LogManager.getLogManager().reset(); + java.util.logging.Logger.getLogger("").setLevel(Level.WARNING); + SLF4JBridgeHandler.removeHandlersForRootLogger(); + SLF4JBridgeHandler.install(); + } + + /** + * @see AbstractJulLoggingListener + */ + public void contextDestroyed() { + if (mbeanObjectName != null) { + JulLoggingManagerMBean.unregisterMBean(mbeanObjectName); + } + } + + /** + * Extract boolean parameter named `paramName` from `sce`. Returns true only if parameter value is `true`. + * + * @param sce configuration provider. Required. + * @param paramName name of the boolean parameter to extract. Required. + * @return true if parameter string value is `true`. false for other values or missing parameter. + */ + private boolean getBooleanParameter(CommonContextEvent sce, String paramName) { + String param = sce.getInitParameter(paramName); + return Boolean.TRUE.toString().equals(param); + } + +} diff --git a/jul-helper/src/main/java/igloo/julhelper/internal/CommonContextEvent.java b/jul-helper/src/main/java/igloo/julhelper/internal/CommonContextEvent.java new file mode 100644 index 0000000..7b99a42 --- /dev/null +++ b/jul-helper/src/main/java/igloo/julhelper/internal/CommonContextEvent.java @@ -0,0 +1,7 @@ +package igloo.julhelper.internal; + +public interface CommonContextEvent { + + String getInitParameter(String paramName); + +} diff --git a/jul-helper/src/main/java/igloo/julhelper/internal/JakartaContextEventWrapper.java b/jul-helper/src/main/java/igloo/julhelper/internal/JakartaContextEventWrapper.java new file mode 100644 index 0000000..02f2987 --- /dev/null +++ b/jul-helper/src/main/java/igloo/julhelper/internal/JakartaContextEventWrapper.java @@ -0,0 +1,17 @@ +package igloo.julhelper.internal; + +public class JakartaContextEventWrapper implements CommonContextEvent { + + private final jakarta.servlet.ServletContextEvent contextEvent; + + public JakartaContextEventWrapper(jakarta.servlet.ServletContextEvent contextEvent) { + super(); + this.contextEvent = contextEvent; + } + + @Override + public String getInitParameter(String paramName) { + return contextEvent.getServletContext().getInitParameter(paramName); + } + +} diff --git a/jul-helper/src/main/java/igloo/julhelper/internal/JavaxContextEventWrapper.java b/jul-helper/src/main/java/igloo/julhelper/internal/JavaxContextEventWrapper.java new file mode 100644 index 0000000..6935ee4 --- /dev/null +++ b/jul-helper/src/main/java/igloo/julhelper/internal/JavaxContextEventWrapper.java @@ -0,0 +1,19 @@ +package igloo.julhelper.internal; + +import javax.servlet.ServletContextEvent; + +public class JavaxContextEventWrapper implements CommonContextEvent { + + private final ServletContextEvent contextEvent; + + public JavaxContextEventWrapper(ServletContextEvent contextEvent) { + super(); + this.contextEvent = contextEvent; + } + + @Override + public String getInitParameter(String paramName) { + return contextEvent.getServletContext().getInitParameter(paramName); + } + +} diff --git a/jul-helper/src/main/java/igloo/julhelper/servlet/JakartaJulLoggingListener.java b/jul-helper/src/main/java/igloo/julhelper/servlet/JakartaJulLoggingListener.java new file mode 100644 index 0000000..1d57410 --- /dev/null +++ b/jul-helper/src/main/java/igloo/julhelper/servlet/JakartaJulLoggingListener.java @@ -0,0 +1,25 @@ +package igloo.julhelper.servlet; + +import igloo.julhelper.internal.AbstractJulLoggingListener; +import igloo.julhelper.internal.JakartaContextEventWrapper; +import jakarta.servlet.ServletContextEvent; +import jakarta.servlet.ServletContextListener; + +/** + * jakarta.servlet version. + * + * @see AbstractJulLoggingListener + */ +public class JakartaJulLoggingListener extends AbstractJulLoggingListener implements ServletContextListener { + + @Override + public void contextInitialized(ServletContextEvent sce) { + super.contextInitialized(new JakartaContextEventWrapper(sce)); + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + super.contextDestroyed(); + } + +} diff --git a/jul-helper/src/main/java/igloo/julhelper/servlet/JulLoggingListener.java b/jul-helper/src/main/java/igloo/julhelper/servlet/JulLoggingListener.java index 64f4775..e560eab 100644 --- a/jul-helper/src/main/java/igloo/julhelper/servlet/JulLoggingListener.java +++ b/jul-helper/src/main/java/igloo/julhelper/servlet/JulLoggingListener.java @@ -1,132 +1,25 @@ package igloo.julhelper.servlet; -import java.util.Optional; -import java.util.logging.Level; -import java.util.logging.LogManager; - -import javax.management.ObjectName; -import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.slf4j.bridge.SLF4JBridgeHandler; - -import igloo.julhelper.jmx.JulLoggingManagerMBean; +import igloo.julhelper.internal.AbstractJulLoggingListener; +import igloo.julhelper.internal.JavaxContextEventWrapper; /** - * # Usage - * - * Conditionally install {@link SLF4JBridgeHandler} and `igloo:type=LoggingManager,name=JulLoggingManager` JMX Bean. - * - * Behavior can be controlled with `skipJulSlf4jBridgeHandler` and `skipJulJmxHelper` init parameters. - * Default behavior is to add both helpers. - * - * `julKnownLoggersResourcePath` init parameter allows to point a resource for loading well-known JUL logger names. - * This file must contain a line by JUL logger. This list is used to conditionally apply logger updates from - * third-party components (like Log4j2LoggingManager), so that JUL logger configuration is applied only for loggers - * and children from this list. By default, `jul-helper/well-known-jul-loggers.txt` is used. You can disable - * this loading with the value `none`. Effective configuration can be retrieve from JMX bean. - * - * This listener can be added in `web.xml` by adding this extract among the first listeners (`context-param` may be - * omitted if default values are convenient): - * - *
{@code
- * 
- *   igloo.julhelper.servlet.JulLoggingListener
- * 
- * 
- *   skipJulSlf4jBridgeHandler
- *   false
- * 
- * 
- *   skipJulJmxHelper
- *   false
- * 
- * }
- * - * # About SLF4JBridgeHandler - * - * Purpose of SLF4JBridgeHandler is to install a handler on the `java.util.logging` root logger. All event that can be - * forwarded from child logger and accepted by root logger level can then be handled by SLF4J. + * javax.servlet version. * - * It implies that level must be set accordingly so that log event can be propagated to SLF4J bridge handler. Either: - * - * * Set a catch-all root level, and do not set level on any child. This configuration implies a performance hit as - * all log event are propagated; - * * Set a catch-all root level, set warning or error level to limit propagation of unwanted loggers. This allows to - * limit log event volume. This configuration needs to configure both JUL and SLF4J backend consistently; - * * Set a WARN root level, and attach {@link SLF4JBridgeHandler} on each targeted child logger. JUL and SLF4J - * backend need to be configured consistently. - * - * # About JUL JMX helper - * - * This JMX MBean allows to bind {@link SLF4JBridgeHandler} and set level on arbitrary loggers to activate logging - * during runtime. + * @see AbstractJulLoggingListener */ -public class JulLoggingListener implements ServletContextListener { - - private static final Logger LOGGER = LoggerFactory.getLogger(JulLoggingListener.class); - - private static final String PARAMETER_SKIP_JUL_SLF4J_BRIDGE_HANDLER = "skipJulSlf4jBridgeHandler"; - private static final String PARAMETER_SKIP_JUL_JMX_HELPER = "skipJulJmxHelper"; - private static final String PARAMETER_JUL_KNOWN_LOGGERS_RESOURCE_PATH = "julKnownLoggersResourcePath"; - - private ObjectName mbeanObjectName; +public class JulLoggingListener extends AbstractJulLoggingListener implements ServletContextListener { - /** - * @see JulLoggingListener - */ @Override - public void contextInitialized(ServletContextEvent sce) { - // "" triggers default loading - String julKnownLoggersResourcePath = Optional.ofNullable(sce.getServletContext().getInitParameter(PARAMETER_JUL_KNOWN_LOGGERS_RESOURCE_PATH)).orElse(""); - if ("none".equalsIgnoreCase(julKnownLoggersResourcePath)) { - // disable loading - julKnownLoggersResourcePath = null; - } - - if (!getBooleanParameter(sce, PARAMETER_SKIP_JUL_SLF4J_BRIDGE_HANDLER)) { - initSlf4jBridgeHandler(); - } - - if (!getBooleanParameter(sce, PARAMETER_SKIP_JUL_JMX_HELPER)) { - mbeanObjectName = JulLoggingManagerMBean.registerMBean(julKnownLoggersResourcePath); - } - - LOGGER.info("jul-to-slf4j installed"); + public void contextInitialized(javax.servlet.ServletContextEvent sce) { + super.contextInitialized(new JavaxContextEventWrapper(sce)); } - /** - * Install jul-to-slf4j bridge handler. - */ - private void initSlf4jBridgeHandler() { - LogManager.getLogManager().reset(); - java.util.logging.Logger.getLogger("").setLevel(Level.WARNING); - SLF4JBridgeHandler.removeHandlersForRootLogger(); - SLF4JBridgeHandler.install(); - } - - /** - * @see JulLoggingListener - */ @Override - public void contextDestroyed(ServletContextEvent sce) { - if (mbeanObjectName != null) { - JulLoggingManagerMBean.unregisterMBean(mbeanObjectName); - } - } - - /** - * Extract boolean parameter named `paramName` from `sce`. Returns true only if parameter value is `true`. - * - * @param sce configuration provider. Required. - * @param paramName name of the boolean parameter to extract. Required. - * @return true if parameter string value is `true`. false for other values or missing parameter. - */ - private boolean getBooleanParameter(ServletContextEvent sce, String paramName) { - String param = sce.getServletContext().getInitParameter(paramName); - return Boolean.TRUE.toString().equals(param); + public void contextDestroyed(javax.servlet.ServletContextEvent sce) { + super.contextDestroyed(); } } diff --git a/log4j2-jmx-helper/pom.xml b/log4j2-jmx-helper/pom.xml index 7fd643a..7cf758f 100644 --- a/log4j2-jmx-helper/pom.xml +++ b/log4j2-jmx-helper/pom.xml @@ -6,7 +6,7 @@ org.iglooproject.components igloo-logging - 1.0.2 + 1.1.0 log4j2-jmx-helper @@ -32,6 +32,11 @@ javax.servlet-api provided
+ + jakarta.servlet + jakarta.servlet-api + provided + org.apache.logging.log4j log4j-core @@ -84,4 +89,4 @@ - \ No newline at end of file + diff --git a/log4j2-jmx-helper/src/main/java/igloo/log4j2jmx/servlet/AbstractLog4j2LoggingManagerListener.java b/log4j2-jmx-helper/src/main/java/igloo/log4j2jmx/servlet/AbstractLog4j2LoggingManagerListener.java new file mode 100644 index 0000000..e68b958 --- /dev/null +++ b/log4j2-jmx-helper/src/main/java/igloo/log4j2jmx/servlet/AbstractLog4j2LoggingManagerListener.java @@ -0,0 +1,54 @@ +package igloo.log4j2jmx.servlet; + +import javax.management.ObjectName; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import igloo.julhelper.internal.AbstractJulLoggingListener; +import igloo.log4j2jmx.jmx.Log4j2LoggingManager; +import igloo.log4j2jmx.jmx.Log4j2LoggingManagerMBean; + +/** + * Install a {@link Log4j2LoggingManager} MBean. This listener does not use any `context-param`. This logging manager + * installs a MBean that allows to dynamically reconfigure log4j2 loggers (log4j2 default implementation only + * allows to reconfigure already configured loggers). + * + * {@link AbstractJulLoggingListener} (jul-helper dependency) is a needed companion if you want to reconfigure JUL loggers at runtime. + * julKnownLoggers configuration (runtime or startup) may need customization to allow JUL logging override. See + * {@link AbstractJulLoggingListener} for further documentation. + * + * `igloo-logging:jul-helper` dependency must be added to use JUL reconfiguration. + * + * Commplete default setup : + * + *
{@code
+ * 
+ *   igloo.julhelper.servlet.JulLoggingListener
+ * 
+ * 
+ *   igloo.log4j2jmx.servlet.Log4j2LoggingManagerListener
+ * 
+ * }
+ * + * @see Log4j2LoggingManager + */ +public abstract class AbstractLog4j2LoggingManagerListener { + + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractLog4j2LoggingManagerListener.class); + + private ObjectName mbeanObjectName; + + public void contextInitialized() { + mbeanObjectName = Log4j2LoggingManagerMBean.registerMBean(); + + LOGGER.info("jul-to-slf4j installed"); + } + + public void contextDestroyed() { + if (mbeanObjectName != null) { + Log4j2LoggingManagerMBean.unregisterMBean(mbeanObjectName); + } + } + +} diff --git a/log4j2-jmx-helper/src/main/java/igloo/log4j2jmx/servlet/JakartaLog4j2LoggingManagerListener.java b/log4j2-jmx-helper/src/main/java/igloo/log4j2jmx/servlet/JakartaLog4j2LoggingManagerListener.java new file mode 100644 index 0000000..04557f1 --- /dev/null +++ b/log4j2-jmx-helper/src/main/java/igloo/log4j2jmx/servlet/JakartaLog4j2LoggingManagerListener.java @@ -0,0 +1,18 @@ +package igloo.log4j2jmx.servlet; + +import jakarta.servlet.ServletContextEvent; +import jakarta.servlet.ServletContextListener; + +public class JakartaLog4j2LoggingManagerListener extends AbstractLog4j2LoggingManagerListener + implements ServletContextListener { + + @Override + public void contextInitialized(ServletContextEvent sce) { + super.contextInitialized(); + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + super.contextDestroyed(); + } +} diff --git a/log4j2-jmx-helper/src/main/java/igloo/log4j2jmx/servlet/Log4j2LoggingManagerListener.java b/log4j2-jmx-helper/src/main/java/igloo/log4j2jmx/servlet/Log4j2LoggingManagerListener.java index 3fac3a6..08a2e72 100644 --- a/log4j2-jmx-helper/src/main/java/igloo/log4j2jmx/servlet/Log4j2LoggingManagerListener.java +++ b/log4j2-jmx-helper/src/main/java/igloo/log4j2jmx/servlet/Log4j2LoggingManagerListener.java @@ -1,58 +1,19 @@ package igloo.log4j2jmx.servlet; -import javax.management.ObjectName; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import igloo.julhelper.servlet.JulLoggingListener; -import igloo.log4j2jmx.jmx.Log4j2LoggingManager; -import igloo.log4j2jmx.jmx.Log4j2LoggingManagerMBean; - -/** - * Install a {@link Log4j2LoggingManager} MBean. This listener does not use any `context-param`. This logging manager - * installs a MBean that allows to dynamically reconfigure log4j2 loggers (log4j2 default implementation only - * allows to reconfigure already configured loggers). - * - * {@link JulLoggingListener} (jul-helper dependency) is a needed companion if you want to reconfigure JUL loggers at runtime. - * julKnownLoggers configuration (runtime or startup) may need customization to allow JUL logging override. See - * {@link JulLoggingListener} for further documentation. - * - * `igloo-logging:jul-helper` dependency must be added to use JUL reconfiguration. - * - * Commplete default setup : - * - *
{@code
- * 
- *   igloo.julhelper.servlet.JulLoggingListener
- * 
- * 
- *   igloo.log4j2jmx.servlet.Log4j2LoggingManagerListener
- * 
- * }
- * - * @see Log4j2LoggingManager - */ -public class Log4j2LoggingManagerListener implements ServletContextListener { - - private static final Logger LOGGER = LoggerFactory.getLogger(Log4j2LoggingManagerListener.class); - - private ObjectName mbeanObjectName; - +public class Log4j2LoggingManagerListener extends AbstractLog4j2LoggingManagerListener + implements ServletContextListener { + @Override public void contextInitialized(ServletContextEvent sce) { - mbeanObjectName = Log4j2LoggingManagerMBean.registerMBean(); - - LOGGER.info("jul-to-slf4j installed"); + super.contextInitialized(); } @Override public void contextDestroyed(ServletContextEvent sce) { - if (mbeanObjectName != null) { - Log4j2LoggingManagerMBean.unregisterMBean(mbeanObjectName); - } + super.contextDestroyed(); } } diff --git a/pom.xml b/pom.xml index c837add..d3e5cc3 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.iglooproject.components igloo-logging - 1.0.2 + 1.1.0 pom @@ -42,6 +42,11 @@ import pom
+ + jakarta.servlet + jakarta.servlet-api + 6.0.0 +