From 495b8381eb4348cdad015e3c324bc4edccfd53d3 Mon Sep 17 00:00:00 2001 From: Michael Jeanson Date: Thu, 10 Feb 2022 15:25:54 +0000 Subject: [PATCH] Add LOG4J2 domain to the Log4j 2.x agent This commit adds a new LOG4J2 domain with native Log4j 2.x loglevels in addition to the existing LOG4J domain. Both domains can be used individually or at the same time by instantiating one or more appenders. For example, a single appender in Log4j 2.x native mode: Two appenders to enable both domains: Change-Id: I9a41e107d19d5a0efffe055edf0ca5211a7f6d6b Signed-off-by: Michael Jeanson Signed-off-by: Mathieu Desnoyers --- doc/examples/java-log4j2-basic/log4j2.xml | 6 ++- doc/examples/java-log4j2-ctx/log4j2.ctx1.xml | 6 ++- doc/examples/java-log4j2-ctx/log4j2.ctx2.xml | 6 ++- .../java-log4j2-prog/HelloLog4j2Prog.java | 8 +++- .../org/lttng/ust/agent/ILttngAgent.java | 2 +- .../ust/agent/log4j2/LttngLog4j2Agent.java | 22 ++++++--- .../ust/agent/log4j2/LttngLog4j2Api.java | 4 +- .../ust/agent/log4j2/LttngLogAppender.java | 6 ++- .../jni/log4j/Makefile.am | 2 + .../jni/log4j/lttng_ust_log4j2.c | 22 +++++++-- .../jni/log4j/lttng_ust_log4j2_tp.c | 14 ++++++ .../jni/log4j/lttng_ust_log4j2_tp.h | 48 +++++++++++++++++++ .../jni/log4j/lttng_ust_log4j_tp.h | 2 +- 13 files changed, 124 insertions(+), 24 deletions(-) create mode 100644 src/lib/lttng-ust-java-agent/jni/log4j/lttng_ust_log4j2_tp.c create mode 100644 src/lib/lttng-ust-java-agent/jni/log4j/lttng_ust_log4j2_tp.h diff --git a/doc/examples/java-log4j2-basic/log4j2.xml b/doc/examples/java-log4j2-basic/log4j2.xml index 6ebcc3e1..6e5fb83e 100644 --- a/doc/examples/java-log4j2-basic/log4j2.xml +++ b/doc/examples/java-log4j2-basic/log4j2.xml @@ -4,13 +4,15 @@ - + + - + + diff --git a/doc/examples/java-log4j2-ctx/log4j2.ctx1.xml b/doc/examples/java-log4j2-ctx/log4j2.ctx1.xml index 52ad5a7c..5606e452 100644 --- a/doc/examples/java-log4j2-ctx/log4j2.ctx1.xml +++ b/doc/examples/java-log4j2-ctx/log4j2.ctx1.xml @@ -4,13 +4,15 @@ - + + - + + diff --git a/doc/examples/java-log4j2-ctx/log4j2.ctx2.xml b/doc/examples/java-log4j2-ctx/log4j2.ctx2.xml index 011152dc..003ae105 100644 --- a/doc/examples/java-log4j2-ctx/log4j2.ctx2.xml +++ b/doc/examples/java-log4j2-ctx/log4j2.ctx2.xml @@ -4,13 +4,15 @@ - + + - + + diff --git a/doc/examples/java-log4j2-prog/HelloLog4j2Prog.java b/doc/examples/java-log4j2-prog/HelloLog4j2Prog.java index 2632ab1d..5b748cce 100644 --- a/doc/examples/java-log4j2-prog/HelloLog4j2Prog.java +++ b/doc/examples/java-log4j2-prog/HelloLog4j2Prog.java @@ -54,15 +54,21 @@ public class HelloLog4j2Prog { appenderBuilder.add(standardLayout); builder.add(appenderBuilder); - /* Create an Lttng appender */ + /* Create an Lttng appender for the LOG4J domain */ appenderBuilder = builder.newAppender("Lttng1", "Lttng"); appenderBuilder.addAttribute("domain", "LOG4J"); builder.add(appenderBuilder); + /* Create an Lttng appender for the LOG4J2 domain */ + appenderBuilder = builder.newAppender("Lttng2", "Lttng"); + appenderBuilder.addAttribute("domain", "LOG4J2"); + 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("Lttng1")); + rootLogger.add(builder.newAppenderRef("Lttng2")); builder.add(rootLogger); Configurator.initialize(builder.build()); diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/ILttngAgent.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/ILttngAgent.java index ca2358a5..ee0397c2 100644 --- a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/ILttngAgent.java +++ b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/ILttngAgent.java @@ -34,7 +34,7 @@ public interface ILttngAgent { * Tracing domains. Corresponds to domains defined by LTTng Tools. */ enum Domain { - JUL(3), LOG4J(4); + JUL(3), LOG4J(4), LOG4J2(6); private int value; private Domain(int value) { diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j2/org/lttng/ust/agent/log4j2/LttngLog4j2Agent.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j2/org/lttng/ust/agent/log4j2/LttngLog4j2Agent.java index cb7c35ad..707639a1 100644 --- a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j2/org/lttng/ust/agent/log4j2/LttngLog4j2Agent.java +++ b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j2/org/lttng/ust/agent/log4j2/LttngLog4j2Agent.java @@ -27,17 +27,25 @@ import org.lttng.ust.agent.AbstractLttngAgent; */ class LttngLog4j2Agent extends AbstractLttngAgent { - private static LttngLog4j2Agent instance = null; + private static LttngLog4j2Agent log4j2_instance = null; + private static LttngLog4j2Agent log4j1_instance = null; - private LttngLog4j2Agent() { - super(Domain.LOG4J); + private LttngLog4j2Agent(Domain domain) { + super(domain); } - public static synchronized LttngLog4j2Agent getInstance() { - if (instance == null) { - instance = new LttngLog4j2Agent(); + public static synchronized LttngLog4j2Agent getLog4j1Instance() { + if (log4j1_instance == null) { + log4j1_instance = new LttngLog4j2Agent(Domain.LOG4J); } - return instance; + return log4j1_instance; + } + + public static synchronized LttngLog4j2Agent getLog4j2Instance() { + if (log4j2_instance == null) { + log4j2_instance = new LttngLog4j2Agent(Domain.LOG4J2); + } + return log4j2_instance; } @Override diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j2/org/lttng/ust/agent/log4j2/LttngLog4j2Api.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j2/org/lttng/ust/agent/log4j2/LttngLog4j2Api.java index 617d0d11..bc907546 100644 --- a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j2/org/lttng/ust/agent/log4j2/LttngLog4j2Api.java +++ b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j2/org/lttng/ust/agent/log4j2/LttngLog4j2Api.java @@ -17,5 +17,5 @@ final class LttngLog4j2Api { static native void tracepointWithContext(String message, String loggerName, String className, String methodName, String fileName, int lineNumber, long timeStamp, int logLevel, String threadName, byte[] contextEntries, - byte[] contextStrings); -} + byte[] contextStrings, boolean log4j1Compat); +} \ No newline at end of file diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j2/org/lttng/ust/agent/log4j2/LttngLogAppender.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j2/org/lttng/ust/agent/log4j2/LttngLogAppender.java index 3b7afa5b..cebd1894 100644 --- a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j2/org/lttng/ust/agent/log4j2/LttngLogAppender.java +++ b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j2/org/lttng/ust/agent/log4j2/LttngLogAppender.java @@ -92,7 +92,9 @@ public final class LttngLogAppender extends AbstractAppender implements ILttngHa /* Register to the relevant agent. */ if (domain == LttngLog4j2Agent.Domain.LOG4J) { - agent = LttngLog4j2Agent.getInstance(); + agent = LttngLog4j2Agent.getLog4j1Instance(); + } else if (domain == LttngLog4j2Agent.Domain.LOG4J2) { + agent = LttngLog4j2Agent.getLog4j2Instance(); } else { throw new IllegalArgumentException("Unsupported domain '" + domain + "'"); } @@ -239,6 +241,6 @@ public final class LttngLogAppender extends AbstractAppender implements ILttngHa LttngLog4j2Api.tracepointWithContext(message, loggername, classname, methodname, filename, line, event.getTimeMillis(), event.getLevel().intLevel(), event.getThreadName(), - contextInfo.getEntriesArray(), contextInfo.getStringsArray()); + contextInfo.getEntriesArray(), contextInfo.getStringsArray(), agent.getDomain() == Domain.LOG4J); } } diff --git a/src/lib/lttng-ust-java-agent/jni/log4j/Makefile.am b/src/lib/lttng-ust-java-agent/jni/log4j/Makefile.am index bc1db248..5e3fc938 100644 --- a/src/lib/lttng-ust-java-agent/jni/log4j/Makefile.am +++ b/src/lib/lttng-ust-java-agent/jni/log4j/Makefile.am @@ -4,6 +4,8 @@ AM_CPPFLAGS += -I$(builddir) -I$(srcdir) $(JNI_CPPFLAGS) lib_LTLIBRARIES = liblttng-ust-log4j-jni.la liblttng_ust_log4j_jni_la_SOURCES = \ + lttng_ust_log4j2_tp.c \ + lttng_ust_log4j2_tp.h \ lttng_ust_log4j_tp.c \ lttng_ust_log4j_tp.h nodist_liblttng_ust_log4j_jni_la_SOURCES = diff --git a/src/lib/lttng-ust-java-agent/jni/log4j/lttng_ust_log4j2.c b/src/lib/lttng-ust-java-agent/jni/log4j/lttng_ust_log4j2.c index f01139ad..d65dab7e 100644 --- a/src/lib/lttng-ust-java-agent/jni/log4j/lttng_ust_log4j2.c +++ b/src/lib/lttng-ust-java-agent/jni/log4j/lttng_ust_log4j2.c @@ -9,6 +9,7 @@ #define _LGPL_SOURCE #include "org_lttng_ust_agent_log4j2_LttngLog4j2Api.h" #include "lttng_ust_log4j_tp.h" +#include "lttng_ust_log4j2_tp.h" #include "../common/lttng_ust_context.h" /* @@ -109,7 +110,8 @@ JNIEXPORT void JNICALL Java_org_lttng_ust_agent_log4j2_LttngLog4j2Api_tracepoint jint logLevel, jstring threadName, jbyteArray context_info_entries, - jbyteArray context_info_strings) + jbyteArray context_info_strings, + jboolean log4j1Compat) { jboolean iscopy; const char *msg_cstr = (*env)->GetStringUTFChars(env, message, &iscopy); @@ -132,9 +134,21 @@ JNIEXPORT void JNICALL Java_org_lttng_ust_agent_log4j2_LttngLog4j2Api_tracepoint lttng_ust_context_info_tls.ctx_strings = context_info_strings_array; lttng_ust_context_info_tls.ctx_strings_len = (*env)->GetArrayLength(env, context_info_strings); - lttng_ust_tracepoint(lttng_log4j, event, msg_cstr, logger_name_cstr, - class_name_cstr, method_name_cstr, file_name_cstr, - lineNumber, timeStamp, loglevel_2x_to_1x(logLevel), thread_name_cstr); + if (log4j1Compat) { + /* + * Log4j 1.x compatible tracepoint with loglevel conversion. + */ + lttng_ust_tracepoint(lttng_log4j, event, msg_cstr, logger_name_cstr, + class_name_cstr, method_name_cstr, file_name_cstr, + lineNumber, timeStamp, loglevel_2x_to_1x(logLevel), thread_name_cstr); + } else { + /* + * Log4j 2.x tracepoint with native loglevel. + */ + lttng_ust_tracepoint(lttng_log4j2, event, msg_cstr, logger_name_cstr, + class_name_cstr, method_name_cstr, file_name_cstr, + lineNumber, timeStamp, logLevel, thread_name_cstr); + } lttng_ust_context_info_tls.ctx_entries = NULL; lttng_ust_context_info_tls.ctx_entries_len = 0; diff --git a/src/lib/lttng-ust-java-agent/jni/log4j/lttng_ust_log4j2_tp.c b/src/lib/lttng-ust-java-agent/jni/log4j/lttng_ust_log4j2_tp.c new file mode 100644 index 00000000..b905e81c --- /dev/null +++ b/src/lib/lttng-ust-java-agent/jni/log4j/lttng_ust_log4j2_tp.c @@ -0,0 +1,14 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (C) 2022 EfficiOS Inc. + */ + +#define _LGPL_SOURCE + +#define LTTNG_UST_TRACEPOINT_HIDDEN_DEFINITION +#define LTTNG_UST_TRACEPOINT_PROVIDER_HIDDEN_DEFINITION + +#define LTTNG_UST_TRACEPOINT_DEFINE +#define LTTNG_UST_TRACEPOINT_CREATE_PROBES +#include "lttng_ust_log4j2_tp.h" diff --git a/src/lib/lttng-ust-java-agent/jni/log4j/lttng_ust_log4j2_tp.h b/src/lib/lttng-ust-java-agent/jni/log4j/lttng_ust_log4j2_tp.h new file mode 100644 index 00000000..bbfe9b7f --- /dev/null +++ b/src/lib/lttng-ust-java-agent/jni/log4j/lttng_ust_log4j2_tp.h @@ -0,0 +1,48 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (C) 2022 EfficiOS Inc. + */ + +#undef LTTNG_UST_TRACEPOINT_PROVIDER +#define LTTNG_UST_TRACEPOINT_PROVIDER lttng_log4j2 + +#if !defined(_TRACEPOINT_LTTNG_UST_LOG4J2_H) || defined(LTTNG_UST_TRACEPOINT_HEADER_MULTI_READ) +#define _TRACEPOINT_LTTNG_UST_LOG4J2_H + +#include + +/* + * Tracepoint used by Java applications using the log4j 2.x convention for loglevels. + */ +LTTNG_UST_TRACEPOINT_EVENT(lttng_log4j2, event, + LTTNG_UST_TP_ARGS( + const char *, msg, + const char *, logger_name, + const char *, class_name, + const char *, method_name, + const char *, file_name, + int, line_number, + long, timestamp, + int, log_level, + const char *, thread_name), + LTTNG_UST_TP_FIELDS( + lttng_ust_field_string(msg, msg) + lttng_ust_field_string(logger_name, logger_name) + lttng_ust_field_string(class_name, class_name) + lttng_ust_field_string(method_name, method_name) + lttng_ust_field_string(filename, file_name) + lttng_ust_field_integer(int, line_number, line_number) + lttng_ust_field_integer(long, timestamp, timestamp) + lttng_ust_field_integer(int, int_loglevel, log_level) + lttng_ust_field_string(thread_name, thread_name) + ) +) + +#endif /* _TRACEPOINT_LTTNG_UST_LOG4J2_H */ + +#undef LTTNG_UST_TRACEPOINT_INCLUDE +#define LTTNG_UST_TRACEPOINT_INCLUDE "./lttng_ust_log4j2_tp.h" + +/* This part must be outside protection */ +#include diff --git a/src/lib/lttng-ust-java-agent/jni/log4j/lttng_ust_log4j_tp.h b/src/lib/lttng-ust-java-agent/jni/log4j/lttng_ust_log4j_tp.h index 8fa81187..ce4f919d 100644 --- a/src/lib/lttng-ust-java-agent/jni/log4j/lttng_ust_log4j_tp.h +++ b/src/lib/lttng-ust-java-agent/jni/log4j/lttng_ust_log4j_tp.h @@ -13,7 +13,7 @@ #include /* - * Tracepoint used by Java applications using the log4j log appender. + * Tracepoint used by Java applications using the log4j 1.x convention for loglevels. */ LTTNG_UST_TRACEPOINT_EVENT(lttng_log4j, event, LTTNG_UST_TP_ARGS( -- 2.34.1