diff --git a/instrumentation/internal/internal-slf4j-bridge/bootstrap/build.gradle.kts b/instrumentation/internal/internal-slf4j-bridge/bootstrap/build.gradle.kts new file mode 100644 index 000000000000..2cb65998cad9 --- /dev/null +++ b/instrumentation/internal/internal-slf4j-bridge/bootstrap/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + id("otel.javaagent-bootstrap") +} + +dependencies { + compileOnly(project(":javaagent-bootstrap")) +} diff --git a/instrumentation/internal/internal-slf4j-bridge/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/logging/Slf4jBridgeInstaller.java b/instrumentation/internal/internal-slf4j-bridge/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/logging/Slf4jBridgeInstaller.java new file mode 100644 index 000000000000..4ba9712ad712 --- /dev/null +++ b/instrumentation/internal/internal-slf4j-bridge/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/logging/Slf4jBridgeInstaller.java @@ -0,0 +1,17 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.bootstrap.logging; + +import io.opentelemetry.javaagent.Slf4jLogRecorder; +import io.opentelemetry.javaagent.bootstrap.Slf4jBridgeLogRecorderHolder; + +public class Slf4jBridgeInstaller { + private Slf4jBridgeInstaller() {} + + public static void installSlf4jLogger(Slf4jLogRecorder slf4JLogRecorder) { + Slf4jBridgeLogRecorderHolder.initialize(slf4JLogRecorder); + } +} diff --git a/instrumentation/internal/internal-slf4j-bridge/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/logging/Slf4jBridgeInstallerFlags.java b/instrumentation/internal/internal-slf4j-bridge/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/logging/Slf4jBridgeInstallerFlags.java new file mode 100644 index 000000000000..f1a8f529b979 --- /dev/null +++ b/instrumentation/internal/internal-slf4j-bridge/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/logging/Slf4jBridgeInstallerFlags.java @@ -0,0 +1,15 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.bootstrap.logging; + +import java.util.concurrent.atomic.AtomicBoolean; + +public final class Slf4jBridgeInstallerFlags { + + private Slf4jBridgeInstallerFlags() {} + + public static final AtomicBoolean IS_INSTALLED = new AtomicBoolean(false); +} diff --git a/instrumentation/internal/internal-slf4j-bridge/javaagent/build.gradle.kts b/instrumentation/internal/internal-slf4j-bridge/javaagent/build.gradle.kts new file mode 100644 index 000000000000..e74638d17193 --- /dev/null +++ b/instrumentation/internal/internal-slf4j-bridge/javaagent/build.gradle.kts @@ -0,0 +1,26 @@ +plugins { + id("otel.javaagent-instrumentation") +} + +muzzle { + pass { + group.set("org.slf4j") + module.set("slf4j-api") + versions.set("[2.0.0,)") + assertInverse.set(true) + } +} + +val latestDepTest = findProperty("testLatestDeps") as Boolean +dependencies { + bootstrap(project(":instrumentation:internal:internal-slf4j-bridge:bootstrap")) + + compileOnly(project(":javaagent-bootstrap")) + + compileOnly("org.slf4j:slf4j-api") { + version { + // 2.0.0 introduced fluent API + strictly("2.0.0") + } + } +} diff --git a/instrumentation/internal/internal-slf4j-bridge/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/internal/slf4jbridge/LoggerFactoryInstrumentation.java b/instrumentation/internal/internal-slf4j-bridge/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/internal/slf4jbridge/LoggerFactoryInstrumentation.java new file mode 100644 index 000000000000..f3f231a3b4bb --- /dev/null +++ b/instrumentation/internal/internal-slf4j-bridge/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/internal/slf4jbridge/LoggerFactoryInstrumentation.java @@ -0,0 +1,43 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.internal.slf4jbridge; + +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.takesArguments; + +import io.opentelemetry.javaagent.bootstrap.logging.Slf4jBridgeInstallerFlags; +import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; + +public class LoggerFactoryInstrumentation implements TypeInstrumentation { + + @Override + public ElementMatcher typeMatcher() { + return named("org.slf4j.LoggerFactory"); + } + + @Override + public void transform(TypeTransformer transformer) { + // once a call to getILoggerFactory() exits we can be certain that slf4j is properly initialized + transformer.applyAdviceToMethod( + named("getILoggerFactory").and(takesArguments(0)), + this.getClass().getName() + "$GetLoggerFactoryAdvice"); + } + + @SuppressWarnings("unused") + public static class GetLoggerFactoryAdvice { + + @Advice.OnMethodExit(suppress = Throwable.class) + public static void onExit() { + if (Slf4jBridgeInstallerFlags.IS_INSTALLED.compareAndSet(false, true)) { + Slf4jLogRecorderImpl.install(); + } + } + } +} diff --git a/instrumentation/internal/internal-slf4j-bridge/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/internal/slf4jbridge/Slf4jBridgeIgnoredTypesConfigurer.java b/instrumentation/internal/internal-slf4j-bridge/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/internal/slf4jbridge/Slf4jBridgeIgnoredTypesConfigurer.java new file mode 100644 index 000000000000..69f45def12b3 --- /dev/null +++ b/instrumentation/internal/internal-slf4j-bridge/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/internal/slf4jbridge/Slf4jBridgeIgnoredTypesConfigurer.java @@ -0,0 +1,20 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.internal.slf4jbridge; + +import com.google.auto.service.AutoService; +import io.opentelemetry.javaagent.extension.ignore.IgnoredTypesBuilder; +import io.opentelemetry.javaagent.extension.ignore.IgnoredTypesConfigurer; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; + +@AutoService(IgnoredTypesConfigurer.class) +public final class Slf4jBridgeIgnoredTypesConfigurer implements IgnoredTypesConfigurer { + + @Override + public void configure(IgnoredTypesBuilder builder, ConfigProperties config) { + builder.allowClass("org.slf4j.LoggerFactory"); + } +} diff --git a/instrumentation/internal/internal-slf4j-bridge/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/internal/slf4jbridge/Slf4jBridgeInstrumentationModule.java b/instrumentation/internal/internal-slf4j-bridge/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/internal/slf4jbridge/Slf4jBridgeInstrumentationModule.java new file mode 100644 index 000000000000..9a00553af3aa --- /dev/null +++ b/instrumentation/internal/internal-slf4j-bridge/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/internal/slf4jbridge/Slf4jBridgeInstrumentationModule.java @@ -0,0 +1,26 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.internal.slf4jbridge; + +import static java.util.Collections.singletonList; + +import com.google.auto.service.AutoService; +import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; +import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import java.util.List; + +@AutoService(InstrumentationModule.class) +public class Slf4jBridgeInstrumentationModule extends InstrumentationModule { + + public Slf4jBridgeInstrumentationModule() { + super("internal-slf4j-bridge"); + } + + @Override + public List typeInstrumentations() { + return singletonList(new LoggerFactoryInstrumentation()); + } +} diff --git a/instrumentation/internal/internal-slf4j-bridge/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/internal/slf4jbridge/Slf4jLogRecorderImpl.java b/instrumentation/internal/internal-slf4j-bridge/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/internal/slf4jbridge/Slf4jLogRecorderImpl.java new file mode 100644 index 000000000000..1f3df49b20ca --- /dev/null +++ b/instrumentation/internal/internal-slf4j-bridge/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/internal/slf4jbridge/Slf4jLogRecorderImpl.java @@ -0,0 +1,110 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.internal.slf4jbridge; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.Value; +import io.opentelemetry.api.logs.LoggerProvider; +import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.context.Context; +import io.opentelemetry.javaagent.Slf4jLogRecorder; +import io.opentelemetry.javaagent.bootstrap.CallDepth; +import io.opentelemetry.javaagent.bootstrap.logging.Slf4jBridgeInstaller; +import javax.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.event.Level; +import org.slf4j.spi.LoggingEventBuilder; + +public final class Slf4jLogRecorderImpl implements Slf4jLogRecorder { + + private Slf4jLogRecorderImpl() {} + + public static void install() { + Slf4jBridgeInstaller.installSlf4jLogger(new Slf4jLogRecorderImpl()); + } + + @Override + public void record( + Context context, + String scopeName, + @Nullable String eventName, + @Nullable Value bodyValue, + Attributes attributes, + Severity severity) { + CallDepth callDepth = CallDepth.forClass(LoggerProvider.class); + try { + if (callDepth.getAndIncrement() > 0) { + return; + } + recordToSlf4j(scopeName, eventName, bodyValue, attributes, severity); + } finally { + callDepth.decrementAndGet(); + } + } + + @SuppressWarnings("CheckReturnValue") + public static void recordToSlf4j( + String scopeName, + @Nullable String eventName, + @Nullable Value bodyValue, + Attributes attributes, + Severity severity) { + Logger logger = LoggerFactory.getLogger(scopeName); + Level level = toSlf4jLevel(severity); + if (!logger.isEnabledForLevel(level)) { + return; + } + LoggingEventBuilder builder = logger.atLevel(level); + if (bodyValue != null) { + builder.setMessage(bodyValue.asString()); + } + attributes.forEach((key, value) -> builder.addKeyValue(key.getKey(), value)); + + // append event_name last to take priority over attributes + if (eventName != null) { + builder.addKeyValue("event_name", eventName); + } + builder.log(); + } + + private static Level toSlf4jLevel(Severity severity) { + switch (severity) { + case TRACE: + case TRACE2: + case TRACE3: + case TRACE4: + return Level.TRACE; + case DEBUG: + case DEBUG2: + case DEBUG3: + case DEBUG4: + return Level.DEBUG; + case INFO: + case INFO2: + case INFO3: + case INFO4: + return Level.INFO; + case WARN: + case WARN2: + case WARN3: + case WARN4: + return Level.WARN; + case ERROR: + case ERROR2: + case ERROR3: + case ERROR4: + case FATAL: + case FATAL2: + case FATAL3: + case FATAL4: + return Level.ERROR; + case UNDEFINED_SEVERITY_NUMBER: + return Level.INFO; + } + throw new IllegalArgumentException("Unknown severity: " + severity); + } +} diff --git a/instrumentation/internal/internal-slf4j-bridge/metadata.yaml b/instrumentation/internal/internal-slf4j-bridge/metadata.yaml new file mode 100644 index 000000000000..5a03ece2f748 --- /dev/null +++ b/instrumentation/internal/internal-slf4j-bridge/metadata.yaml @@ -0,0 +1 @@ +classification: internal diff --git a/instrumentation/log4j/log4j-appender-2.17/library/src/main/java/io/opentelemetry/instrumentation/log4j/appender/v2_17/OpenTelemetryAppender.java b/instrumentation/log4j/log4j-appender-2.17/library/src/main/java/io/opentelemetry/instrumentation/log4j/appender/v2_17/OpenTelemetryAppender.java index 85eb7821ee92..5c3ccfad14e0 100644 --- a/instrumentation/log4j/log4j-appender-2.17/library/src/main/java/io/opentelemetry/instrumentation/log4j/appender/v2_17/OpenTelemetryAppender.java +++ b/instrumentation/log4j/log4j-appender-2.17/library/src/main/java/io/opentelemetry/instrumentation/log4j/appender/v2_17/OpenTelemetryAppender.java @@ -10,6 +10,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.logs.LogRecordBuilder; +import io.opentelemetry.api.logs.Loopback; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.api.trace.TraceFlags; @@ -310,6 +311,12 @@ public void append(LogEvent event) { } private void emit(OpenTelemetry openTelemetry, LogEvent event) { + Context context = Context.current(); + // This is an optimization. SDK will automatically filter these logs as well. + if (Loopback.isLoopback(context)) { + return; + } + String instrumentationName = event.getLoggerName(); if (instrumentationName == null || instrumentationName.isEmpty()) { instrumentationName = "ROOT"; @@ -318,7 +325,6 @@ private void emit(OpenTelemetry openTelemetry, LogEvent event) { LogRecordBuilder builder = openTelemetry.getLogsBridge().loggerBuilder(instrumentationName).build().logRecordBuilder(); ReadOnlyStringMap contextData = event.getContextData(); - Context context = Context.current(); // when using async logger we'll be executing on a different thread than what started logging // reconstruct the context from context data if (context == Context.root()) { @@ -339,6 +345,7 @@ private void emit(OpenTelemetry openTelemetry, LogEvent event) { TraceState.getDefault()))); } } + context = Loopback.withLoopback(context); mapper.mapLogEvent( builder, diff --git a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java index c8d52c454555..10927c536c3b 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java @@ -18,6 +18,7 @@ import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder; import io.opentelemetry.api.logs.LogRecordBuilder; import io.opentelemetry.api.logs.LoggerProvider; +import io.opentelemetry.api.logs.Loopback; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.internal.SemconvStability; @@ -111,19 +112,26 @@ public static Builder builder() { } public void emit(LoggerProvider loggerProvider, ILoggingEvent event, long threadId) { + Context context = Context.current(); + // This is an optimization. SDK will automatically filter these logs as well. + if (Loopback.isLoopback(context)) { + return; + } + context = Loopback.withLoopback(context); + String instrumentationName = event.getLoggerName(); if (instrumentationName == null || instrumentationName.isEmpty()) { instrumentationName = "ROOT"; } LogRecordBuilder builder = loggerProvider.loggerBuilder(instrumentationName).build().logRecordBuilder(); - mapLoggingEvent(builder, event, threadId); + mapLoggingEvent(builder, event, threadId, context); builder.emit(); } /** Map the {@link ILoggingEvent} data model onto the {@link LogRecordBuilder}. */ private void mapLoggingEvent( - LogRecordBuilder builder, ILoggingEvent loggingEvent, long threadId) { + LogRecordBuilder builder, ILoggingEvent loggingEvent, long threadId, Context context) { // message String message = loggingEvent.getFormattedMessage(); if (message != null) { @@ -233,7 +241,7 @@ private void mapLoggingEvent( captureLogstashMarkerAttributes(builder, loggingEvent); } // span context - builder.setContext(Context.current()); + builder.setContext(context); } // getInstant is available since Logback 1.3 diff --git a/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/Slf4jLogRecorder.java b/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/Slf4jLogRecorder.java new file mode 100644 index 000000000000..1b213d89e092 --- /dev/null +++ b/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/Slf4jLogRecorder.java @@ -0,0 +1,24 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.Value; +import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.context.Context; +import javax.annotation.Nullable; + +@FunctionalInterface +public interface Slf4jLogRecorder { + + void record( + Context context, + String scopeName, + @Nullable String eventName, + @Nullable Value body, + Attributes attributes, + Severity severity); +} diff --git a/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/Slf4jBridgeLogRecorderHolder.java b/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/Slf4jBridgeLogRecorderHolder.java new file mode 100644 index 000000000000..aebebc805151 --- /dev/null +++ b/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/Slf4jBridgeLogRecorderHolder.java @@ -0,0 +1,41 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.bootstrap; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.Value; +import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.context.Context; +import io.opentelemetry.javaagent.Slf4jLogRecorder; +import java.util.concurrent.atomic.AtomicReference; + +public final class Slf4jBridgeLogRecorderHolder { + + private static final Slf4jLogRecorder NOOP_OTEL_LOGGER = + (unused, unused2, unused3, unused4, unused5, unused6) -> {}; + + private static final AtomicReference otelLogger = + new AtomicReference<>(NOOP_OTEL_LOGGER); + + public static void initialize(Slf4jLogRecorder slf4JLogRecorder) { + if (!Slf4jBridgeLogRecorderHolder.otelLogger.compareAndSet( + NOOP_OTEL_LOGGER, slf4JLogRecorder)) { + slf4JLogRecorder.record( + Context.root(), + Slf4jLogRecorder.class.getName(), + null, + Value.of("Developer error: logging system has already been initialized once"), + Attributes.empty(), + Severity.WARN); + } + } + + public static Slf4jLogRecorder get() { + return otelLogger.get(); + } + + private Slf4jBridgeLogRecorderHolder() {} +} diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/OpenTelemetryInstaller.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/OpenTelemetryInstaller.java index ff7147ef44bb..2f3554a09fe3 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/OpenTelemetryInstaller.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/OpenTelemetryInstaller.java @@ -9,8 +9,10 @@ import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.config.bridge.DeclarativeConfigPropertiesBridgeBuilder; import io.opentelemetry.javaagent.bootstrap.OpenTelemetrySdkAccess; +import io.opentelemetry.javaagent.bootstrap.Slf4jBridgeLogRecorderHolder; import io.opentelemetry.javaagent.tooling.config.EarlyInitAgentConfig; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; @@ -19,6 +21,8 @@ import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.logs.LogRecordProcessor; +import io.opentelemetry.sdk.logs.ReadWriteLogRecord; import java.util.Arrays; public final class OpenTelemetryInstaller { @@ -36,6 +40,8 @@ public static AutoConfiguredOpenTelemetrySdk installOpenTelemetrySdk( AutoConfiguredOpenTelemetrySdk.builder() .setResultAsGlobal() .setServiceClassLoader(extensionClassLoader) + .addLoggerProviderCustomizer( + (builder, unused) -> builder.addLogRecordProcessor(new Slf4jBridgeAgentProcessor())) .build(); ConfigProvider configProvider = AutoConfigureUtil.getConfigProvider(autoConfiguredSdk); OpenTelemetrySdk sdk = autoConfiguredSdk.getOpenTelemetrySdk(); @@ -56,6 +62,20 @@ public static AutoConfiguredOpenTelemetrySdk installOpenTelemetrySdk( return autoConfiguredSdk; } + private static class Slf4jBridgeAgentProcessor implements LogRecordProcessor { + @Override + public void onEmit(Context context, ReadWriteLogRecord logRecord) { + Slf4jBridgeLogRecorderHolder.get() + .record( + context, + logRecord.getInstrumentationScopeInfo().getName(), + logRecord.getEventName(), + logRecord.getBodyValue(), + logRecord.getAttributes(), + logRecord.getSeverity()); + } + } + // Visible for testing static ConfigProperties getDeclarativeConfigBridgedProperties( EarlyInitAgentConfig earlyConfig, ConfigProvider configProvider) { diff --git a/javaagent/build.gradle.kts b/javaagent/build.gradle.kts index 48f72a5132b2..f2eef9db2a72 100644 --- a/javaagent/build.gradle.kts +++ b/javaagent/build.gradle.kts @@ -174,6 +174,8 @@ tasks { exclude("META-INF/LICENSE") exclude("META-INF/NOTICE") exclude("META-INF/maven/**") + // slf4j-api-2.0.17.jar!META-INF/LICENSE.txt + exclude("META-INF/LICENSE.txt") archiveFileName.set("baseJavaagentLibs-relocated-tmp.jar") } @@ -206,6 +208,8 @@ tasks { exclude("META-INF/LICENSE") exclude("META-INF/NOTICE") exclude("META-INF/maven/**") + // slf4j-api-2.0.17.jar!META-INF/LICENSE.txt + exclude("META-INF/LICENSE.txt") archiveFileName.set("javaagentLibs-relocated-tmp.jar") } diff --git a/settings.gradle.kts b/settings.gradle.kts index 51eb76c1740f..60d7cf51723d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -314,6 +314,8 @@ include(":instrumentation:internal:internal-class-loader:javaagent") include(":instrumentation:internal:internal-class-loader:javaagent-integration-tests") include(":instrumentation:internal:internal-eclipse-osgi-3.6:javaagent") include(":instrumentation:internal:internal-lambda:javaagent") +include(":instrumentation:internal:internal-slf4j-bridge:bootstrap") +include(":instrumentation:internal:internal-slf4j-bridge:javaagent") include(":instrumentation:internal:internal-reflection:javaagent") include(":instrumentation:internal:internal-reflection:javaagent-integration-tests") include(":instrumentation:internal:internal-url-class-loader:javaagent")