Add 'domain' parameter to the Log4j 2.x agent
authorMichael Jeanson <mjeanson@efficios.com>
Thu, 10 Feb 2022 15:25:02 +0000 (15:25 +0000)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 21 Feb 2022 15:16:43 +0000 (10:16 -0500)
The initial Log4j 2.x agent commit only implemented a compatibility mode
to be used with the existing LOG4J domain in lttng-tools.

In this mode the agent converts the new Log4j 2.x loglevel values to
their corresponding Log4j 1.x values in the same way the upstream
compatibility bridge does.

This is great when doing in-place migration using the upstream
compatibility bridge but doesn't cover the usecase of an application
that natively uses Log4j 2.x.

This commit adds a new mandatory 'domain' parameter to the Log4j2 agent
which currently only implements the 'LOG4J' compatibility domain in
preparation to adding a 'LOG4J2' domain.

The configuration for a single appender in Log4j 1.x compat mode will
now look like this:

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="WARN">
      <Appenders>
        <Lttng name="LTTNG" domain="LOG4J"/>
      </Appenders>
      <Loggers>
        <Root level="all">
          <AppenderRef ref="LTTNG"/>
        </Root>
      </Loggers>
    </Configuration>

Change-Id: I7fd5f79ad58c77175714bd4198d8ff5db2e6b846
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
doc/examples/java-log4j2-basic/log4j2.xml
doc/examples/java-log4j2-ctx/log4j2.ctx1.xml
doc/examples/java-log4j2-ctx/log4j2.ctx2.xml
doc/examples/java-log4j2-prog/HelloLog4j2Prog.java
liblttng-ust-java-agent/java/lttng-ust-agent-log4j2/org/lttng/ust/agent/log4j2/LttngLogAppender.java

index 2dc83dd321ea174ab37a7841b0188858d3a82567..6ebcc3e14682785b1737665173a2a853ec053190 100644 (file)
@@ -4,7 +4,7 @@
     <Console name="Console" target="SYSTEM_OUT">
       <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
     </Console>
-    <Lttng name="Lttng">
+    <Lttng name="Lttng" domain="LOG4J">
     </Lttng>
   </Appenders>
   <Loggers>
index d59ce7709495a2100cbe565c8d1cac84d38fa8c0..52ad5a7ccbb08788e1d6a8543fc32ced20f8cc04 100644 (file)
@@ -4,7 +4,7 @@
     <Console name="Console" target="SYSTEM_OUT">
       <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
     </Console>
-    <Lttng name="Lttng">
+    <Lttng name="Lttng" domain="LOG4J">
     </Lttng>
   </Appenders>
   <Loggers>
index c62af2e5328a546fa7d10788c167547e814f2660..011152dcb7ffb99f968c5977b8118f190e170995 100644 (file)
@@ -4,7 +4,7 @@
     <Console name="Console" target="SYSTEM_OUT">
       <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
     </Console>
-    <Lttng name="Lttng">
+    <Lttng name="Lttng" domain="LOG4J">
     </Lttng>
   </Appenders>
   <Loggers>
