-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
305 additions
and
168 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,4 +7,4 @@ target | |
out/ | ||
bin/ | ||
.*.swp | ||
ecplise/ | ||
eclipse/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
128 changes: 128 additions & 0 deletions
128
jul-helper/src/main/java/igloo/julhelper/internal/AbstractJulLoggingListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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): | ||
* | ||
* <pre>{@code | ||
* <listener> | ||
* <listener-class>igloo.julhelper.servlet.JulLoggingListener</listener-class> | ||
* </listener> | ||
* <context-param> | ||
* <param-name>skipJulSlf4jBridgeHandler</param-name> | ||
* <param-value>false</param-value> | ||
* </context-param> | ||
* <context-param> | ||
* <param-name>skipJulJmxHelper</param-name> | ||
* <param-value>false</param-value> | ||
* </context-param> | ||
* }</pre> | ||
* | ||
* # 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); | ||
} | ||
|
||
} |
7 changes: 7 additions & 0 deletions
7
jul-helper/src/main/java/igloo/julhelper/internal/CommonContextEvent.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package igloo.julhelper.internal; | ||
|
||
public interface CommonContextEvent { | ||
|
||
String getInitParameter(String paramName); | ||
|
||
} |
17 changes: 17 additions & 0 deletions
17
jul-helper/src/main/java/igloo/julhelper/internal/JakartaContextEventWrapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
|
||
} |
19 changes: 19 additions & 0 deletions
19
jul-helper/src/main/java/igloo/julhelper/internal/JavaxContextEventWrapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
|
||
} |
25 changes: 25 additions & 0 deletions
25
jul-helper/src/main/java/igloo/julhelper/servlet/JakartaJulLoggingListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
|
||
/** | ||
* <code>jakarta.servlet</code> 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(); | ||
} | ||
|
||
} |
125 changes: 9 additions & 116 deletions
125
jul-helper/src/main/java/igloo/julhelper/servlet/JulLoggingListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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): | ||
* | ||
* <pre>{@code | ||
* <listener> | ||
* <listener-class>igloo.julhelper.servlet.JulLoggingListener</listener-class> | ||
* </listener> | ||
* <context-param> | ||
* <param-name>skipJulSlf4jBridgeHandler</param-name> | ||
* <param-value>false</param-value> | ||
* </context-param> | ||
* <context-param> | ||
* <param-name>skipJulJmxHelper</param-name> | ||
* <param-value>false</param-value> | ||
* </context-param> | ||
* }</pre> | ||
* | ||
* # 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. | ||
* <code>javax.servlet</code> 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(); | ||
} | ||
|
||
} |
Oops, something went wrong.