Skip to content

Commit

Permalink
migrate to instrumenter API, move TracingFilter to library, rename mo…
Browse files Browse the repository at this point in the history
…dule, other review refinements
  • Loading branch information
anosek-an committed Sep 3, 2021
1 parent 89e6485 commit cf73b9c
Show file tree
Hide file tree
Showing 18 changed files with 340 additions and 191 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ muzzle {
pass {
group.set("org.restlet")
module.set("org.restlet")
versions.set("[1.0.0, 1.2.0)")
versions.set("[1.0.0, 1.2-M1)")
}
}

Expand All @@ -17,10 +17,10 @@ repositories {
}

dependencies {
api(project(":instrumentation:restlet:restlet-core-1.1:library"))
api(project(":instrumentation:restlet:restlet-1.1:library"))

library("org.restlet:org.restlet:1.1.5")
library("com.noelios.restlet:com.noelios.restlet:1.1.5")
implementation(project(":instrumentation:restlet:restlet-core-1.1:library"))
testImplementation(project(":instrumentation:restlet:restlet-core-1.1:testing"))
implementation(project(":instrumentation:restlet:restlet-1.1:library"))
testImplementation(project(":instrumentation:restlet:restlet-1.1:testing"))
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
public class RestletInstrumentationModule extends InstrumentationModule {

public RestletInstrumentationModule() {
super("restlet-core", "restlet-core-1.1");
super("restlet", "restlet-1.1");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@

package io.opentelemetry.javaagent.instrumentation.restlet.v1_1;

import static io.opentelemetry.instrumentation.restlet.v1_1.RestletHttpServerTracer.tracer;
import static io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge.currentContext;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;

import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.tracer.ServerSpan;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import net.bytebuddy.asm.Advice;
Expand Down Expand Up @@ -45,7 +47,9 @@ public static void getRouteInfo(@Advice.This Route route, @Advice.Argument(0) Re
return;
}

Span serverSpan = tracer().getServerSpan(request);
Context context = currentContext();

Span serverSpan = ServerSpan.fromContextOrNull(context);

if (serverSpan == null) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

package io.opentelemetry.javaagent.instrumentation.restlet.v1_1;

import static io.opentelemetry.instrumentation.restlet.v1_1.RestletHttpServerTracer.tracer;
import static io.opentelemetry.instrumentation.restlet.v1_1.RestletSingletons.instrumenter;
import static io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge.currentContext;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
Expand Down Expand Up @@ -43,52 +44,46 @@ public static class ServerHandleAdvice {
public static void beginRequest(
@Advice.Argument(0) Request request,
@Advice.Argument(1) Response response,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {

Context serverContext = tracer().getServerContext(request);
Context parentContext = currentContext();

if (serverContext != null) {
if (!instrumenter().shouldStart(parentContext, request)) {
return;
}

serverContext =
tracer().startSpan(request, request, request, request.getResourceRef().getPath());
scope = serverContext.makeCurrent();
context = instrumenter().start(parentContext, request);
scope = context.makeCurrent();
}

@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void finishRequest(
@Advice.Argument(0) Request request,
@Advice.Argument(1) Response response,
@Advice.Thrown Throwable exception,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {

Context serverContext = tracer().getServerContext(request);

if (scope == null) {
return;
}

scope.close();

if (serverContext == null) {
if (context == null) {
return;
}

if (exception != null) {
tracer().endExceptionally(serverContext, exception, response);
instrumenter().end(context, request, response, exception);
return;
}

// Restlet suppresses exceptions and sets the throwable in status
Throwable statusThrowable = response.getStatus().getThrowable();

if (statusThrowable != null) {
tracer().endExceptionally(serverContext, statusThrowable, response);
return;
}

tracer().end(serverContext, response);
instrumenter().end(context, request, response, statusThrowable);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ dependencies {
library("org.restlet:org.restlet:1.1.5")
library("com.noelios.restlet:com.noelios.restlet:1.1.5")

testImplementation(project(":instrumentation:restlet:restlet-core-1.1:testing"))
testImplementation(project(":instrumentation:restlet:restlet-1.1:testing"))
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
import io.opentelemetry.context.propagation.TextMapGetter;
import org.restlet.data.Request;

final class RestletExtractAdapter implements TextMapGetter<Request> {
final class RestletHeadersGetter implements TextMapGetter<Request> {

static final RestletExtractAdapter GETTER = new RestletExtractAdapter();
static final RestletHeadersGetter GETTER = new RestletHeadersGetter();

@Override
public Iterable<String> keys(Request carrier) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.restlet.v1_1;

import io.opentelemetry.instrumentation.api.instrumenter.http.HttpAttributesExtractor;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.restlet.data.Reference;
import org.restlet.data.Request;
import org.restlet.data.Response;

final class RestletHttpAttributesExtractor extends HttpAttributesExtractor<Request, Response> {
@Override
protected @Nullable String method(Request request) {
return request.getMethod().toString();
}

@Override
protected @Nullable String url(Request request) {
return request.getOriginalRef().toString();
}

@Override
protected @Nullable String target(Request request) {
Reference ref = request.getOriginalRef();
String path = ref.getPath();
return ref.hasQuery() ? path + "?" + ref.getQuery() : path;
}

@Override
protected @Nullable String host(Request request) {
return null;
}

@Override
protected @Nullable String route(Request request) {
return null;
}

@Override
protected @Nullable String scheme(Request request) {
return request.getOriginalRef().getScheme();
}

@Override
protected @Nullable String userAgent(Request request) {
return request.getClientInfo().getAgent();
}

@Override
protected @Nullable Long requestContentLength(Request request, @Nullable Response response) {
return null;
}

@Override
protected @Nullable Long requestContentLengthUncompressed(
Request request, @Nullable Response response) {
return null;
}

@Override
protected @Nullable String flavor(Request request, @Nullable Response response) {
String version = (String) request.getAttributes().get("org.restlet.http.version");
switch (version) {
case "HTTP/1.0":
return SemanticAttributes.HttpFlavorValues.HTTP_1_0;
case "HTTP/1.1":
return SemanticAttributes.HttpFlavorValues.HTTP_1_1;
case "HTTP/2.0":
return SemanticAttributes.HttpFlavorValues.HTTP_2_0;
default:
// fall through
}
return null;
}

@Override
protected @Nullable String serverName(Request request, @Nullable Response response) {
return null;
}

@Override
protected @Nullable Integer statusCode(Request request, Response response) {
return response.getStatus().getCode();
}

@Override
protected @Nullable Long responseContentLength(Request request, Response response) {
return null;
}

@Override
protected @Nullable Long responseContentLengthUncompressed(Request request, Response response) {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.restlet.v1_1;

import io.opentelemetry.instrumentation.api.instrumenter.net.NetAttributesExtractor;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.restlet.data.Request;
import org.restlet.data.Response;

final class RestletNetAttributesExtractor extends NetAttributesExtractor<Request, Response> {
@Override
public String transport(Request request) {
return SemanticAttributes.NetTransportValues.IP_TCP;
}

@Override
public @Nullable String peerName(Request request, @Nullable Response response) {
return request.getHostRef().getUserInfo();
}

@Override
public @Nullable Integer peerPort(Request request, @Nullable Response response) {
return request.getClientInfo().getPort();
}

@Override
public @Nullable String peerIp(Request request, @Nullable Response response) {
return request.getClientInfo().getAddress();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.restlet.v1_1;

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.context.propagation.TextMapGetter;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.SpanStatusExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.net.NetAttributesExtractor;
import org.restlet.data.Request;
import org.restlet.data.Response;

public final class RestletSingletons {

private static final String INSTRUMENTATION_NAME = "io.opentelemetry.restlet-1.1";

private static final Instrumenter<Request, Response> INSTRUMENTER;

static {
HttpAttributesExtractor<Request, Response> httpAttributesExtractor =
new RestletHttpAttributesExtractor();
SpanNameExtractor<Request> spanNameExtractor =
HttpSpanNameExtractor.create(httpAttributesExtractor);
SpanStatusExtractor<Request, Response> spanStatusExtractor =
HttpSpanStatusExtractor.create(httpAttributesExtractor);
NetAttributesExtractor<Request, Response> netAttributesExtractor =
new RestletNetAttributesExtractor();

OpenTelemetry openTelemetry = GlobalOpenTelemetry.get();

INSTRUMENTER =
Instrumenter.<Request, Response>newBuilder(
openTelemetry, INSTRUMENTATION_NAME, spanNameExtractor)
.setSpanStatusExtractor(spanStatusExtractor)
.addAttributesExtractor(httpAttributesExtractor)
.addAttributesExtractor(netAttributesExtractor)
.newServerInstrumenter(RestletHeadersGetter.GETTER);
}

public static Instrumenter<Request, Response> instrumenter() {
return INSTRUMENTER;
}

public static TextMapGetter<Request> getter() {
return RestletHeadersGetter.GETTER;
}

private RestletSingletons() {}
}
Loading

0 comments on commit cf73b9c

Please sign in to comment.