index 685eebfa41a9c0d96cd59d386be9b4c38b5c08fe..2632ab1d7a2e32861c37e9ac012eef02526b4bd7 100644 (file)
@@ -50,18 +50,19 @@ public class HelloLog4j2Prog {
                standardLayout.addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable");
 
                /* Create a console appender */
-               AppenderComponentBuilder appenderBuilder = builder.newAppender("Stdout", "CONSOLE");
+               AppenderComponentBuilder appenderBuilder = builder.newAppender("Stdout", "Console");
                appenderBuilder.add(standardLayout);
                builder.add(appenderBuilder);
 
                /* Create an Lttng appender */
-               appenderBuilder = builder.newAppender("Lttng", "LTTNG");
+               appenderBuilder = builder.newAppender("Lttng1", "Lttng");
+               appenderBuilder.addAttribute("domain", "LOG4J");
                builder.add(appenderBuilder);
 
                /* Create a root logger with both appenders attached */
                RootLoggerComponentBuilder rootLogger = builder.newRootLogger(Level.DEBUG);
                rootLogger.add(builder.newAppenderRef("Stdout"));
-               rootLogger.add(builder.newAppenderRef("Lttng"));
+               rootLogger.add(builder.newAppenderRef("Lttng1"));
                builder.add(rootLogger);
 
                Configurator.initialize(builder.build());
index 08612f57cd2f5bcdb93137fd7101b05637377cff..3b7afa5b72dadb4bd6510b42c94e423d402773d9 100644 (file)
@@ -26,6 +26,7 @@ import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginElement;
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
 import org.apache.logging.log4j.message.Message;
+import org.lttng.ust.agent.ILttngAgent.Domain;
 import org.lttng.ust.agent.ILttngHandler;
 import org.lttng.ust.agent.context.ContextInfoSerializer;
 
@@ -61,20 +62,24 @@ public final class LttngLogAppender extends AbstractAppender implements ILttngHa
         * Constructor
         *
         * @param name             The name of the Appender.
+        * @param domain           The LTTng-UST agent domain 'LOG4J' / 'LOG4J2'.
         * @param filter           The Filter or null.
-        * @param ignoreExceptions If {@code "true"} (default) exceptions encountered
-        *                         when appending events are logged; otherwise they are
+        * @param ignoreExceptions If {@code "true"} exceptions encountered when
+        *                         appending events are logged; otherwise they are
         *                         propagated to the caller.
         *
-        * @throws IOException       This handler requires the lttng-ust-log4j-jni.so
-        *                           native library, through which it will send the
-        *                           trace events. This exception is thrown if this
-        *                           library cannot be found.
-        * @throws SecurityException We will forward any SecurityExcepion that may be
-        *                           thrown when trying to load the JNI library.
+        * @throws IOException              This handler requires the
+        *                                  lttng-ust-log4j-jni.so native library,
+        *                                  through which it will send the trace events.
+        *                                  This exception is thrown if this library
+        *                                  cannot be found.
+        * @throws IllegalArgumentException If the provided domain is unsupported.
+        * @throws SecurityException        We will forward any SecurityExcepion that
+        *                                  may be thrown when trying to load the JNI
+        *                                  library.
         */
-       protected LttngLogAppender(String name, Filter filter, boolean ignoreExceptions)
-                       throws IOException, SecurityException {
+       protected LttngLogAppender(String name, LttngLog4j2Agent.Domain domain, Filter filter, boolean ignoreExceptions)
+                       throws IOException, IllegalArgumentException, SecurityException {
 
                super(name, filter, null, ignoreExceptions, Property.EMPTY_ARRAY);
 
@@ -86,7 +91,12 @@ public final class LttngLogAppender extends AbstractAppender implements ILttngHa
                }
 
                /* Register to the relevant agent. */
-               agent = LttngLog4j2Agent.getInstance();
+               if (domain == LttngLog4j2Agent.Domain.LOG4J) {
+                       agent = LttngLog4j2Agent.getInstance();
+               } else {
+                       throw new IllegalArgumentException("Unsupported domain '" + domain + "'");
+               }
+
                agent.registerHandler(this);
        }
 
@@ -94,35 +104,59 @@ public final class LttngLogAppender extends AbstractAppender implements ILttngHa
         * Create an LttngLogAppender.
         *
         * @param name             The name of the Appender, null returns null.
+        * @param domain           The LTTng-UST agent domain 'LOG4J' / 'LOG4J2'.
         * @param ignoreExceptions If {@code "true"} (default) exceptions encountered
         *                         when appending events are logged; otherwise they are
         *                         propagated to the caller.
         * @param filter           The Filter or null.
         *
-        * @return A new LttngLogAppender, null if the name was null.
-        *
-        * @throws IOException       This handler requires the lttng-ust-log4j-jni.so
-        *                           native library, through which it will send the
-        *                           trace events. This exception is thrown if this
-        *                           library cannot be found.
-        * @throws SecurityException We will forward any SecurityExcepion that may be
-        *                           thrown when trying to load the JNI library.
+        * @return A new LttngLogAppender, null if the name was null or the domain is
+        *         null or invalid.
         */
        @PluginFactory
        public static LttngLogAppender createAppender(@PluginAttribute("name") String name,
-                       @PluginAttribute("ignoreExceptions") Boolean ignoreExceptions, @PluginElement("Filters") Filter filter)
-                       throws IOException, SecurityException {
+                       @PluginAttribute("domain") String domain, @PluginAttribute("ignoreExceptions") Boolean ignoreExceptions,
+                       @PluginElement("Filters") Filter filter) {
 
                if (name == null) {
                        LOGGER.error("No name provided for LttngLogAppender");
                        return null;
                }
 
+               if (domain == null) {
+                       LOGGER.error("No domain provided for LttngLogAppender");
+                       return null;
+               }
+
                if (ignoreExceptions == null) {
                        ignoreExceptions = true;
                }
 
-               return new LttngLogAppender(name, filter, ignoreExceptions);
+               /* Parse the domain string */
+               LttngLog4j2Agent.Domain parsedDomain;
+               try {
+                       parsedDomain = LttngLog4j2Agent.Domain.valueOf(domain.toUpperCase());
+               } catch (IllegalArgumentException e) {
+                       LOGGER.error("Invalid domain '{}' for LttngLogAppender", domain);
+                       return null;
+               }
+
+               /* Create the appender and handle the possible failures. */
+               LttngLogAppender newAppender;
+               try {
+                       newAppender = new LttngLogAppender(name, parsedDomain, filter, ignoreExceptions);
+               } catch (IllegalArgumentException e) {
+                       LOGGER.error("Invalid domain '{}' for LttngLogAppender", parsedDomain);
+                       newAppender = null;
+               } catch (SecurityException e) {
+                       LOGGER.error("Security error trying to load '{}' JNI library for LttngLogAppender", SHARED_OBJECT_NAME);
+                       newAppender = null;
+               } catch (IOException e) {
+                       LOGGER.error("Failed to load '{}' JNI library for LttngLogAppender", SHARED_OBJECT_NAME);
+                       newAppender = null;
+               }
+
+               return newAppender;
        }
 
        @Override
This page took 0.029501 seconds and 4 git commands to generate.