Skip to content

Commit 3a94ffb

Browse files
committed
[tracing] Use OT provided mechanisms for configuring OT
Notably, we now use OpenTelemetry's own reflection-based mechanism for loading tracers. This means we have removed our custom code for setting things up for Jaeger.
1 parent a34ad83 commit 3a94ffb

7 files changed

Lines changed: 426 additions & 363 deletions

File tree

java/client/src/org/openqa/selenium/remote/tracing/opentelemetry/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ java_library(
99
"//java/client/test/org/openqa/selenium/remote/tracing:__subpackages__",
1010
],
1111
deps = [
12+
"//java:auto-service",
1213
"//java/client/src/org/openqa/selenium:core",
1314
"//java/client/src/org/openqa/selenium/json",
1415
"//java/client/src/org/openqa/selenium/remote/tracing",
@@ -18,6 +19,7 @@ java_library(
1819
artifact("io.opentelemetry:opentelemetry-exporter-logging"),
1920
artifact("io.opentelemetry:opentelemetry-sdk"),
2021
artifact("io.opentelemetry:opentelemetry-sdk-common"),
22+
artifact("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure"),
2123
artifact("io.opentelemetry:opentelemetry-sdk-trace"),
2224
artifact("io.opentelemetry:opentelemetry-semconv"),
2325
],

java/client/src/org/openqa/selenium/remote/tracing/opentelemetry/OpenTelemetryTracer.java

Lines changed: 8 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -17,38 +17,15 @@
1717

1818
package org.openqa.selenium.remote.tracing.opentelemetry;
1919

20-
import io.opentelemetry.api.common.Attributes;
21-
import io.opentelemetry.api.trace.StatusCode;
22-
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
20+
import io.opentelemetry.api.trace.Tracer;
2321
import io.opentelemetry.context.Context;
24-
import io.opentelemetry.context.propagation.ContextPropagators;
2522
import io.opentelemetry.context.propagation.TextMapPropagator;
26-
import io.opentelemetry.api.trace.Tracer;
2723
import io.opentelemetry.sdk.OpenTelemetrySdk;
28-
import io.opentelemetry.sdk.common.CompletableResultCode;
29-
import io.opentelemetry.sdk.resources.Resource;
30-
import io.opentelemetry.sdk.trace.SdkTracerProvider;
31-
import io.opentelemetry.sdk.trace.SpanProcessor;
32-
import io.opentelemetry.sdk.trace.data.EventData;
33-
import io.opentelemetry.sdk.trace.data.SpanData;
34-
import io.opentelemetry.sdk.trace.data.StatusData;
35-
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
36-
import io.opentelemetry.sdk.trace.export.SpanExporter;
37-
38-
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
24+
import io.opentelemetry.sdk.autoconfigure.OpenTelemetrySdkAutoConfiguration;
3925
import org.openqa.selenium.internal.Require;
40-
import org.openqa.selenium.json.Json;
41-
import org.openqa.selenium.json.JsonOutput;
4226
import org.openqa.selenium.remote.tracing.Propagator;
4327
import org.openqa.selenium.remote.tracing.TraceContext;
4428

45-
import java.util.Collection;
46-
import java.util.HashMap;
47-
import java.util.LinkedList;
48-
import java.util.List;
49-
import java.util.Map;
50-
import java.util.Optional;
51-
import java.util.logging.Level;
5229
import java.util.logging.Logger;
5330

5431
public class OpenTelemetryTracer implements org.openqa.selenium.remote.tracing.Tracer {
@@ -80,102 +57,22 @@ public static OpenTelemetryTracer getInstance() {
8057

8158
private static OpenTelemetryTracer createTracer() {
8259
LOG.info("Using OpenTelemetry for tracing");
83-
List<SpanProcessor> exporters = new LinkedList<>();
84-
exporters.add(SimpleSpanProcessor.create(new SpanExporter() {
85-
@Override
86-
public CompletableResultCode export(Collection<SpanData> spans) {
87-
88-
spans.forEach(span -> {
89-
LOG.fine(String.valueOf(span));
90-
91-
String traceId = span.getTraceId();
92-
String spanId = span.getSpanId();
93-
StatusData status = span.getStatus();
94-
List<EventData> eventList = span.getEvents();
95-
eventList.forEach(event -> {
96-
Map<String, Object> map = new HashMap<>();
97-
map.put("eventTime", event.getEpochNanos());
98-
map.put("traceId", traceId);
99-
map.put("spanId", spanId);
100-
map.put("spanKind", span.getKind().toString());
101-
map.put("eventName", event.getName());
10260

103-
Attributes attributes = event.getAttributes();
104-
map.put("attributes", attributes.asMap());
105-
String jsonString = getJsonString(map);
106-
if (status.getStatusCode() == StatusCode.ERROR) {
107-
LOG.log(Level.WARNING, jsonString);
108-
} else {
109-
LOG.log(Level.FINE, jsonString);
110-
}
111-
});
112-
});
113-
return CompletableResultCode.ofSuccess();
114-
}
115-
116-
@Override
117-
public CompletableResultCode flush() {
118-
return CompletableResultCode.ofSuccess();
119-
}
120-
121-
@Override
122-
public CompletableResultCode shutdown() {
123-
// no-op
124-
return CompletableResultCode.ofSuccess();
125-
}
126-
}));
127-
128-
// The Jaeger exporter doesn't yet have a `TracerFactoryProvider`, so we
129-
// shall look up the class using reflection, and beg for forgiveness
130-
// later.
131-
Optional<SpanExporter> maybeJaeger = JaegerTracing.findJaegerExporter();
132-
maybeJaeger.ifPresent(
133-
exporter -> exporters.add(SimpleSpanProcessor.create(exporter)));
134-
135-
Resource serviceNameResource =
136-
Resource.create(Attributes.of(
137-
ResourceAttributes.SERVICE_NAME,
138-
System.getProperty("JAEGER_SERVICE_NAME", "selenium")));
139-
140-
// OpenTelemetry default propagators are no-op since version 0.9.0.
141-
// Hence, required propagators need to defined and added.
142-
ContextPropagators propagators =
143-
ContextPropagators.create((W3CTraceContextPropagator.getInstance()));
144-
145-
SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
146-
.addSpanProcessor(SpanProcessor.composite(exporters))
147-
.setResource(Resource.getDefault().merge(serviceNameResource))
148-
.build();
149-
150-
OpenTelemetrySdk openTelemetrySdk = OpenTelemetrySdk.builder()
151-
.setTracerProvider(sdkTracerProvider)
152-
.setPropagators(propagators)
153-
.buildAndRegisterGlobal();
154-
155-
Runtime.getRuntime()
156-
.addShutdownHook(new Thread(sdkTracerProvider::close));
61+
OpenTelemetrySdk autoConfiguredSdk = OpenTelemetrySdkAutoConfiguration.initialize();
15762

15863
return new OpenTelemetryTracer(
159-
openTelemetrySdk.getTracer("default"),
160-
propagators.getTextMapPropagator());
161-
}
162-
163-
private static String getJsonString(Map<String, Object> map) {
164-
StringBuilder text = new StringBuilder();
165-
try (JsonOutput json = new Json().newOutput(text).setPrettyPrint(false)) {
166-
json.write(map);
167-
text.append('\n');
168-
}
169-
return text.toString();
64+
autoConfiguredSdk.getTracer("default"),
65+
autoConfiguredSdk.getPropagators().getTextMapPropagator());
17066
}
17167

17268
private final Tracer tracer;
17369
private final OpenTelemetryPropagator telemetryPropagator;
17470

175-
public OpenTelemetryTracer(Tracer tracer, TextMapPropagator textMapPropagator) {
71+
public OpenTelemetryTracer(Tracer tracer, TextMapPropagator propagator) {
17672
this.tracer = Require.nonNull("Tracer", tracer);
17773
this.telemetryPropagator = new OpenTelemetryPropagator(
178-
tracer, Require.nonNull("Formatter", textMapPropagator));
74+
tracer,
75+
Require.nonNull("Formatter", propagator));
17976
}
18077

18178
@Override
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Licensed to the Software Freedom Conservancy (SFC) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The SFC licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.openqa.selenium.remote.tracing.opentelemetry;
19+
20+
import com.google.auto.service.AutoService;
21+
import io.opentelemetry.api.common.Attributes;
22+
import io.opentelemetry.api.trace.StatusCode;
23+
import io.opentelemetry.sdk.autoconfigure.spi.SdkTracerProviderConfigurer;
24+
import io.opentelemetry.sdk.common.CompletableResultCode;
25+
import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder;
26+
import io.opentelemetry.sdk.trace.data.EventData;
27+
import io.opentelemetry.sdk.trace.data.SpanData;
28+
import io.opentelemetry.sdk.trace.data.StatusData;
29+
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
30+
import io.opentelemetry.sdk.trace.export.SpanExporter;
31+
import org.openqa.selenium.json.Json;
32+
import org.openqa.selenium.json.JsonOutput;
33+
34+
import java.util.Collection;
35+
import java.util.HashMap;
36+
import java.util.List;
37+
import java.util.Map;
38+
import java.util.logging.Level;
39+
import java.util.logging.Logger;
40+
41+
@AutoService(SdkTracerProviderConfigurer.class)
42+
public class SeleniumSpanExporter implements SdkTracerProviderConfigurer {
43+
private static final Logger LOG = Logger.getLogger(SeleniumSpanExporter.class.getName());
44+
45+
@Override
46+
public void configure(SdkTracerProviderBuilder tracerProvider) {
47+
tracerProvider.addSpanProcessor(SimpleSpanProcessor.create(new SpanExporter() {
48+
@Override
49+
public CompletableResultCode export(Collection<SpanData> spans) {
50+
spans.forEach(span -> {
51+
LOG.fine(String.valueOf(span));
52+
53+
String traceId = span.getTraceId();
54+
String spanId = span.getSpanId();
55+
StatusData status = span.getStatus();
56+
List<EventData> eventList = span.getEvents();
57+
eventList.forEach(event -> {
58+
Map<String, Object> map = new HashMap<>();
59+
map.put("eventTime", event.getEpochNanos());
60+
map.put("traceId", traceId);
61+
map.put("spanId", spanId);
62+
map.put("spanKind", span.getKind().toString());
63+
map.put("eventName", event.getName());
64+
65+
Attributes attributes = event.getAttributes();
66+
map.put("attributes", attributes.asMap());
67+
String jsonString = getJsonString(map);
68+
if (status.getStatusCode() == StatusCode.ERROR) {
69+
LOG.log(Level.WARNING, jsonString);
70+
} else {
71+
LOG.log(Level.FINE, jsonString);
72+
}
73+
});
74+
});
75+
return CompletableResultCode.ofSuccess();
76+
}
77+
78+
@Override
79+
public CompletableResultCode flush() {
80+
return CompletableResultCode.ofSuccess();
81+
}
82+
83+
@Override
84+
public CompletableResultCode shutdown() {
85+
// no-op
86+
return CompletableResultCode.ofSuccess();
87+
}
88+
}));
89+
}
90+
91+
private static String getJsonString(Map<String, Object> map) {
92+
StringBuilder text = new StringBuilder();
93+
try (JsonOutput json = new Json().newOutput(text).setPrettyPrint(false)) {
94+
json.write(map);
95+
text.append('\n');
96+
}
97+
return text.toString();
98+
}
99+
}

java/maven_deps.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ def selenium_java_deps():
4444
"io.opentelemetry:opentelemetry-semconv:%s" % opentelemetry_version+"-alpha",
4545
"io.opentelemetry:opentelemetry-sdk:%s" % opentelemetry_version,
4646
"io.opentelemetry:opentelemetry-sdk-common:%s" % opentelemetry_version,
47+
"io.opentelemetry:opentelemetry-sdk-extension-autoconfigure:0.16.0-alpha",
4748
"io.opentelemetry:opentelemetry-sdk-testing:%s" % opentelemetry_version,
4849
"io.opentelemetry:opentelemetry-sdk-trace:%s" % opentelemetry_version,
4950
"io.ous:jtoml:2.0.0",

0 commit comments

Comments
 (0)