Skip to content

Commit 1ab2dbf

Browse files
Bridge log body any value (#12204)
Co-authored-by: opentelemetrybot <[email protected]>
1 parent bd9dce8 commit 1ab2dbf

File tree

18 files changed

+520
-26
lines changed

18 files changed

+520
-26
lines changed

instrumentation/log4j/log4j-appender-2.17/javaagent/src/test/java/io/opentelemetry/instrumentation/log4j/appender/v2_17/Log4j2Test.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import static java.util.concurrent.TimeUnit.MILLISECONDS;
1212

1313
import io.opentelemetry.api.common.AttributeKey;
14+
import io.opentelemetry.api.common.Value;
1415
import io.opentelemetry.api.logs.Severity;
1516
import io.opentelemetry.api.trace.SpanContext;
1617
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
@@ -173,7 +174,7 @@ void testStringMapMessage() {
173174
testing.waitAndAssertLogRecords(
174175
logRecord ->
175176
logRecord
176-
.hasBody("")
177+
.hasBody((Value<?>) null)
177178
.hasInstrumentationScope(InstrumentationScopeInfo.builder("abc").build())
178179
.hasSeverity(Severity.INFO)
179180
.hasSeverityText("INFO")

instrumentation/opentelemetry-api/opentelemetry-api-1.27/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_27/ApplicationOpenTelemetry127.java

+25-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_10.metrics.ApplicationMeterFactory;
1515
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_10.metrics.ApplicationMeterProvider;
1616
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_15.metrics.ApplicationMeterFactory115;
17+
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_27.logs.ApplicationLoggerFactory;
18+
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_27.logs.ApplicationLoggerFactory127;
1719
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_27.logs.ApplicationLoggerProvider;
1820
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_4.trace.ApplicationTracerProvider14;
1921
import java.lang.reflect.InvocationTargetException;
@@ -39,7 +41,8 @@ private ApplicationOpenTelemetry127() {
3941
new ApplicationContextPropagators(agentOpenTelemetry.getPropagators());
4042
applicationMeterProvider =
4143
new ApplicationMeterProvider(getMeterFactory(), agentOpenTelemetry.getMeterProvider());
42-
applicationLoggerProvider = new ApplicationLoggerProvider(agentOpenTelemetry.getLogsBridge());
44+
applicationLoggerProvider =
45+
new ApplicationLoggerProvider(getLoggerFactory(), agentOpenTelemetry.getLogsBridge());
4346
}
4447

4548
@Override
@@ -105,9 +108,29 @@ private static ApplicationMeterFactory getMeterFactory() {
105108
}
106109

107110
private static ApplicationMeterFactory getMeterFactory(String className) {
111+
return getFactory(className, ApplicationMeterFactory.class);
112+
}
113+
114+
private static ApplicationLoggerFactory getLoggerFactory() {
115+
// this class is defined in opentelemetry-api-1.42
116+
ApplicationLoggerFactory loggerFactory =
117+
getLoggerFactory(
118+
"io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_42.logs.ApplicationLoggerFactory142");
119+
if (loggerFactory == null) {
120+
loggerFactory = new ApplicationLoggerFactory127();
121+
}
122+
123+
return loggerFactory;
124+
}
125+
126+
private static ApplicationLoggerFactory getLoggerFactory(String className) {
127+
return getFactory(className, ApplicationLoggerFactory.class);
128+
}
129+
130+
private static <T> T getFactory(String className, Class<T> factoryClass) {
108131
try {
109132
Class<?> clazz = Class.forName(className);
110-
return (ApplicationMeterFactory) clazz.getConstructor().newInstance();
133+
return factoryClass.cast(clazz.getConstructor().newInstance());
111134
} catch (ClassNotFoundException
112135
| NoSuchMethodException
113136
| InstantiationException

instrumentation/opentelemetry-api/opentelemetry-api-1.27/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_27/logs/ApplicationLogRecordBuilder.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@
1515
import java.time.Instant;
1616
import java.util.concurrent.TimeUnit;
1717

18-
class ApplicationLogRecordBuilder implements LogRecordBuilder {
18+
public class ApplicationLogRecordBuilder implements LogRecordBuilder {
1919

2020
private final io.opentelemetry.api.logs.LogRecordBuilder agentLogRecordBuilder;
2121

22-
ApplicationLogRecordBuilder(io.opentelemetry.api.logs.LogRecordBuilder agentLogRecordBuilder) {
22+
protected ApplicationLogRecordBuilder(
23+
io.opentelemetry.api.logs.LogRecordBuilder agentLogRecordBuilder) {
2324
this.agentLogRecordBuilder = agentLogRecordBuilder;
2425
}
2526

instrumentation/opentelemetry-api/opentelemetry-api-1.27/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_27/logs/ApplicationLogger.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
import application.io.opentelemetry.api.logs.LogRecordBuilder;
99
import application.io.opentelemetry.api.logs.Logger;
1010

11-
class ApplicationLogger implements Logger {
11+
public class ApplicationLogger implements Logger {
1212

1313
private final io.opentelemetry.api.logs.Logger agentLogger;
1414

15-
ApplicationLogger(io.opentelemetry.api.logs.Logger agentLogger) {
15+
protected ApplicationLogger(io.opentelemetry.api.logs.Logger agentLogger) {
1616
this.agentLogger = agentLogger;
1717
}
1818

instrumentation/opentelemetry-api/opentelemetry-api-1.27/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_27/logs/ApplicationLoggerBuilder.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@
1111

1212
final class ApplicationLoggerBuilder implements LoggerBuilder {
1313

14+
private final ApplicationLoggerFactory loggerFactory;
1415
private final io.opentelemetry.api.logs.LoggerBuilder agentBuilder;
1516

16-
ApplicationLoggerBuilder(io.opentelemetry.api.logs.LoggerBuilder agentBuilder) {
17+
ApplicationLoggerBuilder(
18+
ApplicationLoggerFactory loggerFactory,
19+
io.opentelemetry.api.logs.LoggerBuilder agentBuilder) {
20+
this.loggerFactory = loggerFactory;
1721
this.agentBuilder = agentBuilder;
1822
}
1923

@@ -33,6 +37,6 @@ public LoggerBuilder setInstrumentationVersion(String version) {
3337

3438
@Override
3539
public Logger build() {
36-
return new ApplicationLogger(agentBuilder.build());
40+
return loggerFactory.newLogger(agentBuilder.build());
3741
}
3842
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_27.logs;
7+
8+
public interface ApplicationLoggerFactory {
9+
10+
ApplicationLogger newLogger(io.opentelemetry.api.logs.Logger agentLogger);
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_27.logs;
7+
8+
import io.opentelemetry.api.logs.Logger;
9+
10+
public class ApplicationLoggerFactory127 implements ApplicationLoggerFactory {
11+
12+
@Override
13+
public ApplicationLogger newLogger(Logger agentLogger) {
14+
return new ApplicationLogger(agentLogger);
15+
}
16+
}

instrumentation/opentelemetry-api/opentelemetry-api-1.27/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_27/logs/ApplicationLoggerProvider.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,19 @@
1212
@SuppressWarnings("UnnecessarilyFullyQualified")
1313
public class ApplicationLoggerProvider implements LoggerProvider {
1414

15+
private final ApplicationLoggerFactory loggerFactory;
1516
private final io.opentelemetry.api.logs.LoggerProvider agentLoggerProvider;
1617

17-
public ApplicationLoggerProvider(io.opentelemetry.api.logs.LoggerProvider agentLoggerProvider) {
18+
public ApplicationLoggerProvider(
19+
ApplicationLoggerFactory loggerFactory,
20+
io.opentelemetry.api.logs.LoggerProvider agentLoggerProvider) {
21+
this.loggerFactory = loggerFactory;
1822
this.agentLoggerProvider = agentLoggerProvider;
1923
}
2024

2125
@Override
2226
public LoggerBuilder loggerBuilder(String instrumentationName) {
23-
return new ApplicationLoggerBuilder(agentLoggerProvider.loggerBuilder(instrumentationName));
27+
return new ApplicationLoggerBuilder(
28+
loggerFactory, agentLoggerProvider.loggerBuilder(instrumentationName));
2429
}
2530
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
plugins {
2+
id("otel.javaagent-instrumentation")
3+
}
4+
5+
dependencies {
6+
compileOnly(project(":opentelemetry-api-shaded-for-instrumenting", configuration = "v1_42"))
7+
compileOnly("io.opentelemetry:opentelemetry-api-incubator")
8+
9+
implementation(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.0:javaagent"))
10+
implementation(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.4:javaagent"))
11+
implementation(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.10:javaagent"))
12+
implementation(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.15:javaagent"))
13+
implementation(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.27:javaagent"))
14+
implementation(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.31:javaagent"))
15+
implementation(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.32:javaagent"))
16+
implementation(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.37:javaagent"))
17+
implementation(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.38:javaagent"))
18+
}
19+
20+
configurations.configureEach {
21+
if (name.endsWith("testRuntimeClasspath", true) || name.endsWith("testCompileClasspath", true)) {
22+
resolutionStrategy {
23+
force("io.opentelemetry:opentelemetry-api:1.42.0")
24+
}
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_42;
7+
8+
import static java.util.Collections.singletonList;
9+
10+
import com.google.auto.service.AutoService;
11+
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
12+
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
13+
import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule;
14+
import java.util.List;
15+
16+
@AutoService(InstrumentationModule.class)
17+
public class OpenTelemetryApiInstrumentationModule extends InstrumentationModule
18+
implements ExperimentalInstrumentationModule {
19+
public OpenTelemetryApiInstrumentationModule() {
20+
super("opentelemetry-api", "opentelemetry-api-1.42");
21+
}
22+
23+
@Override
24+
public List<TypeInstrumentation> typeInstrumentations() {
25+
return singletonList(new OpenTelemetryInstrumentation());
26+
}
27+
28+
@Override
29+
public String getModuleGroup() {
30+
return "opentelemetry-api-bridge";
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_42;
7+
8+
import static net.bytebuddy.matcher.ElementMatchers.named;
9+
import static net.bytebuddy.matcher.ElementMatchers.none;
10+
11+
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
12+
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
13+
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_42.logs.ApplicationLoggerFactory142;
14+
import net.bytebuddy.asm.Advice;
15+
import net.bytebuddy.description.type.TypeDescription;
16+
import net.bytebuddy.matcher.ElementMatcher;
17+
18+
public class OpenTelemetryInstrumentation implements TypeInstrumentation {
19+
20+
@Override
21+
public ElementMatcher<TypeDescription> typeMatcher() {
22+
return named("application.io.opentelemetry.api.GlobalOpenTelemetry");
23+
}
24+
25+
@Override
26+
public void transform(TypeTransformer transformer) {
27+
transformer.applyAdviceToMethod(
28+
none(), OpenTelemetryInstrumentation.class.getName() + "$InitAdvice");
29+
}
30+
31+
@SuppressWarnings({"ReturnValueIgnored", "unused"})
32+
public static class InitAdvice {
33+
@Advice.OnMethodEnter
34+
public static void init() {
35+
// the sole purpose of this advice is to ensure that ApplicationLoggerFactory142 is recognized
36+
// as helper class and injected into class loader
37+
ApplicationLoggerFactory142.class.getName();
38+
}
39+
}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_42.logs;
7+
8+
import application.io.opentelemetry.api.common.KeyValue;
9+
import application.io.opentelemetry.api.common.Value;
10+
import application.io.opentelemetry.api.logs.LogRecordBuilder;
11+
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_27.logs.ApplicationLogRecordBuilder;
12+
import java.nio.ByteBuffer;
13+
import java.util.ArrayList;
14+
import java.util.List;
15+
16+
class ApplicationLogRecordBuilder142 extends ApplicationLogRecordBuilder
17+
implements LogRecordBuilder {
18+
19+
private final io.opentelemetry.api.logs.LogRecordBuilder agentLogRecordBuilder;
20+
21+
ApplicationLogRecordBuilder142(io.opentelemetry.api.logs.LogRecordBuilder agentLogRecordBuilder) {
22+
super(agentLogRecordBuilder);
23+
this.agentLogRecordBuilder = agentLogRecordBuilder;
24+
}
25+
26+
@Override
27+
public LogRecordBuilder setBody(Value<?> body) {
28+
agentLogRecordBuilder.setBody(convertValue(body));
29+
return this;
30+
}
31+
32+
@SuppressWarnings("unchecked")
33+
private static io.opentelemetry.api.common.Value<?> convertValue(Value<?> value) {
34+
if (value == null) {
35+
return null;
36+
}
37+
38+
switch (value.getType()) {
39+
case STRING:
40+
return io.opentelemetry.api.common.Value.of((String) value.getValue());
41+
case BOOLEAN:
42+
return io.opentelemetry.api.common.Value.of((Boolean) value.getValue());
43+
case LONG:
44+
return io.opentelemetry.api.common.Value.of((Long) value.getValue());
45+
case DOUBLE:
46+
return io.opentelemetry.api.common.Value.of((Double) value.getValue());
47+
case ARRAY:
48+
List<Value<?>> values = (List<Value<?>>) value.getValue();
49+
List<io.opentelemetry.api.common.Value<?>> convertedValues = new ArrayList<>();
50+
for (Value<?> source : values) {
51+
convertedValues.add(convertValue(source));
52+
}
53+
return io.opentelemetry.api.common.Value.of(convertedValues);
54+
case KEY_VALUE_LIST:
55+
List<KeyValue> keyValueList = (List<KeyValue>) value.getValue();
56+
io.opentelemetry.api.common.KeyValue[] convertedKeyValueList =
57+
new io.opentelemetry.api.common.KeyValue[keyValueList.size()];
58+
int i = 0;
59+
for (KeyValue source : keyValueList) {
60+
convertedKeyValueList[i++] =
61+
io.opentelemetry.api.common.KeyValue.of(
62+
source.getKey(), convertValue(source.getValue()));
63+
}
64+
return io.opentelemetry.api.common.Value.of(convertedKeyValueList);
65+
case BYTES:
66+
ByteBuffer byteBuffer = (ByteBuffer) value.getValue();
67+
byte[] bytes = new byte[byteBuffer.remaining()];
68+
byteBuffer.get(bytes);
69+
break;
70+
}
71+
72+
throw new IllegalStateException("Unhandled value type: " + value.getType());
73+
}
74+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_42.logs;
7+
8+
import application.io.opentelemetry.api.logs.LogRecordBuilder;
9+
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_27.logs.ApplicationLogger;
10+
11+
class ApplicationLogger142 extends ApplicationLogger {
12+
13+
private final io.opentelemetry.api.logs.Logger agentLogger;
14+
15+
ApplicationLogger142(io.opentelemetry.api.logs.Logger agentLogger) {
16+
super(agentLogger);
17+
this.agentLogger = agentLogger;
18+
}
19+
20+
@Override
21+
public LogRecordBuilder logRecordBuilder() {
22+
return new ApplicationLogRecordBuilder142(agentLogger.logRecordBuilder());
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_42.logs;
7+
8+
import io.opentelemetry.api.logs.Logger;
9+
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_27.logs.ApplicationLogger;
10+
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_27.logs.ApplicationLoggerFactory;
11+
12+
public class ApplicationLoggerFactory142 implements ApplicationLoggerFactory {
13+
14+
@Override
15+
public ApplicationLogger newLogger(Logger agentLogger) {
16+
return new ApplicationLogger142(agentLogger);
17+
}
18+
}

0 commit comments

Comments
 (0)