Skip to content

Commit

Permalink
[tracing] Migrate to OpenTelemetry
Browse files Browse the repository at this point in the history
  • Loading branch information
shs96c committed Feb 4, 2020
1 parent b94185e commit 16a703c
Show file tree
Hide file tree
Showing 74 changed files with 1,001 additions and 432 deletions.
6 changes: 4 additions & 2 deletions java/client/src/org/openqa/selenium/remote/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ java_export(
"BaseAugmenter.java",
"InterfaceImplementation.java",
"JdkAugmenter.java",
"RemoteTags.java",
"html5/AddApplicationCache.java",
"html5/AddLocationContext.java",
"html5/AddWebStorage.java",
Expand All @@ -65,7 +66,7 @@ java_export(
"org.openqa.selenium.remote.internal",
],
uses = [
"io.opentracing.Tracer",
"io.opentelemetry.trace.Tracer",
"org.openqa.selenium.remote.session.CapabilitiesFilter",
"org.openqa.selenium.remote.session.CapabilityTransform",
"org.openqa.selenium.remote.service.DriverService$Builder",
Expand All @@ -92,8 +93,9 @@ java_export(
"//java/client/src/org/openqa/selenium/os",
"//java/client/src/org/openqa/selenium/remote/http/netty",
"//java/client/src/org/openqa/selenium/remote/http/okhttp",
artifact("net.bytebuddy:byte-buddy"),
artifact("com.google.guava:guava"),
artifact("io.opentelemetry:opentelemetry-api"),
artifact("net.bytebuddy:byte-buddy"),
],
)

Expand Down
22 changes: 22 additions & 0 deletions java/client/src/org/openqa/selenium/remote/RemoteTags.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.openqa.selenium.remote;

import io.opentelemetry.trace.Span;
import org.openqa.selenium.Capabilities;

import java.util.function.BiConsumer;

public class RemoteTags {

private RemoteTags() {
// Utility class
}

public static BiConsumer<Span, Capabilities> CAPABILITIES = (span, caps) -> {
span.setAttribute("session.capabilities", String.valueOf(caps));
};

public static BiConsumer<Span, SessionId> SESSION_ID = (span, id) -> {
span.setAttribute("session.id", String.valueOf(id));
};

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ java_library(
exports = [
# Exposed by tracing APIs
"//java/client/src/org/openqa/selenium/remote/http",
artifact("io.opentracing:opentracing-api"),
artifact("io.opentelemetry:opentelemetry-api"),
],
deps = [
"//java/client/src/org/openqa/selenium/remote/http",
artifact("io.opentracing:opentracing-api"),
artifact("io.opentelemetry:opentelemetry-api"),
],
)
24 changes: 24 additions & 0 deletions java/client/src/org/openqa/selenium/remote/tracing/HttpTags.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.openqa.selenium.remote.tracing;

import io.opentelemetry.trace.Span;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

import java.util.function.BiConsumer;

public class HttpTags {

private HttpTags() {
// Utility class
}

public static BiConsumer<Span, HttpRequest> HTTP_REQUEST = (span, req) -> {
span.setAttribute("http.method", req.getMethod().toString());
span.setAttribute("http.url", req.getUri());
};

public static BiConsumer<Span, HttpResponse> HTTP_RESPONSE = (span, res) -> {
span.setAttribute("http.status_code", res.getStatus());
};

}
88 changes: 40 additions & 48 deletions java/client/src/org/openqa/selenium/remote/tracing/HttpTracing.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,59 @@

package org.openqa.selenium.remote.tracing;

import io.opentracing.Span;
import io.opentracing.SpanContext;
import io.opentracing.Tracer;
import io.opentracing.propagation.Format;
import io.opentracing.propagation.TextMap;
import io.opentracing.tag.Tags;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.SpanContext;
import io.opentelemetry.trace.SpanId;
import io.opentelemetry.trace.TraceFlags;
import io.opentelemetry.trace.TraceId;
import io.opentelemetry.trace.Tracer;
import io.opentelemetry.trace.Tracestate;
import org.openqa.selenium.remote.http.HttpRequest;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.logging.Logger;

public class HttpTracing {

private static final Logger LOG = Logger.getLogger(HttpTracing.class.getName());
private static final SpanContext NO_OP_CONTEXT = SpanContext.create(
TraceId.getInvalid(),
SpanId.getInvalid(),
TraceFlags.getDefault(),
Tracestate.getDefault());

private HttpTracing() {
// Utility classes
}

public static SpanContext extract(Tracer tracer, HttpRequest request) {
private static SpanContext extract(Tracer tracer, HttpRequest request) {
Objects.requireNonNull(tracer, "Tracer to use must be set.");
Objects.requireNonNull(request, "Request must be set.");

return tracer.extract(Format.Builtin.HTTP_HEADERS, new HttpRequestAdapter(request));
if (tracer.getHttpTextFormat().fields().stream()
.map(field -> request.getHeader(field) != null)
.reduce(false, Boolean::logicalAnd)) {
return tracer.getHttpTextFormat().extract(request, (req, key) -> req.getHeader(key));
}
return NO_OP_CONTEXT;
}

public static Span.Builder newSpanAsChildOf(Tracer tracer, HttpRequest request, String name) {
Objects.requireNonNull(tracer, "Tracer to use must be set.");
Objects.requireNonNull(request, "Request must be set.");
Objects.requireNonNull(name, "Name to use must be set.");

SpanContext parent = extract(tracer, request);

Span.Builder builder = tracer.spanBuilder(name);
if (parent != null) {
builder.setParent(parent);
} else {
// This should never happen, but you never know, right?
builder.setNoParent();
}

return builder;
}

public static void inject(Tracer tracer, Span span, HttpRequest request) {
Expand All @@ -58,42 +84,8 @@ public static void inject(Tracer tracer, Span span, HttpRequest request) {
StackTraceElement caller = Thread.currentThread().getStackTrace()[2];
LOG.fine(String.format("Injecting %s into %s at %s:%d", request, span, caller.getClassName(), caller.getLineNumber()));

span.setTag(Tags.HTTP_METHOD.getKey(), request.getMethod().toString());
span.setTag(Tags.HTTP_URL.getKey(), request.getUri());

tracer.inject(span.context(), Format.Builtin.HTTP_HEADERS, new HttpRequestAdapter(request));
}

private static class HttpRequestAdapter implements TextMap {

private final HttpRequest request;

public HttpRequestAdapter(HttpRequest request) {
this.request = Objects.requireNonNull(request, "Request to use must be set.");
}

@Override
public void put(String key, String value) {
Objects.requireNonNull(key, "Key to use must be set.");
Objects.requireNonNull(value, "Value to use must be set.");
request.setHeader(key, value);
}

@Override
public Iterator<Map.Entry<String, String>> iterator() {
return asMap(request).entrySet().iterator();
}

private static Map<String, String> asMap(HttpRequest request) {
Map<String, String> entries = new LinkedHashMap<>();
request.getHeaderNames().forEach(name ->
request.getHeaders(name).forEach(value -> {
if (value != null) {
entries.put(name, value);
}
})
);
return entries;
}
span.setAttribute("http.method", request.getMethod().toString());
span.setAttribute("http.url", request.getUri());
tracer.getHttpTextFormat().inject(span.getContext(), request, (req, key, value) -> req.setHeader(key, value));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

package org.openqa.selenium.remote.tracing;

import io.opentracing.Tracer;
import io.opentelemetry.trace.Tracer;
import org.openqa.selenium.remote.http.Filter;
import org.openqa.selenium.remote.http.HttpHandler;
import org.openqa.selenium.remote.http.HttpRequest;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,25 @@

package org.openqa.selenium.remote.tracing;

import io.opentracing.Span;
import io.opentracing.SpanContext;
import io.opentracing.Tracer;
import io.opentracing.tag.Tags;
import io.opentelemetry.context.Scope;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.Status;
import io.opentelemetry.trace.Tracer;
import org.openqa.selenium.remote.http.HttpHandler;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

import java.io.UncheckedIOException;
import java.util.Objects;
import java.util.function.Function;
import java.util.logging.Level;
import java.util.logging.Logger;

import static io.opentelemetry.trace.Span.Kind.SERVER;
import static org.openqa.selenium.remote.tracing.HttpTags.HTTP_REQUEST;
import static org.openqa.selenium.remote.tracing.HttpTags.HTTP_RESPONSE;
import static org.openqa.selenium.remote.tracing.HttpTracing.newSpanAsChildOf;

public class SpanWrappedHttpHandler implements HttpHandler {

private static final Logger LOG = Logger.getLogger(SpanWrappedHttpHandler.class.getName());
Expand All @@ -47,28 +53,23 @@ public SpanWrappedHttpHandler(Tracer tracer, Function<HttpRequest, String> namer
public HttpResponse execute(HttpRequest req) throws UncheckedIOException {
String name = Objects.requireNonNull(namer.apply(req), "Operation name must be set for " + req);

Span previousSpan = tracer.scopeManager().activeSpan();
SpanContext context = HttpTracing.extract(tracer, req);
Span span = tracer.buildSpan(name).asChildOf(context).ignoreActiveSpan().start();
tracer.scopeManager().activate(span);
Span span = newSpanAsChildOf(tracer, req, name).setSpanKind(SERVER).startSpan();

try {
span.setTag(Tags.SPAN_KIND, Tags.SPAN_KIND_SERVER)
.setTag(Tags.HTTP_METHOD, req.getMethod().toString())
.setTag(Tags.HTTP_URL, req.getUri());
try (Scope scope = tracer.withSpan(span)) {
HTTP_REQUEST.accept(span, req);
HttpTracing.inject(tracer, span, req);

HttpResponse res = delegate.execute(req);

span.setTag(Tags.HTTP_STATUS, res.getStatus());
HTTP_RESPONSE.accept(span, res);

return res;
} catch (Throwable t) {
span.setTag(Tags.ERROR, true);
span.setStatus(Status.UNKNOWN.withDescription(t.getMessage()));
LOG.log(Level.WARNING, "Unable to execute request: " + t.getMessage(), t);
throw t;
} finally {
span.finish();
tracer.scopeManager().activate(previousSpan);
span.end();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

package org.openqa.selenium.remote.tracing;

import io.opentracing.Tracer;
import io.opentelemetry.trace.Tracer;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.Routable;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@

package org.openqa.selenium.remote.tracing;

import io.opentracing.Span;
import io.opentracing.Tracer;
import io.opentelemetry.context.Scope;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.Tracer;

import java.util.concurrent.Callable;

Expand All @@ -36,12 +37,8 @@ public TracedCallable(Tracer tracer, Span span, Callable<T> delegate) {

@Override
public T call() throws Exception {
Span previousSpan = tracer.scopeManager().activeSpan();
tracer.scopeManager().activate(this.span);
try {
try (Scope scope = tracer.withSpan(span)) {
return delegate.call();
} finally {
tracer.scopeManager().activate(previousSpan);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

package org.openqa.selenium.remote.tracing;

import io.opentracing.Tracer;
import io.opentelemetry.trace.Tracer;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.http.HttpRequest;
Expand Down
7 changes: 3 additions & 4 deletions java/maven_deps.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@ def selenium_java_deps():
"io.netty:netty-handler:%s" % netty_version,
"io.netty:netty-transport:%s" % netty_version,
"io.opentelemetry:opentelemetry-api:0.2.0",
"io.opentelemetry:opentelemetry-exporters-logging:0.2.0",
"io.opentelemetry:opentelemetry-exporters-inmemory:0.2.0",
"io.opentracing:opentracing-api:0.33.0",
"io.opentracing:opentracing-noop:0.33.0",
"io.opentracing.contrib:opentracing-tracerresolver:0.1.8",
"io.opentelemetry:opentelemetry-exporters-jaeger:0.2.0",
"io.opentelemetry:opentelemetry-exporters-logging:0.2.0",
"io.opentelemetry:opentelemetry-sdk:0.2.0",
"it.ozimov:embedded-redis:0.7.2",
"javax.servlet:javax.servlet-api:3.1.0",
maven.artifact(
Expand Down
Loading

0 comments on commit 16a703c

Please sign in to comment.