Upgrade to otel java 1.19.0 (#6757)

Working PR to capture all the changes required to update to otel java
1.19.0. The new log API force allows
`:instrumentation-appender-api-internal` and
`:instrumentation-appender-sdk-internal`, but necessitates a decent
amount of refactoring as a result.

The PR points at the `1.19.0-SNAPSHOT`, which I'll update upon
publication.

Co-authored-by: Mateusz Rzeszutek <mrzeszutek@splunk.com>
Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
Co-authored-by: Lauri Tulmin <ltulmin@splunk.com>
This commit is contained in:
jack-berg 2022-10-12 11:19:37 -05:00 committed by GitHub
parent c5cd8d67a3
commit aeac361816
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
87 changed files with 701 additions and 1001 deletions

View File

@ -8,7 +8,6 @@ dependencies {
add("muzzleBootstrap", "io.opentelemetry.instrumentation:opentelemetry-instrumentation-api")
add("muzzleBootstrap", "io.opentelemetry.instrumentation:opentelemetry-instrumentation-api-semconv")
add("muzzleBootstrap", "io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations-support")
add("muzzleBootstrap", "io.opentelemetry.instrumentation:opentelemetry-instrumentation-appender-api-internal")
add("muzzleTooling", "io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api")
add("muzzleTooling", "io.opentelemetry.javaagent:opentelemetry-javaagent-tooling")

View File

@ -383,7 +383,6 @@ configurations.configureEach {
substitute(module("io.opentelemetry.instrumentation:opentelemetry-instrumentation-api-semconv")).using(project(":instrumentation-api-semconv"))
substitute(module("io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations")).using(project(":instrumentation-annotations"))
substitute(module("io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations-support")).using(project(":instrumentation-annotations-support"))
substitute(module("io.opentelemetry.instrumentation:opentelemetry-instrumentation-appender-api-internal")).using(project(":instrumentation-appender-api-internal"))
substitute(module("io.opentelemetry.javaagent:opentelemetry-javaagent-bootstrap")).using(project(":javaagent-bootstrap"))
substitute(module("io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api")).using(project(":javaagent-extension-api"))
substitute(module("io.opentelemetry.javaagent:opentelemetry-javaagent-tooling")).using(project(":javaagent-tooling"))

View File

@ -12,7 +12,7 @@ val dependencyVersions = hashMapOf<String, String>()
rootProject.extra["versions"] = dependencyVersions
// this line is managed by .github/scripts/update-sdk-version.sh
val otelVersion = "1.18.0"
val otelVersion = "1.19.0"
rootProject.extra["otelVersion"] = otelVersion

View File

@ -38,9 +38,6 @@ The bootstrap class loader contains several modules:
* **The `instrumentation-annotations-support` module**:
it contains classes that provide support for annotation-based auto-instrumentation, e.g.
the `@WithSpan` annotation. This module is internal and its APIs are considered unstable.
* **The `instrumentation-appender-api-internal` module**:
it contains classes that constitute the "appender API", used by logging instrumentations. This
module is internal and its APIs are considered unstable.
* **The `io.opentelemetry.javaagent.bootstrap` package from the `javaagent-extension-api` module**:
this package contains several instrumentation utilities that are only usable when an application
is instrumented with the javaagent; for example, the `Java8BytecodeBridge` that should be used

View File

@ -74,6 +74,7 @@ tasks {
dependencies {
exclude("org.slf4j:slf4j-api")
exclude("io.opentelemetry:opentelemetry-api")
exclude("io.opentelemetry:opentelemetry-api-logs")
exclude("io.opentelemetry:opentelemetry-context")
exclude("io.opentelemetry:opentelemetry-semconv")
}

View File

@ -71,6 +71,7 @@ tasks {
dependencies {
exclude("org.slf4j:slf4j-api")
exclude("io.opentelemetry:opentelemetry-api")
exclude("io.opentelemetry:opentelemetry-api-logs")
exclude("io.opentelemetry:opentelemetry-context")
exclude("io.opentelemetry:opentelemetry-semconv")
}

View File

@ -57,7 +57,7 @@ final class MetricsView {
// the list of rpc server metrics attributes is from
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/rpc.md#attributes
Set<AttributeKey> view = new HashSet<>(alwaysInclude);
view.add(SemanticAttributes.NET_HOST_IP);
view.add(SemanticAttributes.NET_SOCK_HOST_ADDR);
view.add(SemanticAttributes.NET_TRANSPORT);
return view;
}

View File

@ -41,14 +41,14 @@ class RpcServerMetricsTest {
Attributes responseAttributes1 =
Attributes.builder()
.put(SemanticAttributes.NET_HOST_NAME, "example.com")
.put(SemanticAttributes.NET_HOST_IP, "127.0.0.1")
.put(SemanticAttributes.NET_SOCK_HOST_ADDR, "127.0.0.1")
.put(SemanticAttributes.NET_HOST_PORT, 8080)
.put(SemanticAttributes.NET_TRANSPORT, "ip_tcp")
.build();
Attributes responseAttributes2 =
Attributes.builder()
.put(SemanticAttributes.NET_HOST_IP, "127.0.0.1")
.put(SemanticAttributes.NET_SOCK_HOST_ADDR, "127.0.0.1")
.put(SemanticAttributes.NET_HOST_PORT, 8080)
.put(SemanticAttributes.NET_TRANSPORT, "ip_tcp")
.build();
@ -120,7 +120,8 @@ class RpcServerMetricsTest {
SemanticAttributes.RPC_SERVICE,
"myservice.EchoService"),
equalTo(SemanticAttributes.RPC_METHOD, "exampleMethod"),
equalTo(SemanticAttributes.NET_HOST_IP, "127.0.0.1"),
equalTo(
SemanticAttributes.NET_SOCK_HOST_ADDR, "127.0.0.1"),
equalTo(SemanticAttributes.NET_TRANSPORT, "ip_tcp")))));
}

View File

@ -1,13 +0,0 @@
plugins {
id("otel.java-conventions")
id("otel.animalsniffer-conventions")
id("otel.jacoco-conventions")
id("otel.japicmp-conventions")
id("otel.publish-conventions")
}
group = "io.opentelemetry.instrumentation"
dependencies {
api("io.opentelemetry:opentelemetry-api")
}

View File

@ -1,24 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.api.appender.internal;
import javax.annotation.concurrent.ThreadSafe;
/**
* A {@link LogEmitter} is the entry point into a log pipeline.
*
* <p>Obtain a log builder via {@link #logBuilder()}, add properties using the setters, and emit it
* via {@link LogRecordBuilder#emit()}.
*
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*/
@ThreadSafe
public interface LogEmitter {
/** Return a new {@link LogRecordBuilder} to emit a log. */
LogRecordBuilder logBuilder();
}

View File

@ -1,38 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.api.appender.internal;
/**
* Builder class for creating {@link LogEmitter} instances.
*
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*/
public interface LogEmitterBuilder {
/**
* Assign an OpenTelemetry schema URL to the resulting {@link LogEmitter}.
*
* @param schemaUrl the URL of the OpenTelemetry schema being used by this instrumentation library
* @return this
*/
LogEmitterBuilder setSchemaUrl(String schemaUrl);
/**
* Assign a version to the instrumentation library that is using the resulting {@link LogEmitter}.
*
* @param instrumentationVersion the version of the instrumentation library
* @return this
*/
LogEmitterBuilder setInstrumentationVersion(String instrumentationVersion);
/**
* Gets or creates a {@link LogEmitter} instance.
*
* @return a log emitter instance configured with the provided options
*/
LogEmitter build();
}

View File

@ -1,21 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.api.appender.internal;
/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public interface LogEmitterProvider {
/**
* Creates a {@link LogEmitterBuilder} instance.
*
* @param instrumentationName the name of the instrumentation library
* @return a log emitter builder instance
*/
LogEmitterBuilder logEmitterBuilder(String instrumentationName);
}

View File

@ -1,54 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.api.appender.internal;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Nullable;
/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public final class LogEmitterProviderHolder {
private final AtomicReference<LogEmitterProvider> instance =
new AtomicReference<>(NoopLogEmitterProvider.INSTANCE);
@Nullable private volatile Throwable setInstanceCaller;
/** Returns the registered {@link LogEmitterProvider}. */
public LogEmitterProvider get() {
return instance.get();
}
/**
* Sets the {@link LogEmitterProvider} that should be the instance. Future calls to {@link #get()}
* will return the provided {@link LogEmitterProvider} instance. This should be called once as
* early as possible in your application initialization logic, often in a {@code static} block in
* your main class. It should only be called once - an attempt to call it a second time will
* result in an error. If trying to set the instance {@link LogEmitterProvider} multiple times in
* tests, use {@link LogEmitterProviderHolder#resetForTest()} between them.
*/
public void set(LogEmitterProvider logEmitterProvider) {
boolean changed = instance.compareAndSet(NoopLogEmitterProvider.INSTANCE, logEmitterProvider);
if (!changed && (logEmitterProvider != NoopLogEmitterProvider.INSTANCE)) {
throw new IllegalStateException(
"LogEmitterProviderHolder.set has already been called. LogEmitterProviderHolder.set "
+ "must be called only once before any calls to LogEmitterProviderHolder.get. "
+ "Previous invocation set to cause of this exception.",
setInstanceCaller);
}
setInstanceCaller = new Throwable();
}
/**
* Unsets the {@link LogEmitterProvider}. This is only meant to be used from tests which need to
* reconfigure {@link LogEmitterProvider}.
*/
public void resetForTest() {
instance.set(NoopLogEmitterProvider.INSTANCE);
}
}

View File

@ -1,47 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.api.appender.internal;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.context.Context;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
/**
* Used to construct and emit logs from a {@link LogEmitter}.
*
* <p>Obtain a {@link LogRecordBuilder} via {@link LogEmitter#logBuilder()}, add properties using
* the setters, and emit the log by calling {@link #emit()}.
*
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*/
public interface LogRecordBuilder {
/** Set the epoch timestamp using the timestamp and unit. */
LogRecordBuilder setEpoch(long timestamp, TimeUnit unit);
/** Set the epoch timestamp using the instant. */
LogRecordBuilder setEpoch(Instant instant);
/** Set the context. */
LogRecordBuilder setContext(Context context);
/** Set the severity. */
LogRecordBuilder setSeverity(Severity severity);
/** Set the severity text. */
LogRecordBuilder setSeverityText(String severityText);
/** Set the body string. */
LogRecordBuilder setBody(String body);
/** Set the attributes. */
LogRecordBuilder setAllAttributes(Attributes attributes);
/** Emit the log. */
void emit();
}

View File

@ -1,16 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.api.appender.internal;
final class NoopLogEmitter implements LogEmitter {
static final LogEmitter INSTANCE = new NoopLogEmitter();
@Override
public LogRecordBuilder logBuilder() {
return NoopLogRecordBuilder.INSTANCE;
}
}

View File

@ -1,30 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.api.appender.internal;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
final class NoopLogEmitterBuilder implements LogEmitterBuilder {
static final LogEmitterBuilder INSTANCE = new NoopLogEmitterBuilder();
@Override
@CanIgnoreReturnValue
public LogEmitterBuilder setSchemaUrl(String schemaUrl) {
return this;
}
@Override
@CanIgnoreReturnValue
public LogEmitterBuilder setInstrumentationVersion(String instrumentationVersion) {
return this;
}
@Override
public LogEmitter build() {
return NoopLogEmitter.INSTANCE;
}
}

View File

@ -1,16 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.api.appender.internal;
final class NoopLogEmitterProvider implements LogEmitterProvider {
static final NoopLogEmitterProvider INSTANCE = new NoopLogEmitterProvider();
@Override
public LogEmitterBuilder logEmitterBuilder(String instrumentationName) {
return NoopLogEmitterBuilder.INSTANCE;
}
}

View File

@ -1,62 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.api.appender.internal;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.context.Context;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
final class NoopLogRecordBuilder implements LogRecordBuilder {
static final LogRecordBuilder INSTANCE = new NoopLogRecordBuilder();
@Override
@CanIgnoreReturnValue
public LogRecordBuilder setEpoch(long timestamp, TimeUnit unit) {
return this;
}
@Override
@CanIgnoreReturnValue
public LogRecordBuilder setEpoch(Instant instant) {
return this;
}
@Override
@CanIgnoreReturnValue
public LogRecordBuilder setContext(Context context) {
return this;
}
@Override
@CanIgnoreReturnValue
public LogRecordBuilder setSeverity(Severity severity) {
return this;
}
@Override
@CanIgnoreReturnValue
public LogRecordBuilder setSeverityText(String severityText) {
return this;
}
@Override
@CanIgnoreReturnValue
public LogRecordBuilder setBody(String body) {
return this;
}
@Override
@CanIgnoreReturnValue
public LogRecordBuilder setAllAttributes(Attributes attributes) {
return this;
}
@Override
public void emit() {}
}

View File

@ -1,48 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.api.appender.internal;
/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public enum Severity {
UNDEFINED_SEVERITY_NUMBER(0),
TRACE(1),
TRACE2(2),
TRACE3(3),
TRACE4(4),
DEBUG(5),
DEBUG2(6),
DEBUG3(7),
DEBUG4(8),
INFO(9),
INFO2(10),
INFO3(11),
INFO4(12),
WARN(13),
WARN2(14),
WARN3(15),
WARN4(16),
ERROR(17),
ERROR2(18),
ERROR3(19),
ERROR4(20),
FATAL(21),
FATAL2(22),
FATAL3(23),
FATAL4(24);
private final int severityNumber;
Severity(int severityNumber) {
this.severityNumber = severityNumber;
}
public int getSeverityNumber() {
return severityNumber;
}
}

View File

@ -1,66 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.api.appender.internal;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.mockito.Mockito.mock;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
class LogEmitterProviderHolderTest {
private static final LogEmitterProviderHolder holder = new LogEmitterProviderHolder();
@BeforeAll
static void beforeClass() {
holder.resetForTest();
}
@AfterEach
void after() {
holder.resetForTest();
}
@Test
void testGlobalBeforeSet() {
assertThat(holder.get()).isSameAs(NoopLogEmitterProvider.INSTANCE);
}
@Test
void setThenSet() {
setLogEmitterProvider();
assertThatThrownBy(() -> holder.set(mock(LogEmitterProvider.class)))
.isInstanceOf(IllegalStateException.class)
.hasMessageContaining("LogEmitterProviderHolder.set has already been called")
.hasStackTraceContaining("setLogEmitterProvider");
}
@Test
void getThenSet() {
LogEmitterProvider existingProvider = holder.get();
assertSame(existingProvider, NoopLogEmitterProvider.INSTANCE);
LogEmitterProvider newProvider = mock(LogEmitterProvider.class);
holder.set(newProvider);
assertSame(newProvider, holder.get());
}
@Test
void okToSetNoopMultipleTimes() {
holder.set(NoopLogEmitterProvider.INSTANCE);
holder.set(NoopLogEmitterProvider.INSTANCE);
holder.set(NoopLogEmitterProvider.INSTANCE);
holder.set(NoopLogEmitterProvider.INSTANCE);
// pass
}
private static void setLogEmitterProvider() {
holder.set(mock(LogEmitterProvider.class));
}
}

View File

@ -1,15 +0,0 @@
plugins {
id("otel.java-conventions")
id("otel.animalsniffer-conventions")
id("otel.jacoco-conventions")
id("otel.japicmp-conventions")
id("otel.publish-conventions")
}
group = "io.opentelemetry.instrumentation"
dependencies {
api(project(":instrumentation-appender-api-internal"))
api("io.opentelemetry:opentelemetry-sdk-logs")
}

View File

@ -1,23 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.sdk.appender.internal;
import io.opentelemetry.instrumentation.api.appender.internal.LogEmitter;
import io.opentelemetry.instrumentation.api.appender.internal.LogRecordBuilder;
final class DelegatingLogEmitter implements LogEmitter {
private final io.opentelemetry.sdk.logs.LogEmitter delegate;
DelegatingLogEmitter(io.opentelemetry.sdk.logs.LogEmitter delegate) {
this.delegate = delegate;
}
@Override
public LogRecordBuilder logBuilder() {
return new DelegatingLogRecordBuilder(delegate.logRecordBuilder());
}
}

View File

@ -1,38 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.sdk.appender.internal;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import io.opentelemetry.instrumentation.api.appender.internal.LogEmitter;
import io.opentelemetry.instrumentation.api.appender.internal.LogEmitterBuilder;
final class DelegatingLogEmitterBuilder implements LogEmitterBuilder {
private final io.opentelemetry.sdk.logs.LogEmitterBuilder delegate;
DelegatingLogEmitterBuilder(io.opentelemetry.sdk.logs.LogEmitterBuilder delegate) {
this.delegate = delegate;
}
@Override
@CanIgnoreReturnValue
public LogEmitterBuilder setSchemaUrl(String schemaUrl) {
delegate.setSchemaUrl(schemaUrl);
return this;
}
@Override
@CanIgnoreReturnValue
public LogEmitterBuilder setInstrumentationVersion(String instrumentationVersion) {
delegate.setInstrumentationVersion(instrumentationVersion);
return this;
}
@Override
public LogEmitter build() {
return new DelegatingLogEmitter(delegate.build());
}
}

View File

@ -1,32 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.sdk.appender.internal;
import io.opentelemetry.instrumentation.api.appender.internal.LogEmitterBuilder;
import io.opentelemetry.instrumentation.api.appender.internal.LogEmitterProvider;
import io.opentelemetry.sdk.logs.SdkLogEmitterProvider;
/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public final class DelegatingLogEmitterProvider implements LogEmitterProvider {
private final SdkLogEmitterProvider delegate;
public static DelegatingLogEmitterProvider from(SdkLogEmitterProvider delegate) {
return new DelegatingLogEmitterProvider(delegate);
}
private DelegatingLogEmitterProvider(SdkLogEmitterProvider delegate) {
this.delegate = delegate;
}
@Override
public LogEmitterBuilder logEmitterBuilder(String instrumentationName) {
return new DelegatingLogEmitterBuilder(delegate.logEmitterBuilder(instrumentationName));
}
}

View File

@ -1,77 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.sdk.appender.internal;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.appender.internal.LogRecordBuilder;
import io.opentelemetry.instrumentation.api.appender.internal.Severity;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
final class DelegatingLogRecordBuilder implements LogRecordBuilder {
private final io.opentelemetry.sdk.logs.LogRecordBuilder delegate;
DelegatingLogRecordBuilder(io.opentelemetry.sdk.logs.LogRecordBuilder delegate) {
this.delegate = delegate;
}
@Override
@CanIgnoreReturnValue
public LogRecordBuilder setEpoch(long timestamp, TimeUnit unit) {
delegate.setEpoch(timestamp, unit);
return this;
}
@Override
@CanIgnoreReturnValue
public LogRecordBuilder setEpoch(Instant instant) {
delegate.setEpoch(instant);
return this;
}
@Override
@CanIgnoreReturnValue
public LogRecordBuilder setContext(Context context) {
delegate.setContext(context);
return this;
}
@Override
@CanIgnoreReturnValue
public LogRecordBuilder setSeverity(Severity severity) {
delegate.setSeverity(io.opentelemetry.sdk.logs.data.Severity.valueOf(severity.name()));
return this;
}
@Override
@CanIgnoreReturnValue
public LogRecordBuilder setSeverityText(String severityText) {
delegate.setSeverityText(severityText);
return this;
}
@Override
@CanIgnoreReturnValue
public LogRecordBuilder setBody(String body) {
delegate.setBody(body);
return this;
}
@Override
@CanIgnoreReturnValue
public LogRecordBuilder setAllAttributes(Attributes attributes) {
delegate.setAllAttributes(attributes);
return this;
}
@Override
public void emit() {
delegate.emit();
}
}

View File

@ -5,7 +5,7 @@ plugins {
dependencies {
compileOnly(project(":instrumentation:java-util-logging:shaded-stub-for-instrumenting"))
compileOnly(project(":instrumentation-appender-api-internal"))
compileOnly("io.opentelemetry:opentelemetry-api-logs")
compileOnly(project(":javaagent-bootstrap"))
// ensure no cross interference

View File

@ -8,10 +8,10 @@ package io.opentelemetry.javaagent.instrumentation.jul;
import application.java.util.logging.Logger;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.logs.GlobalLoggerProvider;
import io.opentelemetry.api.logs.LogRecordBuilder;
import io.opentelemetry.api.logs.Severity;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.appender.internal.LogRecordBuilder;
import io.opentelemetry.instrumentation.api.appender.internal.Severity;
import io.opentelemetry.javaagent.bootstrap.AgentLogEmitterProvider;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.io.PrintWriter;
@ -41,7 +41,7 @@ public final class JavaUtilLoggingHelper {
instrumentationName = "ROOT";
}
LogRecordBuilder builder =
AgentLogEmitterProvider.get().logEmitterBuilder(instrumentationName).build().logBuilder();
GlobalLoggerProvider.get().loggerBuilder(instrumentationName).build().logRecordBuilder();
mapLogRecord(builder, logRecord);
builder.emit();
}
@ -81,7 +81,7 @@ public final class JavaUtilLoggingHelper {
Throwable throwable = logRecord.getThrown();
if (throwable != null) {
// TODO (trask) extract method for recording exception into
// instrumentation-appender-api-internal
// io.opentelemetry:opentelemetry-api-logs
attributes.put(SemanticAttributes.EXCEPTION_TYPE, throwable.getClass().getName());
attributes.put(SemanticAttributes.EXCEPTION_MESSAGE, throwable.getMessage());
StringWriter writer = new StringWriter();

View File

@ -13,7 +13,7 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import application.java.util.logging.Logger;
import io.opentelemetry.instrumentation.api.appender.internal.LogEmitterProvider;
import io.opentelemetry.api.logs.LoggerProvider;
import io.opentelemetry.javaagent.bootstrap.CallDepth;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
@ -50,7 +50,7 @@ class JavaUtilLoggingInstrumentation implements TypeInstrumentation {
@Advice.Local("otelCallDepth") CallDepth callDepth) {
// need to track call depth across all loggers in order to avoid double capture when one
// logging framework delegates to another
callDepth = CallDepth.forClass(LogEmitterProvider.class);
callDepth = CallDepth.forClass(LoggerProvider.class);
if (callDepth.getAndIncrement() == 0) {
JavaUtilLoggingHelper.capture(logger, logRecord);
}

View File

@ -4,7 +4,7 @@
*/
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
import io.opentelemetry.sdk.logs.data.Severity
import io.opentelemetry.api.logs.Severity
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
import spock.lang.Unroll
@ -50,9 +50,9 @@ class JavaUtilLoggingTest extends AgentInstrumentationSpecification {
await()
.untilAsserted(
() -> {
assertThat(logs).hasSize(1)
assertThat(logRecords).hasSize(1)
})
def log = logs.get(0)
def log = logRecords.get(0)
if (testArgs == "params") {
assertThat(log.getBody().asString()).isEqualTo("xyz: 123")
} else {
@ -81,7 +81,7 @@ class JavaUtilLoggingTest extends AgentInstrumentationSpecification {
}
} else {
Thread.sleep(500) // sleep a bit just to make sure no log is captured
logs.size() == 0
logRecords.size() == 0
}
where:

View File

@ -14,7 +14,7 @@ muzzle {
dependencies {
library("org.jboss.logmanager:jboss-logmanager:1.1.0.GA")
compileOnly(project(":instrumentation-appender-api-internal"))
compileOnly("io.opentelemetry:opentelemetry-api-logs")
compileOnly(project(":javaagent-bootstrap"))
// ensure no cross interference

View File

@ -11,7 +11,7 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import io.opentelemetry.instrumentation.api.appender.internal.LogEmitterProvider;
import io.opentelemetry.api.logs.LoggerProvider;
import io.opentelemetry.javaagent.bootstrap.CallDepth;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
@ -47,7 +47,7 @@ public class JbossLogmanagerInstrumentation implements TypeInstrumentation {
@Advice.Local("otelCallDepth") CallDepth callDepth) {
// need to track call depth across all loggers in order to avoid double capture when one
// logging framework delegates to another
callDepth = CallDepth.forClass(LogEmitterProvider.class);
callDepth = CallDepth.forClass(LoggerProvider.class);
if (callDepth.getAndIncrement() == 0) {
LoggingEventMapper.INSTANCE.capture(logger, record);
}

View File

@ -10,11 +10,11 @@ import static java.util.Collections.emptyList;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.logs.GlobalLoggerProvider;
import io.opentelemetry.api.logs.LogRecordBuilder;
import io.opentelemetry.api.logs.Severity;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.appender.internal.LogRecordBuilder;
import io.opentelemetry.instrumentation.api.appender.internal.Severity;
import io.opentelemetry.instrumentation.api.internal.cache.Cache;
import io.opentelemetry.javaagent.bootstrap.AgentLogEmitterProvider;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.io.PrintWriter;
@ -58,7 +58,7 @@ public final class LoggingEventMapper {
}
LogRecordBuilder builder =
AgentLogEmitterProvider.get().logEmitterBuilder(instrumentationName).build().logBuilder();
GlobalLoggerProvider.get().loggerBuilder(instrumentationName).build().logRecordBuilder();
String message = record.getFormattedMessage();
if (message != null) {
@ -76,7 +76,7 @@ public final class LoggingEventMapper {
Throwable throwable = record.getThrown();
if (throwable != null) {
// TODO (trask) extract method for recording exception into
// instrumentation-appender-api-internal
// io.opentelemetry:opentelemetry-api-logs
attributes.put(SemanticAttributes.EXCEPTION_TYPE, throwable.getClass().getName());
attributes.put(SemanticAttributes.EXCEPTION_MESSAGE, throwable.getMessage());
StringWriter writer = new StringWriter();

View File

@ -5,7 +5,7 @@
import io.opentelemetry.api.common.AttributeKey
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
import io.opentelemetry.sdk.logs.data.Severity
import io.opentelemetry.api.logs.Severity
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
import org.jboss.logmanager.MDC
import org.jboss.logmanager.Level
@ -50,9 +50,9 @@ class JbossLogmanagerTest extends AgentInstrumentationSpecification {
await()
.untilAsserted(
() -> {
assertThat(logs).hasSize(1)
assertThat(logRecords).hasSize(1)
})
def log = logs.get(0)
def log = logRecords.get(0)
assertThat(log.getBody().asString()).isEqualTo("xyz")
assertThat(log.getInstrumentationScopeInfo().getName()).isEqualTo("abc")
assertThat(log.getSeverity()).isEqualTo(severity)
@ -77,7 +77,7 @@ class JbossLogmanagerTest extends AgentInstrumentationSpecification {
}
} else {
Thread.sleep(500) // sleep a bit just to make sure no log is captured
assertThat(logs.size() == 0).isTrue()
assertThat(logRecords.size() == 0).isTrue()
}
where:
@ -113,9 +113,9 @@ class JbossLogmanagerTest extends AgentInstrumentationSpecification {
await()
.untilAsserted(
() -> {
assertThat(logs).hasSize(1)
assertThat(logRecords).hasSize(1)
})
def log = logs.get(0)
def log = logRecords.get(0)
assertThat(log.getBody().asString()).isEqualTo("xyz")
assertThat(log.getInstrumentationScopeInfo().getName()).isEqualTo("abc")
assertThat(log.getSeverity()).isEqualTo(Severity.INFO)

View File

@ -9,8 +9,9 @@ import io.opentelemetry.context.Context
import io.opentelemetry.extension.kotlin.asContextElement
import io.opentelemetry.instrumentation.reactor.ContextPropagationOperator
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension
import io.opentelemetry.instrumentation.testing.util.TelemetryDataUtil.orderByRootSpanName
import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat
import io.opentelemetry.sdk.trace.data.SpanData
import io.opentelemetry.sdk.testing.assertj.TraceAssert
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
@ -48,7 +49,6 @@ import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.Arguments.arguments
import org.junit.jupiter.params.provider.ArgumentsProvider
import org.junit.jupiter.params.provider.ArgumentsSource
import java.time.Duration
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
import java.util.function.Consumer
@ -69,7 +69,8 @@ class KotlinCoroutinesInstrumentationTest {
singleThread.shutdown()
}
@RegisterExtension val testing = AgentInstrumentationExtension.create()
@RegisterExtension
val testing = AgentInstrumentationExtension.create()
val tracer = testing.openTelemetry.getTracer("test")
@ -325,42 +326,40 @@ class KotlinCoroutinesInstrumentationTest {
// should have the same iteration number (attribute "iter").
// The traces are in some random order, so let's keep track and make sure we see
// each iteration # exactly once
val assertions = mutableListOf<Consumer<List<SpanData>>>()
val assertions = mutableListOf<Consumer<TraceAssert>>()
for (i in 0 until numIters) {
assertions.add { trace ->
assertThat(trace).satisfiesExactly(
Consumer {
assertThat(it)
.hasName("a")
trace.hasSpansSatisfyingExactly(
{
it.hasName("a")
.hasNoParent()
},
Consumer {
assertThat(it)
.hasName("a2")
.hasParent(trace.get(0))
{
it.hasName("a2")
.hasParent(trace.getSpan(0))
}
)
}
}
for (i in 0 until numIters) {
assertions.add { trace ->
assertThat(trace).satisfiesExactly(
Consumer {
assertThat(it)
.hasName("b")
trace.hasSpansSatisfyingExactly(
{
it.hasName("b")
.hasNoParent()
},
Consumer {
assertThat(it)
.hasName("b2")
.hasParent(trace.get(0))
{
it.hasName("b2")
.hasParent(trace.getSpan(0))
}
)
}
}
await().atMost(Duration.ofSeconds(30)).untilAsserted {
val traces = testing.waitForTraces(assertions.size)
assertThat(traces).satisfiesExactlyInAnyOrder(*assertions.toTypedArray())
}
testing.waitAndAssertSortedTraces(
orderByRootSpanName("a", "b"),
*assertions.toTypedArray()
)
}
@ParameterizedTest

View File

@ -16,7 +16,7 @@ dependencies {
// 1.2 introduces MDC and there's no version earlier than 1.2.4 available
library("log4j:log4j:1.2.4")
compileOnly(project(":instrumentation-appender-api-internal"))
compileOnly("io.opentelemetry:opentelemetry-api-logs")
compileOnly(project(":javaagent-bootstrap"))
testImplementation("org.awaitility:awaitility")

View File

@ -11,7 +11,7 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import io.opentelemetry.instrumentation.api.appender.internal.LogEmitterProvider;
import io.opentelemetry.api.logs.LoggerProvider;
import io.opentelemetry.javaagent.bootstrap.CallDepth;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
@ -54,7 +54,7 @@ class Log4jAppenderInstrumentation implements TypeInstrumentation {
@Advice.Local("otelCallDepth") CallDepth callDepth) {
// need to track call depth across all loggers to avoid double capture when one logging
// framework delegates to another
callDepth = CallDepth.forClass(LogEmitterProvider.class);
callDepth = CallDepth.forClass(LoggerProvider.class);
if (callDepth.getAndIncrement() == 0) {
LogEventMapper.INSTANCE.capture(logger, level, message, t);
}

View File

@ -10,11 +10,11 @@ import static java.util.Collections.emptyList;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.logs.GlobalLoggerProvider;
import io.opentelemetry.api.logs.LogRecordBuilder;
import io.opentelemetry.api.logs.Severity;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.appender.internal.LogRecordBuilder;
import io.opentelemetry.instrumentation.api.appender.internal.Severity;
import io.opentelemetry.instrumentation.api.internal.cache.Cache;
import io.opentelemetry.javaagent.bootstrap.AgentLogEmitterProvider;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.io.PrintWriter;
@ -64,7 +64,7 @@ public final class LogEventMapper {
instrumentationName = "ROOT";
}
LogRecordBuilder builder =
AgentLogEmitterProvider.get().logEmitterBuilder(instrumentationName).build().logBuilder();
GlobalLoggerProvider.get().loggerBuilder(instrumentationName).build().logRecordBuilder();
// message
if (message != null) {
@ -82,7 +82,7 @@ public final class LogEventMapper {
// throwable
if (throwable != null) {
// TODO (trask) extract method for recording exception into
// instrumentation-appender-api-internal
// io.opentelemetry:opentelemetry-api-logs
attributes.put(SemanticAttributes.EXCEPTION_TYPE, throwable.getClass().getName());
attributes.put(SemanticAttributes.EXCEPTION_MESSAGE, throwable.getMessage());
StringWriter writer = new StringWriter();

View File

@ -5,7 +5,7 @@
import io.opentelemetry.api.common.AttributeKey
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
import io.opentelemetry.sdk.logs.data.Severity
import io.opentelemetry.api.logs.Severity
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
import org.apache.log4j.Logger
import org.apache.log4j.MDC
@ -55,9 +55,9 @@ class Log4j1Test extends AgentInstrumentationSpecification {
await()
.untilAsserted(
() -> {
assertThat(logs).hasSize(1)
assertThat(logRecords).hasSize(1)
})
def log = logs.get(0)
def log = logRecords.get(0)
assertThat(log.getBody().asString()).isEqualTo("xyz")
assertThat(log.getInstrumentationScopeInfo().getName()).isEqualTo("abc")
assertThat(log.getSeverity()).isEqualTo(severity)
@ -82,7 +82,7 @@ class Log4j1Test extends AgentInstrumentationSpecification {
}
} else {
Thread.sleep(500) // sleep a bit just to make sure no log is captured
logs.size() == 0
logRecords.size() == 0
}
where:
@ -118,9 +118,9 @@ class Log4j1Test extends AgentInstrumentationSpecification {
await()
.untilAsserted(
() -> {
assertThat(logs).hasSize(1)
assertThat(logRecords).hasSize(1)
})
def log = logs.get(0)
def log = logRecords.get(0)
assertThat(log.getBody().asString()).isEqualTo("xyz")
assertThat(log.getInstrumentationScopeInfo().getName()).isEqualTo("abc")
assertThat(log.getSeverity()).isEqualTo(Severity.INFO)

View File

@ -14,7 +14,7 @@ muzzle {
dependencies {
library("org.apache.logging.log4j:log4j-core:2.17.0")
compileOnly(project(":instrumentation-appender-api-internal"))
compileOnly("io.opentelemetry:opentelemetry-api-logs")
compileOnly(project(":javaagent-bootstrap"))
implementation(project(":instrumentation:log4j:log4j-appender-2.17:library"))

View File

@ -14,7 +14,7 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import io.opentelemetry.instrumentation.api.appender.internal.LogEmitterProvider;
import io.opentelemetry.api.logs.LoggerProvider;
import io.opentelemetry.javaagent.bootstrap.CallDepth;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
@ -67,7 +67,7 @@ class Log4jAppenderInstrumentation implements TypeInstrumentation {
@Advice.Local("otelCallDepth") CallDepth callDepth) {
// need to track call depth across all loggers in order to avoid double capture when one
// logging framework delegates to another
callDepth = CallDepth.forClass(LogEmitterProvider.class);
callDepth = CallDepth.forClass(LoggerProvider.class);
if (callDepth.getAndIncrement() == 0) {
Log4jHelper.capture(logger, level, marker, message, t);
}

View File

@ -7,10 +7,10 @@ package io.opentelemetry.javaagent.instrumentation.log4j.appender.v2_17;
import static java.util.Collections.emptyList;
import io.opentelemetry.instrumentation.api.appender.internal.LogRecordBuilder;
import io.opentelemetry.api.logs.GlobalLoggerProvider;
import io.opentelemetry.api.logs.LogRecordBuilder;
import io.opentelemetry.instrumentation.log4j.appender.v2_17.internal.ContextDataAccessor;
import io.opentelemetry.instrumentation.log4j.appender.v2_17.internal.LogEventMapper;
import io.opentelemetry.javaagent.bootstrap.AgentLogEmitterProvider;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import java.util.List;
import java.util.Map;
@ -59,7 +59,7 @@ public final class Log4jHelper {
instrumentationName = "ROOT";
}
LogRecordBuilder builder =
AgentLogEmitterProvider.get().logEmitterBuilder(instrumentationName).build().logBuilder();
GlobalLoggerProvider.get().loggerBuilder(instrumentationName).build().logRecordBuilder();
Map<String, String> contextData = ThreadContext.getImmutableContext();
mapper.mapLogEvent(builder, message, level, marker, throwable, contextData);
builder.emit();

View File

@ -4,7 +4,7 @@
*/
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
import io.opentelemetry.sdk.logs.data.Severity
import io.opentelemetry.api.logs.Severity
import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
import org.apache.logging.log4j.LogManager
@ -50,9 +50,9 @@ class Log4j2Test extends AgentInstrumentationSpecification {
await()
.untilAsserted(
() -> {
assertThat(logs).hasSize(1)
assertThat(logRecords).hasSize(1)
})
def log = logs.get(0)
def log = logRecords.get(0)
assertThat(log.getBody().asString()).isEqualTo("xyz: 123")
assertThat(log.getInstrumentationScopeInfo().getName()).isEqualTo("abc")
assertThat(log.getSeverity()).isEqualTo(severity)
@ -77,7 +77,7 @@ class Log4j2Test extends AgentInstrumentationSpecification {
}
} else {
Thread.sleep(500) // sleep a bit just to make sure no log is captured
logs.size() == 0
logRecords.size() == 0
}
where:
@ -112,9 +112,9 @@ class Log4j2Test extends AgentInstrumentationSpecification {
await()
.untilAsserted(
() -> {
assertThat(logs).hasSize(1)
assertThat(logRecords).hasSize(1)
})
def log = logs.get(0)
def log = logRecords.get(0)
assertThat(log.getBody().asString()).isEqualTo("xyz: 123")
assertThat(log.getInstrumentationScopeInfo().getName()).isEqualTo("abc")
assertThat(log.getSeverity()).isEqualTo(Severity.INFO)
@ -138,9 +138,9 @@ class Log4j2Test extends AgentInstrumentationSpecification {
await()
.untilAsserted(
() -> {
assertThat(logs).hasSize(1)
assertThat(logRecords).hasSize(1)
})
def log = logs.get(0)
def log = logRecords.get(0)
assertThat(log.getBody().asString()).isEmpty()
assertThat(log.getInstrumentationScopeInfo().getName()).isEqualTo("abc")
assertThat(log.getSeverity()).isEqualTo(Severity.INFO)
@ -164,9 +164,9 @@ class Log4j2Test extends AgentInstrumentationSpecification {
await()
.untilAsserted(
() -> {
assertThat(logs).hasSize(1)
assertThat(logRecords).hasSize(1)
})
def log = logs.get(0)
def log = logRecords.get(0)
assertThat(log.getBody().asString()).isEqualTo("val2")
assertThat(log.getInstrumentationScopeInfo().getName()).isEqualTo("abc")
assertThat(log.getSeverity()).isEqualTo(Severity.INFO)
@ -189,9 +189,9 @@ class Log4j2Test extends AgentInstrumentationSpecification {
await()
.untilAsserted(
() -> {
assertThat(logs).hasSize(1)
assertThat(logRecords).hasSize(1)
})
def log = logs.get(0)
def log = logRecords.get(0)
assertThat(log.getBody().asString()).isEqualTo("a message")
assertThat(log.getInstrumentationScopeInfo().getName()).isEqualTo("abc")
assertThat(log.getSeverity()).isEqualTo(Severity.INFO)
@ -215,8 +215,8 @@ class Log4j2Test extends AgentInstrumentationSpecification {
await()
.untilAsserted(
() -> {
assertThat(logs).hasSize(1)
def log = logs.get(0)
assertThat(logRecords).hasSize(1)
def log = logRecords.get(0)
OpenTelemetryAssertions.assertThat(log.getAttributes()).containsEntry("log4j.marker", markerName)
})
}

View File

@ -51,19 +51,17 @@ The following demonstrates how you might configure the appender in your `log4j.x
</Configuration>
```
Next, associate the `OpenTelemetryAppender` configured via `log4j2.xml` with
an `SdkLogEmitterProvider` in your application:
Next, configure `GlobalLoggerProvider` with an `SdkLoggerProvider` in your application.
```
SdkLogEmitterProvider logEmitterProvider =
SdkLogEmitterProvider.builder()
SdkLoggerProvider sdkLoggerProvider =
SdkLoggerProvider.builder()
.setResource(Resource.create(...))
.addLogProcessor(...)
.build();
OpenTelemetryAppender.setSdkLogEmitterProvider(logEmitterProvider);
GlobalLoggerProvider.set(sdkLoggerProvider);
```
In this example Log4j2 log events will be sent to both the console appender and
the `OpenTelemetryAppender`, which will drop the logs until
`OpenTelemetryAppender.setSdkLogEmitterProvider(..)` is called. Once initialized, logs will be
emitted to a `LogEmitter` obtained from the `SdkLogEmitterProvider`.
the `OpenTelemetryAppender`, which will drop the logs until `GlobalLoggerProvider.set(..)` is
called. Once initialized, logs will be emitted to a `Logger` obtained from the `SdkLoggerProvider`.

View File

@ -3,12 +3,10 @@ plugins {
}
dependencies {
implementation(project(":instrumentation-appender-api-internal"))
implementation(project(":instrumentation-appender-sdk-internal"))
implementation("io.opentelemetry:opentelemetry-api-logs")
library("org.apache.logging.log4j:log4j-core:2.17.0")
testImplementation(project(":instrumentation-appender-sdk-internal"))
testImplementation("io.opentelemetry:opentelemetry-sdk-logs")
testImplementation("io.opentelemetry:opentelemetry-sdk-testing")
}

View File

@ -7,13 +7,10 @@ package io.opentelemetry.instrumentation.log4j.appender.v2_17;
import static java.util.Collections.emptyList;
import io.opentelemetry.instrumentation.api.appender.internal.LogEmitterProvider;
import io.opentelemetry.instrumentation.api.appender.internal.LogEmitterProviderHolder;
import io.opentelemetry.instrumentation.api.appender.internal.LogRecordBuilder;
import io.opentelemetry.api.logs.GlobalLoggerProvider;
import io.opentelemetry.api.logs.LogRecordBuilder;
import io.opentelemetry.instrumentation.log4j.appender.v2_17.internal.ContextDataAccessor;
import io.opentelemetry.instrumentation.log4j.appender.v2_17.internal.LogEventMapper;
import io.opentelemetry.instrumentation.sdk.appender.internal.DelegatingLogEmitterProvider;
import io.opentelemetry.sdk.logs.SdkLogEmitterProvider;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
@ -44,9 +41,6 @@ public class OpenTelemetryAppender extends AbstractAppender {
static final String PLUGIN_NAME = "OpenTelemetry";
private static final LogEmitterProviderHolder logEmitterProviderHolder =
new LogEmitterProviderHolder();
private final LogEventMapper<ReadOnlyStringMap> mapper;
@PluginBuilderFactory
@ -147,7 +141,7 @@ public class OpenTelemetryAppender extends AbstractAppender {
instrumentationName = "ROOT";
}
LogRecordBuilder builder =
logEmitterProviderHolder.get().logEmitterBuilder(instrumentationName).build().logBuilder();
GlobalLoggerProvider.get().loggerBuilder(instrumentationName).build().logRecordBuilder();
ReadOnlyStringMap contextData = event.getContextData();
mapper.mapLogEvent(
builder,
@ -167,25 +161,6 @@ public class OpenTelemetryAppender extends AbstractAppender {
builder.emit();
}
/**
* This should be called once as early as possible in your application initialization logic, often
* in a {@code static} block in your main class. It should only be called once - an attempt to
* call it a second time will result in an error. If trying to set the {@link
* SdkLogEmitterProvider} multiple times in tests, use {@link
* OpenTelemetryAppender#resetSdkLogEmitterProviderForTest()} between them.
*/
public static void setSdkLogEmitterProvider(SdkLogEmitterProvider sdkLogEmitterProvider) {
logEmitterProviderHolder.set(DelegatingLogEmitterProvider.from(sdkLogEmitterProvider));
}
/**
* Unsets the global {@link LogEmitterProvider}. This is only meant to be used from tests which
* need to reconfigure {@link LogEmitterProvider}.
*/
public static void resetSdkLogEmitterProviderForTest() {
logEmitterProviderHolder.resetForTest();
}
private enum ContextDataAccessorImpl implements ContextDataAccessor<ReadOnlyStringMap> {
INSTANCE;

View File

@ -8,9 +8,9 @@ package io.opentelemetry.instrumentation.log4j.appender.v2_17.internal;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.logs.LogRecordBuilder;
import io.opentelemetry.api.logs.Severity;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.appender.internal.LogRecordBuilder;
import io.opentelemetry.instrumentation.api.appender.internal.Severity;
import io.opentelemetry.instrumentation.api.internal.cache.Cache;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.io.PrintWriter;
@ -183,7 +183,7 @@ public final class LogEventMapper<T> {
private static void setThrowable(AttributesBuilder attributes, Throwable throwable) {
// TODO (trask) extract method for recording exception into
// instrumentation-appender-api-internal
// io.opentelemetry:opentelemetry-api-logs
attributes.put(SemanticAttributes.EXCEPTION_TYPE, throwable.getClass().getName());
attributes.put(SemanticAttributes.EXCEPTION_MESSAGE, throwable.getMessage());
StringWriter writer = new StringWriter();

View File

@ -9,15 +9,16 @@ import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.logs.GlobalLoggerProvider;
import io.opentelemetry.api.logs.Severity;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanContext;
import io.opentelemetry.context.Scope;
import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
import io.opentelemetry.sdk.logs.SdkLogEmitterProvider;
import io.opentelemetry.sdk.logs.data.LogData;
import io.opentelemetry.sdk.logs.data.Severity;
import io.opentelemetry.sdk.logs.export.InMemoryLogExporter;
import io.opentelemetry.sdk.logs.export.SimpleLogProcessor;
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
import io.opentelemetry.sdk.logs.data.LogRecordData;
import io.opentelemetry.sdk.logs.export.InMemoryLogRecordExporter;
import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
@ -39,29 +40,29 @@ class OpenTelemetryAppenderConfigTest {
private static final Logger logger = LogManager.getLogger("TestLogger");
private static InMemoryLogExporter logExporter;
private static InMemoryLogRecordExporter logRecordExporter;
private static Resource resource;
private static InstrumentationScopeInfo instrumentationScopeInfo;
@BeforeAll
static void setupAll() {
logExporter = InMemoryLogExporter.create();
logRecordExporter = InMemoryLogRecordExporter.create();
resource = Resource.getDefault();
instrumentationScopeInfo = InstrumentationScopeInfo.create("TestLogger");
SdkLogEmitterProvider logEmitterProvider =
SdkLogEmitterProvider.builder()
SdkLoggerProvider loggerProvider =
SdkLoggerProvider.builder()
.setResource(resource)
.addLogProcessor(SimpleLogProcessor.create(logExporter))
.addLogRecordProcessor(SimpleLogRecordProcessor.create(logRecordExporter))
.build();
OpenTelemetryAppender.resetSdkLogEmitterProviderForTest();
OpenTelemetryAppender.setSdkLogEmitterProvider(logEmitterProvider);
GlobalLoggerProvider.resetForTest();
GlobalLoggerProvider.set(loggerProvider);
}
@BeforeEach
void setup() {
logExporter.reset();
logRecordExporter.reset();
ThreadContext.clearAll();
}
@ -69,9 +70,9 @@ class OpenTelemetryAppenderConfigTest {
void logNoSpan() {
logger.info("log message 1");
List<LogData> logDataList = logExporter.getFinishedLogItems();
List<LogRecordData> logDataList = logRecordExporter.getFinishedLogItems();
assertThat(logDataList).hasSize(1);
LogData logData = logDataList.get(0);
LogRecordData logData = logDataList.get(0);
assertThat(logData.getResource()).isEqualTo(resource);
assertThat(logData.getInstrumentationScopeInfo()).isEqualTo(instrumentationScopeInfo);
assertThat(logData.getBody().asString()).isEqualTo("log message 1");
@ -86,7 +87,7 @@ class OpenTelemetryAppenderConfigTest {
Span span2 = runWithSpan("span2", () -> logger.info("log message 3"));
List<LogData> logDataList = logExporter.getFinishedLogItems();
List<LogRecordData> logDataList = logRecordExporter.getFinishedLogItems();
assertThat(logDataList).hasSize(3);
assertThat(logDataList.get(0).getSpanContext()).isEqualTo(span1.getSpanContext());
assertThat(logDataList.get(1).getSpanContext()).isEqualTo(SpanContext.getInvalid());
@ -108,9 +109,9 @@ class OpenTelemetryAppenderConfigTest {
Instant start = Instant.now();
logger.info("log message 1", new IllegalStateException("Error!"));
List<LogData> logDataList = logExporter.getFinishedLogItems();
List<LogRecordData> logDataList = logRecordExporter.getFinishedLogItems();
assertThat(logDataList).hasSize(1);
LogData logData = logDataList.get(0);
LogRecordData logData = logDataList.get(0);
assertThat(logData.getResource()).isEqualTo(resource);
assertThat(logData.getInstrumentationScopeInfo()).isEqualTo(instrumentationScopeInfo);
assertThat(logData.getBody().asString()).isEqualTo("log message 1");
@ -138,9 +139,9 @@ class OpenTelemetryAppenderConfigTest {
ThreadContext.clearMap();
}
List<LogData> logDataList = logExporter.getFinishedLogItems();
List<LogRecordData> logDataList = logRecordExporter.getFinishedLogItems();
assertThat(logDataList).hasSize(1);
LogData logData = logDataList.get(0);
LogRecordData logData = logDataList.get(0);
assertThat(logData.getResource()).isEqualTo(resource);
assertThat(logData.getInstrumentationScopeInfo()).isEqualTo(instrumentationScopeInfo);
assertThat(logData.getBody().asString()).isEqualTo("log message 1");
@ -158,9 +159,9 @@ class OpenTelemetryAppenderConfigTest {
message.put("key2", "val2");
logger.info(message);
List<LogData> logDataList = logExporter.getFinishedLogItems();
List<LogRecordData> logDataList = logRecordExporter.getFinishedLogItems();
assertThat(logDataList).hasSize(1);
LogData logData = logDataList.get(0);
LogRecordData logData = logDataList.get(0);
assertThat(logData.getResource()).isEqualTo(resource);
assertThat(logData.getInstrumentationScopeInfo()).isEqualTo(instrumentationScopeInfo);
assertThat(logData.getBody().asString()).isEmpty();
@ -176,9 +177,9 @@ class OpenTelemetryAppenderConfigTest {
message.put("message", "val2");
logger.info(message);
List<LogData> logDataList = logExporter.getFinishedLogItems();
List<LogRecordData> logDataList = logRecordExporter.getFinishedLogItems();
assertThat(logDataList).hasSize(1);
LogData logData = logDataList.get(0);
LogRecordData logData = logDataList.get(0);
assertThat(logData.getResource()).isEqualTo(resource);
assertThat(logData.getInstrumentationScopeInfo()).isEqualTo(instrumentationScopeInfo);
assertThat(logData.getBody().asString()).isEqualTo("val2");
@ -193,8 +194,8 @@ class OpenTelemetryAppenderConfigTest {
logger.info(marker, "Message");
List<LogData> logDataList = logExporter.getFinishedLogItems();
LogData logData = logDataList.get(0);
List<LogRecordData> logDataList = logRecordExporter.getFinishedLogItems();
LogRecordData logData = logDataList.get(0);
assertThat(logData.getAttributes().get(AttributeKey.stringKey("log4j.marker")))
.isEqualTo(markerName);
}
@ -206,9 +207,9 @@ class OpenTelemetryAppenderConfigTest {
message.put("key2", "val2");
logger.info(message);
List<LogData> logDataList = logExporter.getFinishedLogItems();
List<LogRecordData> logDataList = logRecordExporter.getFinishedLogItems();
assertThat(logDataList).hasSize(1);
LogData logData = logDataList.get(0);
LogRecordData logData = logDataList.get(0);
assertThat(logData.getResource()).isEqualTo(resource);
assertThat(logData.getInstrumentationScopeInfo()).isEqualTo(instrumentationScopeInfo);
assertThat(logData.getBody().asString()).isEqualTo("a message");

View File

@ -17,7 +17,7 @@ import static org.mockito.Mockito.verify;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.instrumentation.api.appender.internal.LogRecordBuilder;
import io.opentelemetry.api.logs.LogRecordBuilder;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;

View File

@ -42,7 +42,7 @@ dependencies {
}
}
compileOnly(project(":instrumentation-appender-api-internal"))
compileOnly("io.opentelemetry:opentelemetry-api-logs")
compileOnly(project(":javaagent-bootstrap"))
implementation(project(":instrumentation:logback:logback-appender-1.0:library"))

View File

@ -13,8 +13,8 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import ch.qos.logback.classic.spi.ILoggingEvent;
import io.opentelemetry.instrumentation.api.appender.internal.LogEmitterProvider;
import io.opentelemetry.javaagent.bootstrap.AgentLogEmitterProvider;
import io.opentelemetry.api.logs.GlobalLoggerProvider;
import io.opentelemetry.api.logs.LoggerProvider;
import io.opentelemetry.javaagent.bootstrap.CallDepth;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
@ -49,9 +49,9 @@ class LogbackInstrumentation implements TypeInstrumentation {
@Advice.Local("otelCallDepth") CallDepth callDepth) {
// need to track call depth across all loggers in order to avoid double capture when one
// logging framework delegates to another
callDepth = CallDepth.forClass(LogEmitterProvider.class);
callDepth = CallDepth.forClass(LoggerProvider.class);
if (callDepth.getAndIncrement() == 0) {
mapper().emit(AgentLogEmitterProvider.get(), event);
mapper().emit(GlobalLoggerProvider.get(), event);
}
}

View File

@ -10,12 +10,12 @@ import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.asser
import static org.awaitility.Awaitility.await;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.logs.Severity;
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification;
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
import io.opentelemetry.sdk.logs.data.LogData;
import io.opentelemetry.sdk.logs.data.Severity;
import io.opentelemetry.sdk.logs.data.LogRecordData;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
@ -134,9 +134,9 @@ class LogbackTest extends AgentInstrumentationSpecification {
}
if (expectedSeverity != null) {
await().untilAsserted(() -> assertThat(testing.logs().size()).isEqualTo(1));
await().untilAsserted(() -> assertThat(testing.logRecords().size()).isEqualTo(1));
LogData log = testing.logs().get(0);
LogRecordData log = testing.logRecords().get(0);
assertThat(log)
.hasBody("xyz: 123")
// TODO (trask) why is version "" instead of null?
@ -182,7 +182,7 @@ class LogbackTest extends AgentInstrumentationSpecification {
} else {
Thread.sleep(500); // sleep a bit just to make sure no log is captured
assertThat(testing.logs()).isEmpty();
assertThat(testing.logRecords()).isEmpty();
}
}
@ -196,9 +196,9 @@ class LogbackTest extends AgentInstrumentationSpecification {
MDC.clear();
}
await().untilAsserted(() -> assertThat(testing.logs().size()).isEqualTo(1));
await().untilAsserted(() -> assertThat(testing.logRecords().size()).isEqualTo(1));
LogData log = getLogs().get(0);
LogRecordData log = getLogRecords().get(0);
assertThat(log)
.hasBody("xyz: 123")
// TODO (trask) why is version "" instead of null?
@ -229,9 +229,9 @@ class LogbackTest extends AgentInstrumentationSpecification {
abcLogger.info(marker, "Message");
await().untilAsserted(() -> assertThat(testing.logs().size()).isEqualTo(1));
await().untilAsserted(() -> assertThat(testing.logRecords().size()).isEqualTo(1));
LogData log = getLogs().get(0);
LogRecordData log = getLogRecords().get(0);
assertThat(log)
.hasAttributesSatisfying(

View File

@ -54,19 +54,17 @@ The following demonstrates how you might configure the appender in your `logback
</configuration>
```
Next, associate the `OpenTelemetryAppender` configured via `logback.xml` with
an `SdkLogEmitterProvider` in your application:
Next, configure `GlobalLoggerProvider` with an `SdkLoggerProvider` in your application.
```
SdkLogEmitterProvider logEmitterProvider =
SdkLogEmitterProvider.builder()
SdkLoggerProvider sdkLoggerProvider =
SdkLoggerProvider.builder()
.setResource(Resource.create(...))
.addLogProcessor(...)
.build();
OpenTelemetryAppender.setSdkLogEmitterProvider(logEmitterProvider);
GlobalLoggerProvider.set(sdkLoggerProvider);
```
In this example Logback log events will be sent to both the console appender and
the `OpenTelemetryAppender`, which will drop the logs until
`OpenTelemetryAppender.setSdkLogEmitterProvider(..)` is called. Once initialized, logs will be
emitted to a `LogEmitter` obtained from the `SdkLogEmitterProvider`.
the `OpenTelemetryAppender`, which will drop the logs until `GlobalLoggerProvider.set(..)` is
called. Once initialized, logs will be emitted to a `Logger` obtained from the `SdkLoggerProvider`.

View File

@ -3,8 +3,7 @@ plugins {
}
dependencies {
implementation(project(":instrumentation-appender-api-internal"))
implementation(project(":instrumentation-appender-sdk-internal"))
implementation("io.opentelemetry:opentelemetry-api-logs")
// pin the version strictly to avoid overriding by dependencyManagement versions
compileOnly("ch.qos.logback:logback-classic") {

View File

@ -9,11 +9,8 @@ import static java.util.Collections.emptyList;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.UnsynchronizedAppenderBase;
import io.opentelemetry.instrumentation.api.appender.internal.LogEmitterProvider;
import io.opentelemetry.instrumentation.api.appender.internal.LogEmitterProviderHolder;
import io.opentelemetry.api.logs.GlobalLoggerProvider;
import io.opentelemetry.instrumentation.logback.appender.v1_0.internal.LoggingEventMapper;
import io.opentelemetry.instrumentation.sdk.appender.internal.DelegatingLogEmitterProvider;
import io.opentelemetry.sdk.logs.SdkLogEmitterProvider;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@ -21,9 +18,6 @@ import org.slf4j.MDC;
public class OpenTelemetryAppender extends UnsynchronizedAppenderBase<ILoggingEvent> {
private static final LogEmitterProviderHolder logEmitterProviderHolder =
new LogEmitterProviderHolder();
private volatile boolean captureExperimentalAttributes = false;
private volatile boolean captureCodeAttributes = false;
private volatile boolean captureMarkerAttribute = false;
@ -46,18 +40,7 @@ public class OpenTelemetryAppender extends UnsynchronizedAppenderBase<ILoggingEv
@Override
protected void append(ILoggingEvent event) {
mapper.emit(logEmitterProviderHolder.get(), event);
}
/**
* This should be called once as early as possible in your application initialization logic, often
* in a {@code static} block in your main class. It should only be called once - an attempt to
* call it a second time will result in an error. If trying to set the {@link
* SdkLogEmitterProvider} multiple times in tests, use {@link
* OpenTelemetryAppender#resetSdkLogEmitterProviderForTest()} between them.
*/
public static void setSdkLogEmitterProvider(SdkLogEmitterProvider sdkLogEmitterProvider) {
logEmitterProviderHolder.set(DelegatingLogEmitterProvider.from(sdkLogEmitterProvider));
mapper.emit(GlobalLoggerProvider.get(), event);
}
/**
@ -99,14 +82,6 @@ public class OpenTelemetryAppender extends UnsynchronizedAppenderBase<ILoggingEv
}
}
/**
* Unsets the global {@link LogEmitterProvider}. This is only meant to be used from tests which
* need to reconfigure {@link LogEmitterProvider}.
*/
public static void resetSdkLogEmitterProviderForTest() {
logEmitterProviderHolder.resetForTest();
}
// copied from SDK's DefaultConfigProperties
private static List<String> filterBlanksAndNulls(String[] values) {
return Arrays.stream(values)

View File

@ -11,10 +11,10 @@ import ch.qos.logback.classic.spi.ThrowableProxy;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.logs.LogRecordBuilder;
import io.opentelemetry.api.logs.LoggerProvider;
import io.opentelemetry.api.logs.Severity;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.appender.internal.LogEmitterProvider;
import io.opentelemetry.instrumentation.api.appender.internal.LogRecordBuilder;
import io.opentelemetry.instrumentation.api.appender.internal.Severity;
import io.opentelemetry.instrumentation.api.internal.cache.Cache;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.io.PrintWriter;
@ -53,13 +53,13 @@ public final class LoggingEventMapper {
captureMdcAttributes.size() == 1 && captureMdcAttributes.get(0).equals("*");
}
public void emit(LogEmitterProvider logEmitterProvider, ILoggingEvent event) {
public void emit(LoggerProvider loggerProvider, ILoggingEvent event) {
String instrumentationName = event.getLoggerName();
if (instrumentationName == null || instrumentationName.isEmpty()) {
instrumentationName = "ROOT";
}
LogRecordBuilder builder =
logEmitterProvider.logEmitterBuilder(instrumentationName).build().logBuilder();
loggerProvider.loggerBuilder(instrumentationName).build().logRecordBuilder();
mapLoggingEvent(builder, event);
builder.emit();
}
@ -169,7 +169,7 @@ public final class LoggingEventMapper {
private static void setThrowable(AttributesBuilder attributes, Throwable throwable) {
// TODO (trask) extract method for recording exception into
// instrumentation-appender-api-internal
// io.opentelemetry:opentelemetry-api-logs
attributes.put(SemanticAttributes.EXCEPTION_TYPE, throwable.getClass().getName());
attributes.put(SemanticAttributes.EXCEPTION_MESSAGE, throwable.getMessage());
StringWriter writer = new StringWriter();

View File

@ -8,15 +8,16 @@ package io.opentelemetry.instrumentation.logback.appender.v1_0;
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.logs.GlobalLoggerProvider;
import io.opentelemetry.api.logs.Severity;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanContext;
import io.opentelemetry.context.Scope;
import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
import io.opentelemetry.sdk.logs.SdkLogEmitterProvider;
import io.opentelemetry.sdk.logs.data.LogData;
import io.opentelemetry.sdk.logs.data.Severity;
import io.opentelemetry.sdk.logs.export.InMemoryLogExporter;
import io.opentelemetry.sdk.logs.export.SimpleLogProcessor;
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
import io.opentelemetry.sdk.logs.data.LogRecordData;
import io.opentelemetry.sdk.logs.export.InMemoryLogRecordExporter;
import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
@ -37,38 +38,38 @@ class OpenTelemetryAppenderConfigTest {
private static final Logger logger = LoggerFactory.getLogger("TestLogger");
private static InMemoryLogExporter logExporter;
private static InMemoryLogRecordExporter logRecordExporter;
private static Resource resource;
private static InstrumentationScopeInfo instrumentationScopeInfo;
@BeforeAll
static void setupAll() {
logExporter = InMemoryLogExporter.create();
logRecordExporter = InMemoryLogRecordExporter.create();
resource = Resource.getDefault();
instrumentationScopeInfo = InstrumentationScopeInfo.create("TestLogger");
SdkLogEmitterProvider logEmitterProvider =
SdkLogEmitterProvider.builder()
SdkLoggerProvider loggerProvider =
SdkLoggerProvider.builder()
.setResource(resource)
.addLogProcessor(SimpleLogProcessor.create(logExporter))
.addLogRecordProcessor(SimpleLogRecordProcessor.create(logRecordExporter))
.build();
OpenTelemetryAppender.resetSdkLogEmitterProviderForTest();
OpenTelemetryAppender.setSdkLogEmitterProvider(logEmitterProvider);
GlobalLoggerProvider.resetForTest();
GlobalLoggerProvider.set(loggerProvider);
}
@BeforeEach
void setup() {
logExporter.reset();
logRecordExporter.reset();
}
@Test
void logNoSpan() {
logger.info("log message 1");
List<LogData> logDataList = logExporter.getFinishedLogItems();
List<LogRecordData> logDataList = logRecordExporter.getFinishedLogItems();
assertThat(logDataList).hasSize(1);
LogData logData = logDataList.get(0);
LogRecordData logData = logDataList.get(0);
assertThat(logData.getResource()).isEqualTo(resource);
assertThat(logData.getInstrumentationScopeInfo()).isEqualTo(instrumentationScopeInfo);
assertThat(logData.getBody().asString()).isEqualTo("log message 1");
@ -83,7 +84,7 @@ class OpenTelemetryAppenderConfigTest {
Span span2 = runWithSpan("span2", () -> logger.info("log message 3"));
List<LogData> logDataList = logExporter.getFinishedLogItems();
List<LogRecordData> logDataList = logRecordExporter.getFinishedLogItems();
assertThat(logDataList).hasSize(3);
assertThat(logDataList.get(0).getSpanContext()).isEqualTo(span1.getSpanContext());
assertThat(logDataList.get(1).getSpanContext()).isEqualTo(SpanContext.getInvalid());
@ -107,9 +108,9 @@ class OpenTelemetryAppenderConfigTest {
Marker marker = MarkerFactory.getMarker(markerName);
logger.info(marker, "log message 1", new IllegalStateException("Error!"));
List<LogData> logDataList = logExporter.getFinishedLogItems();
List<LogRecordData> logDataList = logRecordExporter.getFinishedLogItems();
assertThat(logDataList).hasSize(1);
LogData logData = logDataList.get(0);
LogRecordData logData = logDataList.get(0);
assertThat(logData.getResource()).isEqualTo(resource);
assertThat(logData.getInstrumentationScopeInfo()).isEqualTo(instrumentationScopeInfo);
assertThat(logData.getBody().asString()).isEqualTo("log message 1");
@ -155,9 +156,9 @@ class OpenTelemetryAppenderConfigTest {
MDC.clear();
}
List<LogData> logDataList = logExporter.getFinishedLogItems();
List<LogRecordData> logDataList = logRecordExporter.getFinishedLogItems();
assertThat(logDataList).hasSize(1);
LogData logData = logDataList.get(0);
LogRecordData logData = logDataList.get(0);
assertThat(logData.getResource()).isEqualTo(resource);
assertThat(logData.getInstrumentationScopeInfo()).isEqualTo(instrumentationScopeInfo);
assertThat(logData.getBody().asString()).isEqualTo("log message 1");

View File

@ -0,0 +1,29 @@
plugins {
id("otel.javaagent-instrumentation")
}
dependencies {
// this instrumentation needs to be able to reference both the OpenTelemetry API
// that is shaded in the bootstrap class loader (for sending telemetry to the agent),
// and the OpenTelemetry API that the user brings (in order to capture that telemetry)
//
// since (all) instrumentation already uses OpenTelemetry API for sending telemetry to the agent,
// this instrumentation uses a "temporarily shaded" OpenTelemetry API to represent the
// OpenTelemetry API that the user brings
//
// then later, after the OpenTelemetry API in the bootstrap class loader is shaded,
// the "temporarily shaded" OpenTelemetry API is unshaded, so that it will apply to the
// OpenTelemetry API that the user brings
//
// so in the code "application.io.opentelemetry.*" refers to the (unshaded) OpenTelemetry API that
// the application brings (as those references will be translated during the build to remove the
// "application." prefix)
//
// and in the code "io.opentelemetry.*" refers to the (shaded) OpenTelemetry API that is used by
// the agent (as those references will later be shaded)
compileOnly("io.opentelemetry:opentelemetry-api-logs")
compileOnly(project(":opentelemetry-api-shaded-for-instrumenting", configuration = "shadow"))
implementation(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.0:javaagent"))
testImplementation("io.opentelemetry:opentelemetry-sdk-logs")
}

View File

@ -0,0 +1,24 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.logs;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import java.util.Collections;
import java.util.List;
@AutoService(InstrumentationModule.class)
public class OpenTelemetryApiLogsInstrumentationModule extends InstrumentationModule {
public OpenTelemetryApiLogsInstrumentationModule() {
super("opentelemetry-api-logs");
}
@Override
public List<TypeInstrumentation> typeInstrumentations() {
return Collections.singletonList(new OpenTelemetryLogsInstrumentation());
}
}

View File

@ -0,0 +1,51 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.logs;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.isStatic;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.logs.bridge.ApplicationLoggerProvider;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
// Our convention for accessing agent package
@SuppressWarnings("UnnecessarilyFullyQualified")
public class OpenTelemetryLogsInstrumentation implements TypeInstrumentation {
@Override
public ElementMatcher<TypeDescription> typeMatcher() {
return named("application.io.opentelemetry.api.logs.GlobalLoggerProvider");
}
@Override
public void transform(TypeTransformer transformer) {
transformer.applyAdviceToMethod(
isMethod().and(isStatic()).and(named("get")).and(takesArguments(0)),
OpenTelemetryLogsInstrumentation.class.getName() + "$GetGlobalLogsAdvice");
}
@SuppressWarnings("unused")
public static class GetGlobalLogsAdvice {
@Advice.OnMethodEnter(skipOn = Advice.OnDefaultValue.class)
public static Object onEnter() {
return null;
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void methodExit(
@Advice.Return(readOnly = false)
application.io.opentelemetry.api.logs.LoggerProvider loggerProvider) {
loggerProvider = ApplicationLoggerProvider.INSTANCE;
}
}
}

View File

@ -0,0 +1,84 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.logs.bridge;
import application.io.opentelemetry.api.common.AttributeKey;
import application.io.opentelemetry.api.logs.EventBuilder;
import application.io.opentelemetry.api.logs.LogRecordBuilder;
import application.io.opentelemetry.api.logs.Severity;
import application.io.opentelemetry.context.Context;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.context.AgentContextStorage;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.trace.Bridging;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
class ApplicationLogRecordBuilder implements EventBuilder {
private final io.opentelemetry.api.logs.LogRecordBuilder agentLogRecordBuilder;
ApplicationLogRecordBuilder(io.opentelemetry.api.logs.LogRecordBuilder agentLogRecordBuilder) {
this.agentLogRecordBuilder = agentLogRecordBuilder;
}
@Override
@CanIgnoreReturnValue
public LogRecordBuilder setEpoch(long l, TimeUnit timeUnit) {
agentLogRecordBuilder.setEpoch(l, timeUnit);
return this;
}
@Override
@CanIgnoreReturnValue
public LogRecordBuilder setEpoch(Instant instant) {
agentLogRecordBuilder.setEpoch(instant);
return this;
}
@Override
@CanIgnoreReturnValue
public LogRecordBuilder setContext(Context context) {
agentLogRecordBuilder.setContext(AgentContextStorage.getAgentContext(context));
return this;
}
@Override
@CanIgnoreReturnValue
public LogRecordBuilder setSeverity(Severity severity) {
agentLogRecordBuilder.setSeverity(LogBridging.toAgent(severity));
return this;
}
@Override
@CanIgnoreReturnValue
public LogRecordBuilder setSeverityText(String s) {
agentLogRecordBuilder.setSeverityText(s);
return this;
}
@Override
@CanIgnoreReturnValue
public LogRecordBuilder setBody(String s) {
agentLogRecordBuilder.setBody(s);
return this;
}
@Override
@CanIgnoreReturnValue
public <T> LogRecordBuilder setAttribute(AttributeKey<T> attributeKey, T t) {
@SuppressWarnings("unchecked")
io.opentelemetry.api.common.AttributeKey<T> agentKey = Bridging.toAgent(attributeKey);
if (agentKey != null) {
agentLogRecordBuilder.setAttribute(agentKey, t);
}
return this;
}
@Override
public void emit() {
agentLogRecordBuilder.emit();
}
}

View File

@ -0,0 +1,29 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.logs.bridge;
import application.io.opentelemetry.api.logs.EventBuilder;
import application.io.opentelemetry.api.logs.LogRecordBuilder;
import application.io.opentelemetry.api.logs.Logger;
class ApplicationLogger implements Logger {
private final io.opentelemetry.api.logs.Logger agentLogger;
ApplicationLogger(io.opentelemetry.api.logs.Logger agentLogger) {
this.agentLogger = agentLogger;
}
@Override
public EventBuilder eventBuilder(String eventName) {
return new ApplicationLogRecordBuilder(agentLogger.eventBuilder(eventName));
}
@Override
public LogRecordBuilder logRecordBuilder() {
return new ApplicationLogRecordBuilder(agentLogger.logRecordBuilder());
}
}

View File

@ -0,0 +1,45 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.logs.bridge;
import application.io.opentelemetry.api.logs.Logger;
import application.io.opentelemetry.api.logs.LoggerBuilder;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
final class ApplicationLoggerBuilder implements LoggerBuilder {
private final io.opentelemetry.api.logs.LoggerBuilder agentBuilder;
ApplicationLoggerBuilder(io.opentelemetry.api.logs.LoggerBuilder agentBuilder) {
this.agentBuilder = agentBuilder;
}
@Override
@CanIgnoreReturnValue
public LoggerBuilder setEventDomain(String eventDomain) {
agentBuilder.setEventDomain(eventDomain);
return this;
}
@Override
@CanIgnoreReturnValue
public LoggerBuilder setSchemaUrl(String schemaUrl) {
agentBuilder.setSchemaUrl(schemaUrl);
return this;
}
@Override
@CanIgnoreReturnValue
public LoggerBuilder setInstrumentationVersion(String version) {
agentBuilder.setInstrumentationVersion(version);
return this;
}
@Override
public Logger build() {
return new ApplicationLogger(agentBuilder.build());
}
}

View File

@ -0,0 +1,27 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.logs.bridge;
import application.io.opentelemetry.api.logs.LoggerBuilder;
import application.io.opentelemetry.api.logs.LoggerProvider;
// Our convention for accessing agent packages.
@SuppressWarnings("UnnecessarilyFullyQualified")
public class ApplicationLoggerProvider implements LoggerProvider {
public static final LoggerProvider INSTANCE = new ApplicationLoggerProvider();
private final io.opentelemetry.api.logs.LoggerProvider agentLoggerProvider;
public ApplicationLoggerProvider() {
this.agentLoggerProvider = io.opentelemetry.api.logs.GlobalLoggerProvider.get();
}
@Override
public LoggerBuilder loggerBuilder(String instrumentationName) {
return new ApplicationLoggerBuilder(agentLoggerProvider.loggerBuilder(instrumentationName));
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.logs.bridge;
import application.io.opentelemetry.api.logs.Severity;
import java.util.EnumMap;
/**
* This class translates between the (unshaded) OpenTelemetry API that the application brings and
* the (shaded) OpenTelemetry API that is used by the agent.
*
* <p>"application.io.opentelemetry.*" refers to the (unshaded) OpenTelemetry API that the
* application brings (as those references will be translated during the build to remove the
* "application." prefix).
*
* <p>"io.opentelemetry.*" refers to the (shaded) OpenTelemetry API that is used by the agent (as
* those references will later be shaded).
*
* <p>Also see comments in this module's gradle file.
*/
// Our convention for accessing agent package
@SuppressWarnings("UnnecessarilyFullyQualified")
public class LogBridging {
private static final EnumMap<Severity, io.opentelemetry.api.logs.Severity> severityMap;
static {
severityMap = new EnumMap<>(Severity.class);
for (Severity severity : Severity.values()) {
try {
severityMap.put(severity, io.opentelemetry.api.logs.Severity.valueOf(severity.name()));
} catch (IllegalArgumentException e) {
// No mapping exists for this severity, ignore
}
}
}
public static io.opentelemetry.api.logs.Severity toAgent(Severity applicationSeverity) {
return severityMap.getOrDefault(
applicationSeverity, io.opentelemetry.api.logs.Severity.UNDEFINED_SEVERITY_NUMBER);
}
private LogBridging() {}
}

View File

@ -0,0 +1,89 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.logs;
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.logs.GlobalLoggerProvider;
import io.opentelemetry.api.logs.Logger;
import io.opentelemetry.api.logs.Severity;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanContext;
import io.opentelemetry.api.trace.TraceFlags;
import io.opentelemetry.api.trace.TraceState;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
import io.opentelemetry.sdk.trace.IdGenerator;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.extension.RegisterExtension;
class LoggerTest {
@RegisterExtension
static final AgentInstrumentationExtension testing = AgentInstrumentationExtension.create();
private String instrumentationName;
private Logger logger;
@BeforeEach
void setupLogger(TestInfo test) {
instrumentationName = "test-" + test.getDisplayName();
logger =
GlobalLoggerProvider.get()
.loggerBuilder(instrumentationName)
.setInstrumentationVersion("1.2.3")
.setSchemaUrl("http://schema.org")
.build();
}
@Test
void logRecordBuilder() {
SpanContext spanContext =
SpanContext.create(
IdGenerator.random().generateTraceId(),
IdGenerator.random().generateSpanId(),
TraceFlags.getDefault(),
TraceState.getDefault());
logger
.logRecordBuilder()
.setEpoch(1, TimeUnit.SECONDS)
.setEpoch(Instant.now())
.setContext(Context.current().with(Span.wrap(spanContext)))
.setSeverity(Severity.DEBUG)
.setSeverityText("debug")
.setBody("body")
.setAttribute(AttributeKey.stringKey("key"), "value")
.setAllAttributes(Attributes.builder().put("key", "value").build())
.emit();
await()
.untilAsserted(
() ->
assertThat(testing.logRecords())
.satisfiesExactly(
logRecordData -> {
assertThat(logRecordData.getInstrumentationScopeInfo().getName())
.isEqualTo(instrumentationName);
assertThat(logRecordData.getInstrumentationScopeInfo().getVersion())
.isEqualTo("1.2.3");
assertThat(logRecordData.getEpochNanos()).isGreaterThan(0);
assertThat(logRecordData.getSpanContext()).isEqualTo(spanContext);
assertThat(logRecordData.getSeverity()).isEqualTo(Severity.DEBUG);
assertThat(logRecordData.getSeverityText()).isEqualTo("debug");
assertThat(logRecordData.getBody().asString()).isEqualTo("body");
assertThat(logRecordData.getAttributes())
.isEqualTo(Attributes.builder().put("key", "value").build());
}));
}
}

View File

@ -32,13 +32,16 @@ dependencies {
compileOnly("io.opentelemetry:opentelemetry-extension-annotations")
compileOnly("io.opentelemetry:opentelemetry-extension-trace-propagators")
compileOnly("io.opentelemetry:opentelemetry-extension-aws")
compileOnly("io.opentelemetry:opentelemetry-sdk-extension-resources")
compileOnly("io.opentelemetry:opentelemetry-exporter-logging")
compileOnly("io.opentelemetry:opentelemetry-exporter-jaeger")
compileOnly("io.opentelemetry:opentelemetry-exporter-otlp")
compileOnly("io.opentelemetry:opentelemetry-exporter-zipkin")
compileOnly(project(":instrumentation-annotations"))
compileOnly(project(":instrumentation:resources:library"))
annotationProcessor("com.google.auto.service:auto-service")
compileOnly("com.google.auto.service:auto-service-annotations")
testImplementation("org.springframework.kafka:spring-kafka:2.9.0")
testImplementation("org.springframework.boot:spring-boot-starter-actuator:$springBootVersion")
testImplementation("org.springframework.boot:spring-boot-starter-aop:$springBootVersion")
@ -52,7 +55,7 @@ dependencies {
testImplementation(project(":testing-common"))
testImplementation("io.opentelemetry:opentelemetry-sdk")
testImplementation("io.opentelemetry:opentelemetry-sdk-testing")
testImplementation("io.opentelemetry:opentelemetry-sdk-extension-resources")
testImplementation(project(":instrumentation:resources:library"))
testImplementation("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi")
testImplementation("io.opentelemetry:opentelemetry-extension-annotations")
testImplementation("io.opentelemetry:opentelemetry-extension-trace-propagators")

View File

@ -5,18 +5,18 @@
package io.opentelemetry.instrumentation.spring.autoconfigure.resources;
import io.opentelemetry.instrumentation.resources.ContainerResource;
import io.opentelemetry.instrumentation.resources.ContainerResourceProvider;
import io.opentelemetry.instrumentation.resources.HostResource;
import io.opentelemetry.instrumentation.resources.HostResourceProvider;
import io.opentelemetry.instrumentation.resources.OsResource;
import io.opentelemetry.instrumentation.resources.OsResourceProvider;
import io.opentelemetry.instrumentation.resources.ProcessResource;
import io.opentelemetry.instrumentation.resources.ProcessResourceProvider;
import io.opentelemetry.instrumentation.resources.ProcessRuntimeResource;
import io.opentelemetry.instrumentation.resources.ProcessRuntimeResourceProvider;
import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.extension.resources.ContainerResource;
import io.opentelemetry.sdk.extension.resources.ContainerResourceProvider;
import io.opentelemetry.sdk.extension.resources.HostResource;
import io.opentelemetry.sdk.extension.resources.HostResourceProvider;
import io.opentelemetry.sdk.extension.resources.OsResource;
import io.opentelemetry.sdk.extension.resources.OsResourceProvider;
import io.opentelemetry.sdk.extension.resources.ProcessResource;
import io.opentelemetry.sdk.extension.resources.ProcessResourceProvider;
import io.opentelemetry.sdk.extension.resources.ProcessRuntimeResource;
import io.opentelemetry.sdk.extension.resources.ProcessRuntimeResourceProvider;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;

View File

@ -7,7 +7,6 @@ group = "io.opentelemetry.javaagent"
dependencies {
implementation(project(":instrumentation-api"))
implementation(project(":instrumentation-appender-api-internal"))
testImplementation(project(":testing-common"))
}

View File

@ -1,40 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.bootstrap;
import io.opentelemetry.instrumentation.api.appender.internal.LogEmitterProvider;
import io.opentelemetry.instrumentation.api.appender.internal.LogEmitterProviderHolder;
public final class AgentLogEmitterProvider {
private static final LogEmitterProviderHolder delegate = new LogEmitterProviderHolder();
/** Returns the registered global {@link LogEmitterProvider}. */
public static LogEmitterProvider get() {
return delegate.get();
}
/**
* Sets the {@link LogEmitterProvider} that should be used by the agent. Future calls to {@link
* #get()} will return the provided {@link LogEmitterProvider} instance. It should only be called
* once - an attempt to call it a second time will result in an error. If trying to set the
* instance {@link LogEmitterProvider} multiple times in tests, use {@link
* LogEmitterProviderHolder#resetForTest()} between them.
*/
public static void set(LogEmitterProvider logEmitterProvider) {
delegate.set(logEmitterProvider);
}
/**
* Unsets the {@link LogEmitterProvider}. This is only meant to be used from tests which need to
* reconfigure {@link LogEmitterProvider}.
*/
public static void resetForTest() {
delegate.resetForTest();
}
private AgentLogEmitterProvider() {}
}

View File

@ -14,11 +14,11 @@ dependencies {
implementation(project(":javaagent-tooling:javaagent-tooling-java9"))
implementation(project(":instrumentation-api"))
implementation(project(":instrumentation-annotations-support"))
implementation(project(":instrumentation-appender-api-internal"))
implementation(project(":instrumentation-appender-sdk-internal"))
implementation(project(":instrumentation:resources:library"))
implementation(project(":muzzle"))
implementation("io.opentelemetry:opentelemetry-api")
implementation("io.opentelemetry:opentelemetry-api-logs")
implementation("io.opentelemetry:opentelemetry-sdk")
implementation("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure")
implementation("io.opentelemetry:opentelemetry-sdk-metrics")
@ -26,7 +26,6 @@ dependencies {
implementation("io.opentelemetry:opentelemetry-extension-kotlin")
implementation("io.opentelemetry:opentelemetry-extension-aws")
implementation("io.opentelemetry:opentelemetry-extension-trace-propagators")
implementation("io.opentelemetry:opentelemetry-sdk-extension-resources")
// the incubator's ViewConfigCustomizer is used to support loading yaml-based metric views
implementation("io.opentelemetry:opentelemetry-sdk-extension-incubator")

View File

@ -5,16 +5,12 @@
package io.opentelemetry.javaagent.tooling;
import io.opentelemetry.instrumentation.api.appender.internal.LogEmitterProvider;
import io.opentelemetry.instrumentation.sdk.appender.internal.DelegatingLogEmitterProvider;
import io.opentelemetry.javaagent.bootstrap.AgentInitializer;
import io.opentelemetry.javaagent.bootstrap.AgentLogEmitterProvider;
import io.opentelemetry.javaagent.bootstrap.OpenTelemetrySdkAccess;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.logs.SdkLogEmitterProvider;
import java.util.Arrays;
public final class OpenTelemetryInstaller {
@ -42,16 +38,11 @@ public final class OpenTelemetryInstaller {
(timeout, unit) -> {
CompletableResultCode traceResult = sdk.getSdkTracerProvider().forceFlush();
CompletableResultCode metricsResult = sdk.getSdkMeterProvider().forceFlush();
CompletableResultCode.ofAll(Arrays.asList(traceResult, metricsResult))
CompletableResultCode logsResult = sdk.getSdkLoggerProvider().forceFlush();
CompletableResultCode.ofAll(Arrays.asList(traceResult, metricsResult, logsResult))
.join(timeout, unit);
});
SdkLogEmitterProvider sdkLogEmitterProvider =
autoConfiguredSdk.getOpenTelemetrySdk().getSdkLogEmitterProvider();
LogEmitterProvider logEmitterProvider =
DelegatingLogEmitterProvider.from(sdkLogEmitterProvider);
AgentLogEmitterProvider.set(logEmitterProvider);
return autoConfiguredSdk;
}

View File

@ -7,19 +7,19 @@ package io.opentelemetry.javaagent.tooling
import io.opentelemetry.api.GlobalOpenTelemetry
import io.opentelemetry.api.OpenTelemetry
import io.opentelemetry.javaagent.bootstrap.AgentLogEmitterProvider
import io.opentelemetry.api.logs.GlobalLoggerProvider
import spock.lang.Specification
class OpenTelemetryInstallerTest extends Specification {
void setup() {
GlobalOpenTelemetry.resetForTest()
AgentLogEmitterProvider.resetForTest()
GlobalLoggerProvider.resetForTest()
}
void cleanup() {
GlobalOpenTelemetry.resetForTest()
AgentLogEmitterProvider.resetForTest()
GlobalLoggerProvider.resetForTest()
}
def "should initialize GlobalOpenTelemetry"() {

View File

@ -10,6 +10,7 @@ import static java.util.Collections.singletonMap;
import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.logs.GlobalLoggerProvider;
import io.opentelemetry.javaagent.tooling.OpenTelemetryInstaller;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer;
@ -31,6 +32,7 @@ class ConfigurationFileLoaderTest {
@AfterAll
static void cleanUp() {
GlobalOpenTelemetry.resetForTest();
GlobalLoggerProvider.resetForTest();
}
// regression for https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/6696

View File

@ -34,6 +34,7 @@ val javaagentLibs by configurations.creating {
listOf(baseJavaagentLibs, javaagentLibs).forEach {
it.run {
exclude("io.opentelemetry", "opentelemetry-api")
exclude("io.opentelemetry", "opentelemetry-api-logs")
exclude("io.opentelemetry", "opentelemetry-semconv")
}
}
@ -44,9 +45,10 @@ val licenseReportDependencies by configurations.creating {
dependencies {
bootstrapLibs(project(":instrumentation-api"))
// opentelemetry-api is an api dependency of :instrumentation-api, but opentelemetry-api-logs is not
bootstrapLibs("io.opentelemetry:opentelemetry-api-logs")
bootstrapLibs(project(":instrumentation-api-semconv"))
bootstrapLibs(project(":instrumentation-annotations-support"))
bootstrapLibs(project(":instrumentation-appender-api-internal"))
bootstrapLibs(project(":javaagent-bootstrap"))
// extension-api contains both bootstrap packages and agent packages
@ -296,7 +298,6 @@ fun ShadowJar.excludeBootstrapClasses() {
exclude(project(":instrumentation-api"))
exclude(project(":instrumentation-api-semconv"))
exclude(project(":instrumentation-annotations-support"))
exclude(project(":instrumentation-appender-api-internal"))
exclude(project(":javaagent-bootstrap"))
}

58
licenses/licenses.md generated
View File

@ -1,7 +1,7 @@
#javaagent
##Dependency License Report
_2022-10-11 10:41:57 PDT_
_2022-10-11 13:01:17 PDT_
## Apache License, Version 2.0
**1** **Group:** `com.blogspot.mydailyjava` **Name:** `weak-lock-free` **Version:** `0.18`
@ -37,103 +37,103 @@ _2022-10-11 10:41:57 PDT_
> - **POM Project URL**: [https://github.com/square/okio/](https://github.com/square/okio/)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**7** **Group:** `io.opentelemetry` **Name:** `opentelemetry-api` **Version:** `1.18.0`
**7** **Group:** `io.opentelemetry` **Name:** `opentelemetry-api` **Version:** `1.19.0`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)
**8** **Group:** `io.opentelemetry` **Name:** `opentelemetry-context` **Version:** `1.18.0`
**8** **Group:** `io.opentelemetry` **Name:** `opentelemetry-api-logs` **Version:** `1.19.0-alpha`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)
**9** **Group:** `io.opentelemetry` **Name:** `opentelemetry-exporter-common` **Version:** `1.18.0`
**9** **Group:** `io.opentelemetry` **Name:** `opentelemetry-context` **Version:** `1.19.0`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)
**10** **Group:** `io.opentelemetry` **Name:** `opentelemetry-exporter-common` **Version:** `1.19.0`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**10** **Group:** `io.opentelemetry` **Name:** `opentelemetry-exporter-jaeger` **Version:** `1.18.0`
**11** **Group:** `io.opentelemetry` **Name:** `opentelemetry-exporter-jaeger` **Version:** `1.19.0`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**11** **Group:** `io.opentelemetry` **Name:** `opentelemetry-exporter-logging` **Version:** `1.18.0`
**12** **Group:** `io.opentelemetry` **Name:** `opentelemetry-exporter-logging` **Version:** `1.19.0`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**12** **Group:** `io.opentelemetry` **Name:** `opentelemetry-exporter-logging-otlp` **Version:** `1.18.0`
**13** **Group:** `io.opentelemetry` **Name:** `opentelemetry-exporter-logging-otlp` **Version:** `1.19.0`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**13** **Group:** `io.opentelemetry` **Name:** `opentelemetry-exporter-otlp` **Version:** `1.18.0`
**14** **Group:** `io.opentelemetry` **Name:** `opentelemetry-exporter-otlp` **Version:** `1.19.0`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**14** **Group:** `io.opentelemetry` **Name:** `opentelemetry-exporter-otlp-common` **Version:** `1.18.0`
**15** **Group:** `io.opentelemetry` **Name:** `opentelemetry-exporter-otlp-common` **Version:** `1.19.0`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**15** **Group:** `io.opentelemetry` **Name:** `opentelemetry-exporter-otlp-logs` **Version:** `1.18.0-alpha`
**16** **Group:** `io.opentelemetry` **Name:** `opentelemetry-exporter-otlp-logs` **Version:** `1.19.0-alpha`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**16** **Group:** `io.opentelemetry` **Name:** `opentelemetry-exporter-prometheus` **Version:** `1.18.0-alpha`
**17** **Group:** `io.opentelemetry` **Name:** `opentelemetry-exporter-prometheus` **Version:** `1.19.0-alpha`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**17** **Group:** `io.opentelemetry` **Name:** `opentelemetry-exporter-zipkin` **Version:** `1.18.0`
**18** **Group:** `io.opentelemetry` **Name:** `opentelemetry-exporter-zipkin` **Version:** `1.19.0`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**18** **Group:** `io.opentelemetry` **Name:** `opentelemetry-extension-aws` **Version:** `1.18.0`
**19** **Group:** `io.opentelemetry` **Name:** `opentelemetry-extension-aws` **Version:** `1.19.0`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**19** **Group:** `io.opentelemetry` **Name:** `opentelemetry-extension-kotlin` **Version:** `1.18.0`
**20** **Group:** `io.opentelemetry` **Name:** `opentelemetry-extension-kotlin` **Version:** `1.19.0`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**20** **Group:** `io.opentelemetry` **Name:** `opentelemetry-extension-trace-propagators` **Version:** `1.18.0`
**21** **Group:** `io.opentelemetry` **Name:** `opentelemetry-extension-trace-propagators` **Version:** `1.19.0`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**21** **Group:** `io.opentelemetry` **Name:** `opentelemetry-sdk` **Version:** `1.18.0`
**22** **Group:** `io.opentelemetry` **Name:** `opentelemetry-sdk` **Version:** `1.19.0`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**22** **Group:** `io.opentelemetry` **Name:** `opentelemetry-sdk-common` **Version:** `1.18.0`
**23** **Group:** `io.opentelemetry` **Name:** `opentelemetry-sdk-common` **Version:** `1.19.0`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**23** **Group:** `io.opentelemetry` **Name:** `opentelemetry-sdk-extension-autoconfigure` **Version:** `1.18.0-alpha`
**24** **Group:** `io.opentelemetry` **Name:** `opentelemetry-sdk-extension-autoconfigure` **Version:** `1.19.0-alpha`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**24** **Group:** `io.opentelemetry` **Name:** `opentelemetry-sdk-extension-autoconfigure-spi` **Version:** `1.18.0`
**25** **Group:** `io.opentelemetry` **Name:** `opentelemetry-sdk-extension-autoconfigure-spi` **Version:** `1.19.0`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**25** **Group:** `io.opentelemetry` **Name:** `opentelemetry-sdk-extension-incubator` **Version:** `1.18.0-alpha`
**26** **Group:** `io.opentelemetry` **Name:** `opentelemetry-sdk-extension-incubator` **Version:** `1.19.0-alpha`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**26** **Group:** `io.opentelemetry` **Name:** `opentelemetry-sdk-extension-jaeger-remote-sampler` **Version:** `1.18.0`
**27** **Group:** `io.opentelemetry` **Name:** `opentelemetry-sdk-extension-jaeger-remote-sampler` **Version:** `1.19.0`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**27** **Group:** `io.opentelemetry` **Name:** `opentelemetry-sdk-extension-resources` **Version:** `1.18.0`
**28** **Group:** `io.opentelemetry` **Name:** `opentelemetry-sdk-logs` **Version:** `1.19.0-alpha`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**28** **Group:** `io.opentelemetry` **Name:** `opentelemetry-sdk-logs` **Version:** `1.18.0-alpha`
**29** **Group:** `io.opentelemetry` **Name:** `opentelemetry-sdk-metrics` **Version:** `1.19.0`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**29** **Group:** `io.opentelemetry` **Name:** `opentelemetry-sdk-metrics` **Version:** `1.18.0`
**30** **Group:** `io.opentelemetry` **Name:** `opentelemetry-sdk-trace` **Version:** `1.19.0`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**30** **Group:** `io.opentelemetry` **Name:** `opentelemetry-sdk-trace` **Version:** `1.18.0`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
**31** **Group:** `io.opentelemetry` **Name:** `opentelemetry-semconv` **Version:** `1.18.0-alpha`
**31** **Group:** `io.opentelemetry` **Name:** `opentelemetry-semconv` **Version:** `1.19.0-alpha`
> - **POM Project URL**: [https://github.com/open-telemetry/opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java)
> - **POM License**: Apache License, Version 2.0 - [https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)

View File

@ -28,6 +28,7 @@ val v1_10 by configurations.creating {
dependencies {
latestDeps("io.opentelemetry:opentelemetry-api")
latestDeps("io.opentelemetry:opentelemetry-api-logs")
listOf("opentelemetry-api", "opentelemetry-context").forEach {
v1_10Deps("io.opentelemetry:$it") {

View File

@ -111,8 +111,6 @@ include(":bom")
include(":bom-alpha")
include(":instrumentation-api")
include(":instrumentation-api-semconv")
include(":instrumentation-appender-api-internal")
include(":instrumentation-appender-sdk-internal")
include(":instrumentation-annotations")
include(":instrumentation-annotations-support")
include(":instrumentation-annotations-support-testing")
@ -363,6 +361,7 @@ include(":instrumentation:okhttp:okhttp-3.0:testing")
include(":instrumentation:opentelemetry-api:opentelemetry-api-1.0:javaagent")
include(":instrumentation:opentelemetry-api:opentelemetry-api-1.4:javaagent")
include(":instrumentation:opentelemetry-api:opentelemetry-api-1.10:javaagent")
include(":instrumentation:opentelemetry-api:opentelemetry-api-logs-1.19:javaagent")
include(":instrumentation:opentelemetry-extension-annotations-1.0:javaagent")
include(":instrumentation:opentelemetry-instrumentation-annotations-1.16:javaagent")
include(":instrumentation:opentelemetry-instrumentation-api:javaagent")

View File

@ -15,7 +15,7 @@ import io.opentelemetry.instrumentation.testing.InstrumentationTestRunner
import io.opentelemetry.instrumentation.testing.util.ContextStorageCloser
import io.opentelemetry.instrumentation.testing.util.TelemetryDataUtil
import io.opentelemetry.instrumentation.testing.util.ThrowingSupplier
import io.opentelemetry.sdk.logs.data.LogData
import io.opentelemetry.sdk.logs.data.LogRecordData
import io.opentelemetry.sdk.metrics.data.MetricData
import io.opentelemetry.sdk.trace.data.SpanData
import org.junit.Rule
@ -72,8 +72,8 @@ abstract class InstrumentationSpecification extends Specification {
}
/** Return a list of all captured logs. */
List<LogData> getLogs() {
testRunner().getExportedLogs()
List<LogRecordData> getLogRecords() {
testRunner().getExportedLogRecords()
}
/**

View File

@ -12,7 +12,7 @@ import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.test.utils.LoggerUtils;
import io.opentelemetry.javaagent.testing.common.AgentTestingExporterAccess;
import io.opentelemetry.javaagent.testing.common.TestAgentListenerAccess;
import io.opentelemetry.sdk.logs.data.LogData;
import io.opentelemetry.sdk.logs.data.LogRecordData;
import io.opentelemetry.sdk.metrics.data.MetricData;
import io.opentelemetry.sdk.trace.data.SpanData;
import java.util.List;
@ -84,8 +84,8 @@ public final class AgentTestRunner extends InstrumentationTestRunner {
}
@Override
public List<LogData> getExportedLogs() {
return AgentTestingExporterAccess.getExportedLogs();
public List<LogRecordData> getExportedLogRecords() {
return AgentTestingExporterAccess.getExportedLogRecords();
}
@Override

View File

@ -11,7 +11,7 @@ import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.testing.util.TelemetryDataUtil;
import io.opentelemetry.instrumentation.testing.util.ThrowingRunnable;
import io.opentelemetry.instrumentation.testing.util.ThrowingSupplier;
import io.opentelemetry.sdk.logs.data.LogData;
import io.opentelemetry.sdk.logs.data.LogRecordData;
import io.opentelemetry.sdk.metrics.data.MetricData;
import io.opentelemetry.sdk.testing.assertj.TraceAssert;
import io.opentelemetry.sdk.testing.assertj.TracesAssert;
@ -53,7 +53,7 @@ public abstract class InstrumentationTestRunner {
public abstract List<MetricData> getExportedMetrics();
public abstract List<LogData> getExportedLogs();
public abstract List<LogRecordData> getExportedLogRecords();
public abstract boolean forceFlushCalled();

View File

@ -13,7 +13,7 @@ import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.exporter.logging.LoggingSpanExporter;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.logs.data.LogData;
import io.opentelemetry.sdk.logs.data.LogRecordData;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.metrics.data.AggregationTemporality;
import io.opentelemetry.sdk.metrics.data.MetricData;
@ -122,7 +122,7 @@ public final class LibraryTestRunner extends InstrumentationTestRunner {
}
@Override
public List<LogData> getExportedLogs() {
public List<LogRecordData> getExportedLogRecords() {
// no logs support yet
return Collections.emptyList();
}

View File

@ -16,7 +16,7 @@ import io.opentelemetry.instrumentation.testing.util.ContextStorageCloser;
import io.opentelemetry.instrumentation.testing.util.ThrowingRunnable;
import io.opentelemetry.instrumentation.testing.util.ThrowingSupplier;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.logs.data.LogData;
import io.opentelemetry.sdk.logs.data.LogRecordData;
import io.opentelemetry.sdk.metrics.data.MetricData;
import io.opentelemetry.sdk.testing.assertj.TraceAssert;
import io.opentelemetry.sdk.trace.data.SpanData;
@ -76,8 +76,8 @@ public abstract class InstrumentationExtension
}
/** Return a list of all captured logs. */
public List<LogData> logs() {
return testRunner.getExportedLogs();
public List<LogRecordData> logRecords() {
return testRunner.getExportedLogRecords();
}
/**

View File

@ -14,6 +14,7 @@ import static java.util.stream.Collectors.toList;
import com.google.protobuf.InvalidProtocolBufferException;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.logs.Severity;
import io.opentelemetry.api.trace.SpanContext;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.api.trace.StatusCode;
@ -44,8 +45,7 @@ import io.opentelemetry.proto.trace.v1.ScopeSpans;
import io.opentelemetry.proto.trace.v1.Span;
import io.opentelemetry.proto.trace.v1.Status;
import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
import io.opentelemetry.sdk.logs.data.LogData;
import io.opentelemetry.sdk.logs.data.Severity;
import io.opentelemetry.sdk.logs.data.LogRecordData;
import io.opentelemetry.sdk.metrics.data.AggregationTemporality;
import io.opentelemetry.sdk.metrics.data.DoublePointData;
import io.opentelemetry.sdk.metrics.data.HistogramPointData;
@ -63,7 +63,7 @@ import io.opentelemetry.sdk.metrics.internal.data.ImmutableSumData;
import io.opentelemetry.sdk.metrics.internal.data.ImmutableSummaryData;
import io.opentelemetry.sdk.metrics.internal.data.ImmutableSummaryPointData;
import io.opentelemetry.sdk.metrics.internal.data.ImmutableValueAtQuantile;
import io.opentelemetry.sdk.testing.logs.TestLogData;
import io.opentelemetry.sdk.testing.logs.TestLogRecordData;
import io.opentelemetry.sdk.testing.trace.TestSpanData;
import io.opentelemetry.sdk.trace.data.EventData;
import io.opentelemetry.sdk.trace.data.LinkData;
@ -276,7 +276,7 @@ public final class AgentTestingExporterAccess {
}
@SuppressWarnings("unchecked")
public static List<LogData> getExportedLogs() {
public static List<LogRecordData> getExportedLogRecords() {
List<byte[]> exportRequests;
try {
exportRequests = (List<byte[]>) getLogExportRequests.invokeExact();
@ -296,7 +296,7 @@ public final class AgentTestingExporterAccess {
})
.flatMap(request -> request.getResourceLogsList().stream())
.collect(toList());
List<LogData> logs = new ArrayList<>();
List<LogRecordData> logs = new ArrayList<>();
for (ResourceLogs resourceLogs : allResourceLogs) {
Resource resource = resourceLogs.getResource();
for (ScopeLogs ilLogs : resourceLogs.getScopeLogsList()) {
@ -391,11 +391,11 @@ public final class AgentTestingExporterAccess {
}
}
private static LogData createLogData(
private static LogRecordData createLogData(
LogRecord logRecord,
io.opentelemetry.sdk.resources.Resource resource,
InstrumentationScopeInfo instrumentationScopeInfo) {
return TestLogData.builder()
return TestLogRecordData.builder()
.setResource(resource)
.setInstrumentationScopeInfo(instrumentationScopeInfo)
.setEpoch(logRecord.getTimeUnixNano(), TimeUnit.NANOSECONDS)

View File

@ -16,9 +16,6 @@ dependencies {
compileOnly(project(":javaagent-bootstrap"))
compileOnly(project(":javaagent-tooling"))
compileOnly(project(":instrumentation-appender-api-internal"))
compileOnly(project(":instrumentation-appender-sdk-internal"))
implementation("io.opentelemetry:opentelemetry-exporter-otlp-common")
compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure")
}

View File

@ -8,7 +8,7 @@ package io.opentelemetry.javaagent.testing.exporter;
import com.google.auto.service.AutoService;
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer;
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider;
import io.opentelemetry.sdk.logs.export.SimpleLogProcessor;
import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor;
import io.opentelemetry.sdk.metrics.export.MetricReader;
import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader;
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
@ -40,9 +40,9 @@ public class AgentTestingCustomizer implements AutoConfigurationCustomizerProvid
autoConfigurationCustomizer.addMeterProviderCustomizer(
(meterProvider, config) -> meterProvider.registerMetricReader(metricReader));
autoConfigurationCustomizer.addLogEmitterProviderCustomizer(
autoConfigurationCustomizer.addLoggerProviderCustomizer(
(logProvider, config) ->
logProvider.addLogProcessor(
SimpleLogProcessor.create(AgentTestingExporterFactory.logExporter)));
logProvider.addLogRecordProcessor(
SimpleLogRecordProcessor.create(AgentTestingExporterFactory.logExporter)));
}
}

View File

@ -12,7 +12,7 @@ public final class AgentTestingExporterFactory {
static final OtlpInMemorySpanExporter spanExporter = new OtlpInMemorySpanExporter();
static final OtlpInMemoryMetricExporter metricExporter = new OtlpInMemoryMetricExporter();
static final OtlpInMemoryLogExporter logExporter = new OtlpInMemoryLogExporter();
static final OtlpInMemoryLogRecordExporter logExporter = new OtlpInMemoryLogRecordExporter();
public static List<byte[]> getSpanExportRequests() {
return spanExporter.getCollectedExportRequests();

View File

@ -9,8 +9,8 @@ import static java.util.logging.Level.INFO;
import io.opentelemetry.exporter.internal.otlp.logs.LogsRequestMarshaler;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.logs.data.LogData;
import io.opentelemetry.sdk.logs.export.LogExporter;
import io.opentelemetry.sdk.logs.data.LogRecordData;
import io.opentelemetry.sdk.logs.export.LogRecordExporter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
@ -21,9 +21,10 @@ import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.logging.Logger;
class OtlpInMemoryLogExporter implements LogExporter {
class OtlpInMemoryLogRecordExporter implements LogRecordExporter {
private static final Logger logger = Logger.getLogger(OtlpInMemoryLogExporter.class.getName());
private static final Logger logger =
Logger.getLogger(OtlpInMemoryLogRecordExporter.class.getName());
private final Queue<byte[]> collectedRequests = new ConcurrentLinkedQueue<>();
@ -36,13 +37,13 @@ class OtlpInMemoryLogExporter implements LogExporter {
}
@Override
public CompletableResultCode export(Collection<LogData> logs) {
for (LogData log : logs) {
logger.log(INFO, "Exporting log {0}", log);
public CompletableResultCode export(Collection<LogRecordData> logRecords) {
for (LogRecordData logRecord : logRecords) {
logger.log(INFO, "Exporting log {0}", logRecord);
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
LogsRequestMarshaler.create(logs).writeBinaryTo(bos);
LogsRequestMarshaler.create(logRecords).writeBinaryTo(bos);
} catch (IOException e) {
throw new UncheckedIOException(e);
}