From 93a436f8280a90299cca12ef319790c7d707ee67 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 15 Apr 2025 16:57:02 +0200 Subject: [PATCH 01/14] wip --- .../co/elastic/otel/agent/ElasticAgent.java | 3 ++ buildscripts/allowed-licenses.json | 5 +++ custom/build.gradle.kts | 3 ++ .../logging/ElasticLoggingCustomizer.java | 31 ++++++++++++++++ .../otel/logging/Slf4jInternalLogger.java | 37 +++++++++++++++++++ gradle/libs.versions.toml | 3 ++ 6 files changed, 82 insertions(+) create mode 100644 custom/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java create mode 100644 custom/src/main/java/co/elastic/otel/logging/Slf4jInternalLogger.java diff --git a/agent/entrypoint/src/main/java/co/elastic/otel/agent/ElasticAgent.java b/agent/entrypoint/src/main/java/co/elastic/otel/agent/ElasticAgent.java index f817cb7d3..5fa769114 100644 --- a/agent/entrypoint/src/main/java/co/elastic/otel/agent/ElasticAgent.java +++ b/agent/entrypoint/src/main/java/co/elastic/otel/agent/ElasticAgent.java @@ -31,6 +31,9 @@ public class ElasticAgent { * @param inst instrumentation */ public static void premain(String agentArgs, Instrumentation inst) { + + System.setProperty("otel.javaagent.logging", "elastic"); + OpenTelemetryAgent.premain(agentArgs, inst); } diff --git a/buildscripts/allowed-licenses.json b/buildscripts/allowed-licenses.json index c9308b6f8..5646c0638 100644 --- a/buildscripts/allowed-licenses.json +++ b/buildscripts/allowed-licenses.json @@ -8,6 +8,11 @@ "moduleLicense": "The 2-Clause BSD License", "moduleVersion": ".*", "moduleName": "org.hdrhistogram:HdrHistogram" + }, + { + "moduleLicense": "MIT License", + "moduleVersion": "1.7.36", + "moduleName": "org.slf4j:slf4j-api" } ] } diff --git a/custom/build.gradle.kts b/custom/build.gradle.kts index cf5d954c3..950dd506b 100644 --- a/custom/build.gradle.kts +++ b/custom/build.gradle.kts @@ -20,6 +20,9 @@ dependencies { compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi") compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api") compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-tooling") + compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-bootstrap") + compileOnly(libs.slf4j.api) + implementation(libs.log4j2) compileOnly(libs.bundles.semconv) implementation(libs.contribSpanStacktrace) { diff --git a/custom/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java b/custom/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java new file mode 100644 index 000000000..3b3195534 --- /dev/null +++ b/custom/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java @@ -0,0 +1,31 @@ +package co.elastic.otel.logging; + +import com.google.auto.service.AutoService; +import io.opentelemetry.javaagent.bootstrap.InternalLogger; +import io.opentelemetry.javaagent.tooling.LoggingCustomizer; +import io.opentelemetry.javaagent.tooling.config.EarlyInitAgentConfig; + +@AutoService(LoggingCustomizer.class) +public class ElasticLoggingCustomizer implements LoggingCustomizer { + + @Override + public String name() { + // must match "otel.javaagent.logging" system property for SPI lookup + return "elastic"; + } + + @Override + public void init(EarlyInitAgentConfig earlyInitAgentConfig) { + InternalLogger.initialize(Slf4jInternalLogger::create); + } + + @Override + public void onStartupSuccess() { + } + + @SuppressWarnings("CallToPrintStackTrace") + @Override + public void onStartupFailure(Throwable throwable) { + throwable.printStackTrace(); + } +} diff --git a/custom/src/main/java/co/elastic/otel/logging/Slf4jInternalLogger.java b/custom/src/main/java/co/elastic/otel/logging/Slf4jInternalLogger.java new file mode 100644 index 000000000..fccc6ca0c --- /dev/null +++ b/custom/src/main/java/co/elastic/otel/logging/Slf4jInternalLogger.java @@ -0,0 +1,37 @@ +package co.elastic.otel.logging; + +import io.opentelemetry.javaagent.bootstrap.InternalLogger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import javax.annotation.Nullable; + +/** + * Internal logger implementation that delegates to SLF4J + */ +public class Slf4jInternalLogger implements InternalLogger { + private final Logger logger; + + private Slf4jInternalLogger(String name) { + this.logger = LoggerFactory.getLogger(name); + } + + public static InternalLogger create(String name) { + return new Slf4jInternalLogger(name); + } + + @Override + public boolean isLoggable(Level level) { + // TODO + return true; + } + + @Override + public void log(Level level, String s, @Nullable Throwable throwable) { + // TODO + } + + @Override + public String name() { + return logger.getName(); + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index dfb589ccc..6fc42d4fb 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -76,6 +76,9 @@ ant = "org.apache.ant:ant:1.10.15" # ASM is currently only used during compile-time, so it is okay to diverge from the version used in ByteBuddy asm = "org.ow2.asm:asm:9.8" +slf4j-api = "org.slf4j:slf4j-api:2.0.17" +log4j2 = "org.apache.logging.log4j:log4j-slf4j-impl:2.24.3" + # Instrumented libraries openaiClient = "com.openai:openai-java:1.3.0" From b3eff30ca55b52236c090352e5ce2ca0c0e8ffd3 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 16 Apr 2025 16:30:13 +0200 Subject: [PATCH 02/14] first working version --- ...tel.agent-packaging-conventions.gradle.kts | 3 ++ buildscripts/allowed-licenses.json | 2 +- custom/build.gradle.kts | 2 +- .../co/elastic/otel/logging/AgentLog.java | 49 +++++++++++++++++++ .../logging/ElasticLoggingCustomizer.java | 16 +++++- .../otel/logging/Slf4jInternalLogger.java | 35 +++++++++++-- gradle/libs.versions.toml | 6 ++- 7 files changed, 106 insertions(+), 7 deletions(-) create mode 100644 custom/src/main/java/co/elastic/otel/logging/AgentLog.java diff --git a/buildSrc/src/main/kotlin/elastic-otel.agent-packaging-conventions.gradle.kts b/buildSrc/src/main/kotlin/elastic-otel.agent-packaging-conventions.gradle.kts index 0c3c0ecf8..31725ce8d 100644 --- a/buildSrc/src/main/kotlin/elastic-otel.agent-packaging-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/elastic-otel.agent-packaging-conventions.gradle.kts @@ -182,6 +182,9 @@ tasks { dependsOn(isolateJavaagentLibs) configurations = listOf(bootstrapLibs, upstreamAgent) + // exclude slf4j-simple from the shadow jar as we use log4j2-slf4j instead + exclude("inst/io/opentelemetry/javaagent/slf4j/simple/**") + from(isolateJavaagentLibs.get().outputs) archiveClassifier.set("") diff --git a/buildscripts/allowed-licenses.json b/buildscripts/allowed-licenses.json index 5646c0638..40847cc8f 100644 --- a/buildscripts/allowed-licenses.json +++ b/buildscripts/allowed-licenses.json @@ -11,7 +11,7 @@ }, { "moduleLicense": "MIT License", - "moduleVersion": "1.7.36", + "moduleVersion": ".*", "moduleName": "org.slf4j:slf4j-api" } ] diff --git a/custom/build.gradle.kts b/custom/build.gradle.kts index 950dd506b..afc157db3 100644 --- a/custom/build.gradle.kts +++ b/custom/build.gradle.kts @@ -22,7 +22,7 @@ dependencies { compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-tooling") compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-bootstrap") compileOnly(libs.slf4j.api) - implementation(libs.log4j2) + implementation(libs.bundles.log4j2) compileOnly(libs.bundles.semconv) implementation(libs.contribSpanStacktrace) { diff --git a/custom/src/main/java/co/elastic/otel/logging/AgentLog.java b/custom/src/main/java/co/elastic/otel/logging/AgentLog.java new file mode 100644 index 000000000..7a5aa45c7 --- /dev/null +++ b/custom/src/main/java/co/elastic/otel/logging/AgentLog.java @@ -0,0 +1,49 @@ +package co.elastic.otel.logging; + +import io.opentelemetry.javaagent.bootstrap.InternalLogger; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.core.config.Configurator; + +public class AgentLog { + + private AgentLog() { + + } + + /** + * Sets the agent log level at runtime + * + * @param level log level + */ + public static void setLevel(InternalLogger.Level level) { + // Using log4j2 implementation allows to change the log level programmatically at runtime + // which is not directly possible through the slf4j API and simple implementation used in + // upstream distribution + + Level rootLevel = toLog4jLevel(level); + Configurator.setRootLevel(rootLevel); + + // when debugging we should avoid very chatty http client debug messages + if (rootLevel.intLevel() >= Level.DEBUG.intLevel()) { + Configurator.setLevel("okhttp3.internal.http2", Level.INFO); + Configurator.setLevel("okhttp3.internal.concurrent.TaskRunner", Level.INFO); + } + } + + private static Level toLog4jLevel(InternalLogger.Level level) { + switch (level) { + case TRACE: + return Level.TRACE; + case DEBUG: + return Level.DEBUG; + case INFO: + return Level.INFO; + case WARN: + return Level.WARN; + case ERROR: + return Level.ERROR; + default: + throw new IllegalArgumentException("Unsupported level: " + level); + } + } +} diff --git a/custom/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java b/custom/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java index 3b3195534..40ca5043e 100644 --- a/custom/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java +++ b/custom/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java @@ -4,6 +4,7 @@ import io.opentelemetry.javaagent.bootstrap.InternalLogger; import io.opentelemetry.javaagent.tooling.LoggingCustomizer; import io.opentelemetry.javaagent.tooling.config.EarlyInitAgentConfig; +import org.slf4j.LoggerFactory; @AutoService(LoggingCustomizer.class) public class ElasticLoggingCustomizer implements LoggingCustomizer { @@ -15,8 +16,21 @@ public String name() { } @Override - public void init(EarlyInitAgentConfig earlyInitAgentConfig) { + public void init(EarlyInitAgentConfig earlyConfig) { + + // trigger loading the slf4j provider from the agent CL, this should load log4j implementation + LoggerFactory.getILoggerFactory(); + + // make the agent internal logger delegate to slf4j, which will delegate to log4j InternalLogger.initialize(Slf4jInternalLogger::create); + + // set debug logging when enabled through configuration to behave like the upstream distribution + if (earlyConfig.getBoolean("otel.javaagent.debug", false)) { + AgentLog.setLevel(InternalLogger.Level.DEBUG); + } else { + AgentLog.setLevel(InternalLogger.Level.INFO); + } + } @Override diff --git a/custom/src/main/java/co/elastic/otel/logging/Slf4jInternalLogger.java b/custom/src/main/java/co/elastic/otel/logging/Slf4jInternalLogger.java index fccc6ca0c..43ac07c40 100644 --- a/custom/src/main/java/co/elastic/otel/logging/Slf4jInternalLogger.java +++ b/custom/src/main/java/co/elastic/otel/logging/Slf4jInternalLogger.java @@ -21,13 +21,42 @@ public static InternalLogger create(String name) { @Override public boolean isLoggable(Level level) { - // TODO - return true; + switch (level) { + case TRACE: + return logger.isTraceEnabled(); + case DEBUG: + return logger.isDebugEnabled(); + case INFO: + return logger.isInfoEnabled(); + case WARN: + return logger.isWarnEnabled(); + case ERROR: + return logger.isErrorEnabled(); + default: + throw new IllegalArgumentException("Unsupported level: " + level); + } } @Override public void log(Level level, String s, @Nullable Throwable throwable) { - // TODO + logger.atLevel(toSlf4jLevel(level)).setCause(throwable).log(s); + } + + private static org.slf4j.event.Level toSlf4jLevel(Level level) { + switch (level) { + case TRACE: + return org.slf4j.event.Level.TRACE; + case DEBUG: + return org.slf4j.event.Level.DEBUG; + case INFO: + return org.slf4j.event.Level.INFO; + case WARN: + return org.slf4j.event.Level.WARN; + case ERROR: + return org.slf4j.event.Level.ERROR; + default: + throw new IllegalArgumentException("Unsupported level: " + level); + } } @Override diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6fc42d4fb..0f96c977a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,6 +4,7 @@ jib = "3.4.5" spotless = "7.0.3" junit = "5.12.2" autoservice = "1.1.1" +log4j2 = "2.24.3" # otel protocol (OTLP) opentelemetryProto = "1.3.2-alpha" @@ -77,7 +78,8 @@ ant = "org.apache.ant:ant:1.10.15" asm = "org.ow2.asm:asm:9.8" slf4j-api = "org.slf4j:slf4j-api:2.0.17" -log4j2 = "org.apache.logging.log4j:log4j-slf4j-impl:2.24.3" +log4j2-slf4j = { group= "org.apache.logging.log4j", name="log4j-slf4j2-impl", version.ref="log4j2"} +log4j2-core = { group= "org.apache.logging.log4j", name="log4j-core", version.ref="log4j2"} # Instrumented libraries openaiClient = "com.openai:openai-java:1.3.0" @@ -85,6 +87,8 @@ openaiClient = "com.openai:openai-java:1.3.0" [bundles] semconv = ["opentelemetrySemconv", "opentelemetrySemconvIncubating"] +log4j2 = ["log4j2-core", "log4j2-slf4j"] + [plugins] From c44ee17768bb79fed6bba1b0407043a436dd1fe4 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 16 Apr 2025 16:44:04 +0200 Subject: [PATCH 03/14] use log4j level directly --- .../co/elastic/otel/logging/AgentLog.java | 24 +++---------------- .../logging/ElasticLoggingCustomizer.java | 5 ++-- 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/custom/src/main/java/co/elastic/otel/logging/AgentLog.java b/custom/src/main/java/co/elastic/otel/logging/AgentLog.java index 7a5aa45c7..30a080edf 100644 --- a/custom/src/main/java/co/elastic/otel/logging/AgentLog.java +++ b/custom/src/main/java/co/elastic/otel/logging/AgentLog.java @@ -1,6 +1,5 @@ package co.elastic.otel.logging; -import io.opentelemetry.javaagent.bootstrap.InternalLogger; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.config.Configurator; @@ -15,35 +14,18 @@ private AgentLog() { * * @param level log level */ - public static void setLevel(InternalLogger.Level level) { + public static void setLevel(Level level) { // Using log4j2 implementation allows to change the log level programmatically at runtime // which is not directly possible through the slf4j API and simple implementation used in // upstream distribution - Level rootLevel = toLog4jLevel(level); - Configurator.setRootLevel(rootLevel); + Configurator.setAllLevels("", level); // when debugging we should avoid very chatty http client debug messages - if (rootLevel.intLevel() >= Level.DEBUG.intLevel()) { + if (level.intLevel() >= Level.DEBUG.intLevel()) { Configurator.setLevel("okhttp3.internal.http2", Level.INFO); Configurator.setLevel("okhttp3.internal.concurrent.TaskRunner", Level.INFO); } } - private static Level toLog4jLevel(InternalLogger.Level level) { - switch (level) { - case TRACE: - return Level.TRACE; - case DEBUG: - return Level.DEBUG; - case INFO: - return Level.INFO; - case WARN: - return Level.WARN; - case ERROR: - return Level.ERROR; - default: - throw new IllegalArgumentException("Unsupported level: " + level); - } - } } diff --git a/custom/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java b/custom/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java index 40ca5043e..14715eb41 100644 --- a/custom/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java +++ b/custom/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java @@ -4,6 +4,7 @@ import io.opentelemetry.javaagent.bootstrap.InternalLogger; import io.opentelemetry.javaagent.tooling.LoggingCustomizer; import io.opentelemetry.javaagent.tooling.config.EarlyInitAgentConfig; +import org.apache.logging.log4j.Level; import org.slf4j.LoggerFactory; @AutoService(LoggingCustomizer.class) @@ -26,9 +27,9 @@ public void init(EarlyInitAgentConfig earlyConfig) { // set debug logging when enabled through configuration to behave like the upstream distribution if (earlyConfig.getBoolean("otel.javaagent.debug", false)) { - AgentLog.setLevel(InternalLogger.Level.DEBUG); + AgentLog.setLevel(Level.DEBUG); } else { - AgentLog.setLevel(InternalLogger.Level.INFO); + AgentLog.setLevel(Level.INFO); } } From 230cad1ef839ecd83d977d292a41d0a110830bb6 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Thu, 17 Apr 2025 09:38:11 +0200 Subject: [PATCH 04/14] reformat --- .../co/elastic/otel/logging/AgentLog.java | 40 ++++++++++++++++++- .../logging/ElasticLoggingCustomizer.java | 27 ++++++++++--- .../otel/logging/Slf4jInternalLogger.java | 24 +++++++++-- 3 files changed, 80 insertions(+), 11 deletions(-) diff --git a/custom/src/main/java/co/elastic/otel/logging/AgentLog.java b/custom/src/main/java/co/elastic/otel/logging/AgentLog.java index 30a080edf..5a9eae694 100644 --- a/custom/src/main/java/co/elastic/otel/logging/AgentLog.java +++ b/custom/src/main/java/co/elastic/otel/logging/AgentLog.java @@ -1,12 +1,49 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package co.elastic.otel.logging; import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.core.appender.ConsoleAppender; import org.apache.logging.log4j.core.config.Configurator; +import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder; +import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory; +import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration; +import org.apache.logging.log4j.core.layout.PatternLayout; public class AgentLog { - private AgentLog() { + private static final String PATTERN = "%msg%n"; + private AgentLog() {} + + public static void init() { + + ConfigurationBuilder conf = + ConfigurationBuilderFactory.newConfigurationBuilder(); + conf.add( + conf.newAppender("stdout", ConsoleAppender.PLUGIN_NAME) + .add(conf.newLayout(PatternLayout.class.getName())) + .addAttribute("pattern", PATTERN)); + + // conf.add(conf.newRootLogger().add(conf.newAppenderRef("stdout"))); + + Configurator.initialize(conf.build()); } /** @@ -27,5 +64,4 @@ public static void setLevel(Level level) { Configurator.setLevel("okhttp3.internal.concurrent.TaskRunner", Level.INFO); } } - } diff --git a/custom/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java b/custom/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java index 14715eb41..28279d825 100644 --- a/custom/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java +++ b/custom/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java @@ -1,3 +1,21 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package co.elastic.otel.logging; import com.google.auto.service.AutoService; @@ -22,21 +40,20 @@ public void init(EarlyInitAgentConfig earlyConfig) { // trigger loading the slf4j provider from the agent CL, this should load log4j implementation LoggerFactory.getILoggerFactory(); + AgentLog.init(); + // make the agent internal logger delegate to slf4j, which will delegate to log4j InternalLogger.initialize(Slf4jInternalLogger::create); + AgentLog.setLevel(Level.INFO); // set debug logging when enabled through configuration to behave like the upstream distribution if (earlyConfig.getBoolean("otel.javaagent.debug", false)) { AgentLog.setLevel(Level.DEBUG); - } else { - AgentLog.setLevel(Level.INFO); } - } @Override - public void onStartupSuccess() { - } + public void onStartupSuccess() {} @SuppressWarnings("CallToPrintStackTrace") @Override diff --git a/custom/src/main/java/co/elastic/otel/logging/Slf4jInternalLogger.java b/custom/src/main/java/co/elastic/otel/logging/Slf4jInternalLogger.java index 43ac07c40..322e78507 100644 --- a/custom/src/main/java/co/elastic/otel/logging/Slf4jInternalLogger.java +++ b/custom/src/main/java/co/elastic/otel/logging/Slf4jInternalLogger.java @@ -1,13 +1,29 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package co.elastic.otel.logging; import io.opentelemetry.javaagent.bootstrap.InternalLogger; +import javax.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.Nullable; -/** - * Internal logger implementation that delegates to SLF4J - */ +/** Internal logger implementation that delegates to SLF4J */ public class Slf4jInternalLogger implements InternalLogger { private final Logger logger; From 7e8163cd73a1bcd02fed1b03af02eb6048945a99 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Thu, 17 Apr 2025 10:19:10 +0200 Subject: [PATCH 05/14] move to another module and cleanup --- .../co/elastic/otel/agent/ElasticAgent.java | 1 + custom/build.gradle.kts | 3 +-- internal-logging/build.gradle.kts | 18 ++++++++++++++++++ .../java/co/elastic/otel/logging/AgentLog.java | 11 +++++------ .../otel/logging/ElasticLoggingCustomizer.java | 4 ++-- .../otel/logging/Slf4jInternalLogger.java | 0 settings.gradle.kts | 1 + 7 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 internal-logging/build.gradle.kts rename {custom => internal-logging}/src/main/java/co/elastic/otel/logging/AgentLog.java (87%) rename {custom => internal-logging}/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java (100%) rename {custom => internal-logging}/src/main/java/co/elastic/otel/logging/Slf4jInternalLogger.java (100%) diff --git a/agent/entrypoint/src/main/java/co/elastic/otel/agent/ElasticAgent.java b/agent/entrypoint/src/main/java/co/elastic/otel/agent/ElasticAgent.java index 5fa769114..7e6dad6a8 100644 --- a/agent/entrypoint/src/main/java/co/elastic/otel/agent/ElasticAgent.java +++ b/agent/entrypoint/src/main/java/co/elastic/otel/agent/ElasticAgent.java @@ -32,6 +32,7 @@ public class ElasticAgent { */ public static void premain(String agentArgs, Instrumentation inst) { + // must match value returned by ElasticLoggingCustomizer#getName System.setProperty("otel.javaagent.logging", "elastic"); OpenTelemetryAgent.premain(agentArgs, inst); diff --git a/custom/build.gradle.kts b/custom/build.gradle.kts index afc157db3..fbde0d5ca 100644 --- a/custom/build.gradle.kts +++ b/custom/build.gradle.kts @@ -11,6 +11,7 @@ dependencies { implementation(project(":inferred-spans")) implementation(project(":universal-profiling-integration")) implementation(project(":resources")) + implementation(project(":internal-logging")) instrumentations.forEach { implementation(project(it)) } @@ -21,8 +22,6 @@ dependencies { compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api") compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-tooling") compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-bootstrap") - compileOnly(libs.slf4j.api) - implementation(libs.bundles.log4j2) compileOnly(libs.bundles.semconv) implementation(libs.contribSpanStacktrace) { diff --git a/internal-logging/build.gradle.kts b/internal-logging/build.gradle.kts new file mode 100644 index 000000000..b9ac365f1 --- /dev/null +++ b/internal-logging/build.gradle.kts @@ -0,0 +1,18 @@ +plugins { + id("elastic-otel.library-packaging-conventions") +} + +dependencies { + + compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-tooling") + compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-bootstrap") + compileOnly(libs.slf4j.api) + implementation(libs.bundles.log4j2) + + // needs to be added in order to allow access to AgentListener interface + // this is currently required because autoconfigure is currently not exposed to the extension API. + compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure") +} + +tasks { +} diff --git a/custom/src/main/java/co/elastic/otel/logging/AgentLog.java b/internal-logging/src/main/java/co/elastic/otel/logging/AgentLog.java similarity index 87% rename from custom/src/main/java/co/elastic/otel/logging/AgentLog.java rename to internal-logging/src/main/java/co/elastic/otel/logging/AgentLog.java index 5a9eae694..9394ead31 100644 --- a/custom/src/main/java/co/elastic/otel/logging/AgentLog.java +++ b/internal-logging/src/main/java/co/elastic/otel/logging/AgentLog.java @@ -19,12 +19,10 @@ package co.elastic.otel.logging; import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.core.appender.ConsoleAppender; import org.apache.logging.log4j.core.config.Configurator; import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder; import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory; import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration; -import org.apache.logging.log4j.core.layout.PatternLayout; public class AgentLog { @@ -36,10 +34,11 @@ public static void init() { ConfigurationBuilder conf = ConfigurationBuilderFactory.newConfigurationBuilder(); - conf.add( - conf.newAppender("stdout", ConsoleAppender.PLUGIN_NAME) - .add(conf.newLayout(PatternLayout.class.getName())) - .addAttribute("pattern", PATTERN)); + + // conf.add( + // conf.newAppender("stdout", ConsoleAppender.PLUGIN_NAME) + // .add(conf.newLayout(PatternLayout.class.getName())) + // .addAttribute("pattern", PATTERN)); // conf.add(conf.newRootLogger().add(conf.newAppenderRef("stdout"))); diff --git a/custom/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java b/internal-logging/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java similarity index 100% rename from custom/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java rename to internal-logging/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java index 28279d825..e6cbd9186 100644 --- a/custom/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java +++ b/internal-logging/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java @@ -40,11 +40,11 @@ public void init(EarlyInitAgentConfig earlyConfig) { // trigger loading the slf4j provider from the agent CL, this should load log4j implementation LoggerFactory.getILoggerFactory(); - AgentLog.init(); - // make the agent internal logger delegate to slf4j, which will delegate to log4j InternalLogger.initialize(Slf4jInternalLogger::create); + AgentLog.init(); + AgentLog.setLevel(Level.INFO); // set debug logging when enabled through configuration to behave like the upstream distribution if (earlyConfig.getBoolean("otel.javaagent.debug", false)) { diff --git a/custom/src/main/java/co/elastic/otel/logging/Slf4jInternalLogger.java b/internal-logging/src/main/java/co/elastic/otel/logging/Slf4jInternalLogger.java similarity index 100% rename from custom/src/main/java/co/elastic/otel/logging/Slf4jInternalLogger.java rename to internal-logging/src/main/java/co/elastic/otel/logging/Slf4jInternalLogger.java diff --git a/settings.gradle.kts b/settings.gradle.kts index 05c3ef69b..68c1a8577 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -19,6 +19,7 @@ include("custom") include("instrumentation") include("instrumentation:openai-client-instrumentation:instrumentation-1.1") include("inferred-spans") +include("internal-logging") include("resources") include("runtime-attach") include("smoke-tests") From 6c7fcf2da8a6e25a7a5c828c5254ad73151fe6e5 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Thu, 17 Apr 2025 11:10:11 +0200 Subject: [PATCH 06/14] relocate internal logging impl. --- ...tel.agent-packaging-conventions.gradle.kts | 2 +- custom/build.gradle.kts | 2 +- internal-logging/build.gradle.kts | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/buildSrc/src/main/kotlin/elastic-otel.agent-packaging-conventions.gradle.kts b/buildSrc/src/main/kotlin/elastic-otel.agent-packaging-conventions.gradle.kts index 31725ce8d..704bc1b30 100644 --- a/buildSrc/src/main/kotlin/elastic-otel.agent-packaging-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/elastic-otel.agent-packaging-conventions.gradle.kts @@ -182,7 +182,7 @@ tasks { dependsOn(isolateJavaagentLibs) configurations = listOf(bootstrapLibs, upstreamAgent) - // exclude slf4j-simple from the shadow jar as we use log4j2-slf4j instead + // exclude slf4j-simple from the shadow jar as we use log4j2-slf4j with internal-logging instead exclude("inst/io/opentelemetry/javaagent/slf4j/simple/**") from(isolateJavaagentLibs.get().outputs) diff --git a/custom/build.gradle.kts b/custom/build.gradle.kts index fbde0d5ca..6f9f6ac45 100644 --- a/custom/build.gradle.kts +++ b/custom/build.gradle.kts @@ -11,7 +11,7 @@ dependencies { implementation(project(":inferred-spans")) implementation(project(":universal-profiling-integration")) implementation(project(":resources")) - implementation(project(":internal-logging")) + implementation(project(":internal-logging", configuration = "shadow")) instrumentations.forEach { implementation(project(it)) } diff --git a/internal-logging/build.gradle.kts b/internal-logging/build.gradle.kts index b9ac365f1..3de61c03f 100644 --- a/internal-logging/build.gradle.kts +++ b/internal-logging/build.gradle.kts @@ -1,5 +1,9 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCacheFileTransformer + plugins { id("elastic-otel.library-packaging-conventions") + id("com.gradleup.shadow") } dependencies { @@ -15,4 +19,19 @@ dependencies { } tasks { + val shadowJar by existing(ShadowJar::class) { + // required for META-INF/services files relocation + mergeServiceFiles() + + transform(Log4j2PluginsCacheFileTransformer::class.java) + + // relocate slf4j and log4j for internal logging to prevent any conflict + relocate("org.slf4j", "co.elastic.otel.logging.slf4j") + relocate("org.apache.logging.log4j", "co.elastic.otel.logging.log4j") + relocate("org.apache.logging.slf4j", "co.elastic.otel.logging.log4j.slf4j") + } + + assemble { + dependsOn(shadowJar) + } } From a01182c39ca6794d3138eb0d472f74a0ad579d79 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Thu, 17 Apr 2025 11:10:24 +0200 Subject: [PATCH 07/14] provide elastic config option for log level --- .../otel/logging/ElasticLoggingCustomizer.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/internal-logging/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java b/internal-logging/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java index e6cbd9186..0ab6f4f58 100644 --- a/internal-logging/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java +++ b/internal-logging/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java @@ -45,11 +45,21 @@ public void init(EarlyInitAgentConfig earlyConfig) { AgentLog.init(); - AgentLog.setLevel(Level.INFO); - // set debug logging when enabled through configuration to behave like the upstream distribution - if (earlyConfig.getBoolean("otel.javaagent.debug", false)) { - AgentLog.setLevel(Level.DEBUG); + String levelConfig = earlyConfig.getString("elastic.otel.javaagent.log.level"); + if (levelConfig == null) { + // explicit level not set + AgentLog.setLevel(Level.INFO); + // set debug logging when enabled through configuration to behave like the upstream distribution + if (earlyConfig.getBoolean("otel.javaagent.debug", false)) { + AgentLog.setLevel(Level.DEBUG); + } + } else { + // explicit level provided + Level level = Level.getLevel(levelConfig); + AgentLog.setLevel(level == null ? Level.INFO : level); } + + } @Override From 4cf00481beab51c6bee9989c90fe6b26dec333e7 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Thu, 17 Apr 2025 11:14:57 +0200 Subject: [PATCH 08/14] simplify custom log level usage --- .../logging/ElasticLoggingCustomizer.java | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/internal-logging/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java b/internal-logging/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java index 0ab6f4f58..93ae61e15 100644 --- a/internal-logging/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java +++ b/internal-logging/src/main/java/co/elastic/otel/logging/ElasticLoggingCustomizer.java @@ -45,21 +45,18 @@ public void init(EarlyInitAgentConfig earlyConfig) { AgentLog.init(); - String levelConfig = earlyConfig.getString("elastic.otel.javaagent.log.level"); - if (levelConfig == null) { - // explicit level not set - AgentLog.setLevel(Level.INFO); - // set debug logging when enabled through configuration to behave like the upstream distribution - if (earlyConfig.getBoolean("otel.javaagent.debug", false)) { - AgentLog.setLevel(Level.DEBUG); - } + Level level = null; + if (earlyConfig.getBoolean("otel.javaagent.debug", false)) { + // set debug logging when enabled through configuration to behave like the upstream + // distribution + level = Level.DEBUG; } else { - // explicit level provided - Level level = Level.getLevel(levelConfig); - AgentLog.setLevel(level == null ? Level.INFO : level); + String levelConfig = earlyConfig.getString("elastic.otel.javaagent.log.level"); + if (levelConfig != null) { + level = Level.getLevel(levelConfig); + } } - - + AgentLog.setLevel(level != null ? level : Level.INFO); } @Override From a2e07dc4ef1b115f8c2150da93f3f27f4615b7e4 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Thu, 17 Apr 2025 11:54:05 +0200 Subject: [PATCH 09/14] set custom log format --- .../main/java/co/elastic/otel/logging/AgentLog.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/internal-logging/src/main/java/co/elastic/otel/logging/AgentLog.java b/internal-logging/src/main/java/co/elastic/otel/logging/AgentLog.java index 9394ead31..bb8a8ff02 100644 --- a/internal-logging/src/main/java/co/elastic/otel/logging/AgentLog.java +++ b/internal-logging/src/main/java/co/elastic/otel/logging/AgentLog.java @@ -26,7 +26,7 @@ public class AgentLog { - private static final String PATTERN = "%msg%n"; + private static final String PATTERN = "%d{DEFAULT} [%t] %-5level %logger{36} - %msg{nolookups}%n"; private AgentLog() {} @@ -35,14 +35,13 @@ public static void init() { ConfigurationBuilder conf = ConfigurationBuilderFactory.newConfigurationBuilder(); - // conf.add( - // conf.newAppender("stdout", ConsoleAppender.PLUGIN_NAME) - // .add(conf.newLayout(PatternLayout.class.getName())) - // .addAttribute("pattern", PATTERN)); + conf.add( + conf.newAppender("stdout", "Console") + .add(conf.newLayout("PatternLayout").addAttribute("pattern", PATTERN))); - // conf.add(conf.newRootLogger().add(conf.newAppenderRef("stdout"))); + conf.add(conf.newRootLogger().add(conf.newAppenderRef("stdout"))); - Configurator.initialize(conf.build()); + Configurator.initialize(conf.build(false)); } /** From 9c01a438517bc188013e3f6770ab2ab14d266445 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Thu, 17 Apr 2025 14:16:31 +0200 Subject: [PATCH 10/14] cleanup --- custom/build.gradle.kts | 1 - .../src/main/java/co/elastic/otel/logging/AgentLog.java | 8 ++++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/custom/build.gradle.kts b/custom/build.gradle.kts index 34f0835aa..d4f59d0e0 100644 --- a/custom/build.gradle.kts +++ b/custom/build.gradle.kts @@ -21,7 +21,6 @@ dependencies { compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi") compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api") compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-tooling") - compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-bootstrap") compileOnly(libs.bundles.semconv) implementation(libs.contribSpanStacktrace) { diff --git a/internal-logging/src/main/java/co/elastic/otel/logging/AgentLog.java b/internal-logging/src/main/java/co/elastic/otel/logging/AgentLog.java index bb8a8ff02..3db95705f 100644 --- a/internal-logging/src/main/java/co/elastic/otel/logging/AgentLog.java +++ b/internal-logging/src/main/java/co/elastic/otel/logging/AgentLog.java @@ -28,6 +28,9 @@ public class AgentLog { private static final String PATTERN = "%d{DEFAULT} [%t] %-5level %logger{36} - %msg{nolookups}%n"; + // logger is an empty string + private static final String ROOT_LOGGER_NAME = ""; + private AgentLog() {} public static void init() { @@ -52,11 +55,12 @@ public static void init() { public static void setLevel(Level level) { // Using log4j2 implementation allows to change the log level programmatically at runtime // which is not directly possible through the slf4j API and simple implementation used in - // upstream distribution + // upstream distribution. - Configurator.setAllLevels("", level); + Configurator.setAllLevels(ROOT_LOGGER_NAME, level); // when debugging we should avoid very chatty http client debug messages + // this behavior is replicated from the upstream distribution. if (level.intLevel() >= Level.DEBUG.intLevel()) { Configurator.setLevel("okhttp3.internal.http2", Level.INFO); Configurator.setLevel("okhttp3.internal.concurrent.TaskRunner", Level.INFO); From 32cf14cc0470ce45587e38b70bb39a7afaf57285 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Thu, 17 Apr 2025 15:18:17 +0200 Subject: [PATCH 11/14] attempt to preserve upstream log options --- .../co/elastic/otel/agent/ElasticAgent.java | 22 +++++++++++++++---- internal-logging/build.gradle.kts | 3 --- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/agent/entrypoint/src/main/java/co/elastic/otel/agent/ElasticAgent.java b/agent/entrypoint/src/main/java/co/elastic/otel/agent/ElasticAgent.java index 7e6dad6a8..aee24202f 100644 --- a/agent/entrypoint/src/main/java/co/elastic/otel/agent/ElasticAgent.java +++ b/agent/entrypoint/src/main/java/co/elastic/otel/agent/ElasticAgent.java @@ -20,10 +20,14 @@ import io.opentelemetry.javaagent.OpenTelemetryAgent; import java.lang.instrument.Instrumentation; +import java.util.Locale; /** Elastic agent entry point, delegates to OpenTelemetry agent */ public class ElasticAgent { + private static final String OTEL_JAVAAGENT_LOGGING = "otel.javaagent.logging"; + private static final String OTEL_JAVAAGENT_LOGGING_ENV = "OTEL_JAVAAGENT_LOGGING"; + /** * Entry point for -javaagent JVM argument attach * @@ -31,10 +35,7 @@ public class ElasticAgent { * @param inst instrumentation */ public static void premain(String agentArgs, Instrumentation inst) { - - // must match value returned by ElasticLoggingCustomizer#getName - System.setProperty("otel.javaagent.logging", "elastic"); - + initLogging(); OpenTelemetryAgent.premain(agentArgs, inst); } @@ -45,6 +46,7 @@ public static void premain(String agentArgs, Instrumentation inst) { * @param inst instrumentation */ public static void agentmain(String agentArgs, Instrumentation inst) { + initLogging(); OpenTelemetryAgent.agentmain(agentArgs, inst); } @@ -57,5 +59,17 @@ public static void main(String[] args) { OpenTelemetryAgent.main(args); } + private static void initLogging() { + + // do not override explicitly provided configuration + if (System.getProperty(OTEL_JAVAAGENT_LOGGING) != null + || System.getenv(OTEL_JAVAAGENT_LOGGING_ENV) != null) { + return; + } + + // must match value returned by ElasticLoggingCustomizer#getName + System.setProperty(OTEL_JAVAAGENT_LOGGING, "elastic"); + } + private ElasticAgent() {} } diff --git a/internal-logging/build.gradle.kts b/internal-logging/build.gradle.kts index 3de61c03f..a88867c41 100644 --- a/internal-logging/build.gradle.kts +++ b/internal-logging/build.gradle.kts @@ -13,9 +13,6 @@ dependencies { compileOnly(libs.slf4j.api) implementation(libs.bundles.log4j2) - // needs to be added in order to allow access to AgentListener interface - // this is currently required because autoconfigure is currently not exposed to the extension API. - compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure") } tasks { From b866dd1e99c3907d7c9f494063e90e1e7712a95b Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Thu, 17 Apr 2025 15:19:06 +0200 Subject: [PATCH 12/14] cleanup --- .../src/main/java/co/elastic/otel/agent/ElasticAgent.java | 1 - 1 file changed, 1 deletion(-) diff --git a/agent/entrypoint/src/main/java/co/elastic/otel/agent/ElasticAgent.java b/agent/entrypoint/src/main/java/co/elastic/otel/agent/ElasticAgent.java index aee24202f..7d50c5673 100644 --- a/agent/entrypoint/src/main/java/co/elastic/otel/agent/ElasticAgent.java +++ b/agent/entrypoint/src/main/java/co/elastic/otel/agent/ElasticAgent.java @@ -20,7 +20,6 @@ import io.opentelemetry.javaagent.OpenTelemetryAgent; import java.lang.instrument.Instrumentation; -import java.util.Locale; /** Elastic agent entry point, delegates to OpenTelemetry agent */ public class ElasticAgent { From d6d14e402b2ed62f42be4878a6ada9b17f01f577 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 22 Apr 2025 15:03:38 +0200 Subject: [PATCH 13/14] disable system properties and env variables for log4j --- internal-logging/build.gradle.kts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal-logging/build.gradle.kts b/internal-logging/build.gradle.kts index a88867c41..969717157 100644 --- a/internal-logging/build.gradle.kts +++ b/internal-logging/build.gradle.kts @@ -20,6 +20,10 @@ tasks { // required for META-INF/services files relocation mergeServiceFiles() + // Excluding property source SPI prevents log4j system properties and env variables that might + // be set at the application level to change the behavior of this internal log4j instance. + exclude("**/*.log4j.util.PropertySource") + transform(Log4j2PluginsCacheFileTransformer::class.java) // relocate slf4j and log4j for internal logging to prevent any conflict From 0b05c841bb2eb1710310bf23545af3431b491644 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 22 Apr 2025 15:20:31 +0200 Subject: [PATCH 14/14] prevent explicit 'simple' config issue --- .../java/co/elastic/otel/agent/ElasticAgent.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/agent/entrypoint/src/main/java/co/elastic/otel/agent/ElasticAgent.java b/agent/entrypoint/src/main/java/co/elastic/otel/agent/ElasticAgent.java index 7d50c5673..793e19adc 100644 --- a/agent/entrypoint/src/main/java/co/elastic/otel/agent/ElasticAgent.java +++ b/agent/entrypoint/src/main/java/co/elastic/otel/agent/ElasticAgent.java @@ -26,6 +26,7 @@ public class ElasticAgent { private static final String OTEL_JAVAAGENT_LOGGING = "otel.javaagent.logging"; private static final String OTEL_JAVAAGENT_LOGGING_ENV = "OTEL_JAVAAGENT_LOGGING"; + private static final String OTEL_JAVAAGENT_LOGGING_DEFAULT = "simple"; /** * Entry point for -javaagent JVM argument attach @@ -60,9 +61,10 @@ public static void main(String[] args) { private static void initLogging() { - // do not override explicitly provided configuration - if (System.getProperty(OTEL_JAVAAGENT_LOGGING) != null - || System.getenv(OTEL_JAVAAGENT_LOGGING_ENV) != null) { + // Do not override explicitly provided configuration unless it's using the default as the + // 'simple' provider is not included in this distribution and that triggers an SLF4j error. + if (isLoggingNotDefault(System.getProperty(OTEL_JAVAAGENT_LOGGING)) + || isLoggingNotDefault(System.getenv(OTEL_JAVAAGENT_LOGGING_ENV))) { return; } @@ -70,5 +72,9 @@ private static void initLogging() { System.setProperty(OTEL_JAVAAGENT_LOGGING, "elastic"); } + private static boolean isLoggingNotDefault(String value) { + return value != null && !OTEL_JAVAAGENT_LOGGING_DEFAULT.equals(value); + } + private ElasticAgent() {} }