Skip to content

Commit 775c39f

Browse files
authored
Add span processor that adds container ID to every span if Zipkin exporter is used (#133)
* Add span processor that adds container ID Signed-off-by: Pavol Loffay <[email protected]> * cleanup Signed-off-by: Pavol Loffay <[email protected]>
1 parent a96fe8b commit 775c39f

File tree

6 files changed

+120
-8
lines changed

6 files changed

+120
-8
lines changed

otel-extensions/build.gradle.kts

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ plugins {
33
}
44

55
dependencies {
6-
implementation("org.slf4j:slf4j-api:1.7.30")
76
compileOnly("io.opentelemetry:opentelemetry-sdk:0.10.0")
7+
implementation("io.opentelemetry.javaagent:opentelemetry-javaagent-spi:0.10.1")
8+
9+
implementation("org.slf4j:slf4j-api:1.7.30")
810
implementation("com.google.auto.service:auto-service:1.0-rc7")
911
annotationProcessor("com.google.auto.service:auto-service:1.0-rc7")
1012

otel-extensions/src/main/java/org/hypertrace/agent/otel/extensions/CgroupsReader.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ public class CgroupsReader {
3333

3434
private final String cgroupsPath;
3535

36-
CgroupsReader() {
36+
public CgroupsReader() {
3737
this.cgroupsPath = DEFAULT_CGROUPS_PATH;
3838
}
3939

40-
CgroupsReader(String cgroupsPath) {
40+
public CgroupsReader(String cgroupsPath) {
4141
this.cgroupsPath = cgroupsPath;
4242
}
4343

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright The Hypertrace Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.hypertrace.agent.otel.extensions.processor;
18+
19+
import io.opentelemetry.context.Context;
20+
import io.opentelemetry.sdk.common.CompletableResultCode;
21+
import io.opentelemetry.sdk.resources.ResourceAttributes;
22+
import io.opentelemetry.sdk.trace.ReadWriteSpan;
23+
import io.opentelemetry.sdk.trace.ReadableSpan;
24+
import io.opentelemetry.sdk.trace.SpanProcessor;
25+
import org.hypertrace.agent.otel.extensions.CgroupsReader;
26+
27+
public class AddTagsSpanProcessor implements SpanProcessor {
28+
29+
// initialize at startup because the processor is executed for every span.
30+
private final String containerId;
31+
32+
public AddTagsSpanProcessor() {
33+
CgroupsReader cgroupsReader = new CgroupsReader();
34+
containerId = cgroupsReader.readContainerId();
35+
}
36+
37+
@Override
38+
public void onStart(Context parentContext, ReadWriteSpan span) {
39+
if (containerId != null && !containerId.isEmpty()) {
40+
span.setAttribute(ResourceAttributes.CONTAINER_ID, containerId);
41+
}
42+
}
43+
44+
@Override
45+
public boolean isStartRequired() {
46+
return true;
47+
}
48+
49+
@Override
50+
public void onEnd(ReadableSpan span) {}
51+
52+
@Override
53+
public boolean isEndRequired() {
54+
return false;
55+
}
56+
57+
@Override
58+
public CompletableResultCode shutdown() {
59+
return CompletableResultCode.ofSuccess();
60+
}
61+
62+
@Override
63+
public CompletableResultCode forceFlush() {
64+
return CompletableResultCode.ofSuccess();
65+
}
66+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright The Hypertrace Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.hypertrace.agent.otel.extensions.processor;
18+
19+
import com.google.auto.service.AutoService;
20+
import io.opentelemetry.javaagent.spi.TracerCustomizer;
21+
import io.opentelemetry.sdk.trace.TracerSdkManagement;
22+
23+
/**
24+
* This is a workaround to add container ID tags to spans when Zipkin exporter is used. Zipkin
25+
* exporter does not add process attributes where the container ID is
26+
* https://github.com/open-telemetry/opentelemetry-java/issues/1970.
27+
*
28+
* <p>Remove this once we migrate to OTEL exporter
29+
* https://github.com/hypertrace/javaagent/issues/132
30+
*/
31+
@AutoService(TracerCustomizer.class)
32+
public class HypertraceTracerCustomizer implements TracerCustomizer {
33+
34+
@Override
35+
public void configure(TracerSdkManagement tracerManagement) {
36+
String exporter = System.getProperty("otel.exporter");
37+
if (exporter != null && exporter.contains("zipkin")) {
38+
tracerManagement.addSpanProcessor(new AddTagsSpanProcessor());
39+
}
40+
}
41+
}

smoke-tests/build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ dependencies{
88
testImplementation("com.squareup.okhttp3:okhttp:4.9.0")
99
testImplementation("org.awaitility:awaitility:4.0.3")
1010
testImplementation("io.opentelemetry:opentelemetry-proto:0.10.0")
11+
testImplementation("io.opentelemetry:opentelemetry-sdk:0.10.0")
1112
testImplementation("com.google.protobuf:protobuf-java-util:3.13.0")
1213
}
1314

smoke-tests/src/test/java/org/hypertrace/agent/smoketest/SpringBootSmokeTest.java

+7-5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.hypertrace.agent.smoketest;
1818

1919
import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest;
20+
import io.opentelemetry.sdk.resources.ResourceAttributes;
2021
import java.io.IOException;
2122
import java.util.ArrayList;
2223
import java.util.Collection;
@@ -34,7 +35,7 @@
3435
// key = "SMOKETEST_JAVAAGENT_PATH",
3536
// value =
3637
//
37-
// "/Users/ploffay/projects/hypertrace/javaagent/javaagent/build/libs/hypertrace-agent-0.3.2-all.jar")
38+
// "/Users/ploffay/projects/hypertrace/javaagent/javaagent/build/libs/hypertrace-agent-0.3.3-SNAPSHOT-all.jar")
3839
public class SpringBootSmokeTest extends AbstractSmokeTest {
3940

4041
@Override
@@ -76,7 +77,11 @@ public void get() throws IOException {
7677

7778
Assertions.assertEquals(1, traces.size());
7879
Assertions.assertEquals(
79-
"service.name", traces.get(0).getResourceSpans(0).getResource().getAttributes(0).getKey());
80+
ResourceAttributes.SERVICE_NAME.getKey(),
81+
traces.get(0).getResourceSpans(0).getResource().getAttributes(0).getKey());
82+
Assertions.assertEquals(
83+
ResourceAttributes.CONTAINER_ID.getKey(),
84+
traces.get(0).getResourceSpans(0).getResource().getAttributes(1).getKey());
8085
// value is specified in resources/ht-config.yaml
8186
Assertions.assertEquals(
8287
"app_under_test",
@@ -113,9 +118,6 @@ public void get() throws IOException {
113118
.map(attribute -> attribute.getValue().getStringValue())
114119
.count()
115120
> 0);
116-
// TODO test the container ID once we switch from Zipkin exporter
117-
// Zipkin exporter does not add resource attributes to span
118-
// https://github.com/open-telemetry/opentelemetry-java/issues/1970
119121

120122
// OTEL BS smoke test app does not have an endpoint that uses content type what we capture
121123
// enable once we add smoke tests apps to our build.

0 commit comments

Comments
 (0)