-
Notifications
You must be signed in to change notification settings - Fork 872
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* server instrumentation with first tests * migrate to instrumenter API, move TracingFilter to library, rename module, other review refinements * change name to 1.0 and rebase * review, add ServerSpanNaming, create RestletTracing * codenarc fix * review * fix TracingFilter behaviour on exception, inline HeadersAdapter's methods * move instrumentation to doHandle, add StatusFilter in library test
- Loading branch information
Showing
18 changed files
with
850 additions
and
0 deletions.
There are no files selected for viewing
28 changes: 28 additions & 0 deletions
28
instrumentation/restlet/restlet-1.0/javaagent/build.gradle.kts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
plugins { | ||
id("otel.javaagent-instrumentation") | ||
} | ||
|
||
muzzle { | ||
pass { | ||
group.set("org.restlet") | ||
module.set("org.restlet") | ||
versions.set("[1.0.0, 1.2-M1)") | ||
assertInverse.set(true) | ||
} | ||
} | ||
|
||
repositories { | ||
mavenCentral() | ||
maven("https://maven.restlet.talend.com/") | ||
mavenLocal() | ||
} | ||
|
||
dependencies { | ||
api(project(":instrumentation:restlet:restlet-1.0:library")) | ||
|
||
library("org.restlet:org.restlet:1.1.5") | ||
library("com.noelios.restlet:com.noelios.restlet:1.1.5") | ||
|
||
implementation(project(":instrumentation:restlet:restlet-1.0:library")) | ||
testImplementation(project(":instrumentation:restlet:restlet-1.0:testing")) | ||
} |
25 changes: 25 additions & 0 deletions
25
...io/opentelemetry/javaagent/instrumentation/restlet/v1_0/RestletInstrumentationModule.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.javaagent.instrumentation.restlet.v1_0; | ||
|
||
import com.google.auto.service.AutoService; | ||
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; | ||
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
|
||
@AutoService(InstrumentationModule.class) | ||
public class RestletInstrumentationModule extends InstrumentationModule { | ||
|
||
public RestletInstrumentationModule() { | ||
super("restlet", "restlet-1.0"); | ||
} | ||
|
||
@Override | ||
public List<TypeInstrumentation> typeInstrumentations() { | ||
return Arrays.asList(new ServerInstrumentation(), new RouteInstrumentation()); | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
.../main/java/io/opentelemetry/javaagent/instrumentation/restlet/v1_0/RestletSingletons.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.javaagent.instrumentation.restlet.v1_0; | ||
|
||
import io.opentelemetry.api.GlobalOpenTelemetry; | ||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; | ||
import io.opentelemetry.instrumentation.restlet.v1_0.RestletTracing; | ||
import org.restlet.data.Request; | ||
import org.restlet.data.Response; | ||
|
||
public final class RestletSingletons { | ||
|
||
private static final Instrumenter<Request, Response> INSTRUMENTER = | ||
RestletTracing.create(GlobalOpenTelemetry.get()).getServerInstrumenter(); | ||
|
||
public static Instrumenter<Request, Response> instrumenter() { | ||
return INSTRUMENTER; | ||
} | ||
|
||
private RestletSingletons() {} | ||
} |
51 changes: 51 additions & 0 deletions
51
...in/java/io/opentelemetry/javaagent/instrumentation/restlet/v1_0/RouteInstrumentation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.javaagent.instrumentation.restlet.v1_0; | ||
|
||
import static io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming.Source.CONTROLLER; | ||
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.instrumentation.api.servlet.ServerSpanNaming; | ||
import io.opentelemetry.instrumentation.restlet.v1_0.internal.RestletServerSpanNaming; | ||
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; | ||
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; | ||
import net.bytebuddy.asm.Advice; | ||
import net.bytebuddy.description.type.TypeDescription; | ||
import net.bytebuddy.matcher.ElementMatcher; | ||
import org.restlet.Route; | ||
import org.restlet.data.Request; | ||
|
||
public class RouteInstrumentation implements TypeInstrumentation { | ||
@Override | ||
public ElementMatcher<TypeDescription> typeMatcher() { | ||
return named("org.restlet.Route"); | ||
} | ||
|
||
@Override | ||
public void transform(TypeTransformer transformer) { | ||
transformer.applyAdviceToMethod( | ||
isMethod() | ||
.and(named("beforeHandle")) | ||
.and(takesArgument(0, named("org.restlet.data.Request"))) | ||
.and(takesArgument(1, named("org.restlet.data.Response"))), | ||
this.getClass().getName() + "$RouteBeforeHandleAdvice"); | ||
} | ||
|
||
@SuppressWarnings("unused") | ||
public static class RouteBeforeHandleAdvice { | ||
|
||
@Advice.OnMethodEnter(suppress = Throwable.class) | ||
public static void getRouteInfo(@Advice.This Route route, @Advice.Argument(0) Request request) { | ||
String pattern = route.getTemplate().getPattern(); | ||
|
||
ServerSpanNaming.updateServerSpanName( | ||
currentContext(), CONTROLLER, RestletServerSpanNaming.SERVER_SPAN_NAME, pattern); | ||
} | ||
} | ||
} |
85 changes: 85 additions & 0 deletions
85
...n/java/io/opentelemetry/javaagent/instrumentation/restlet/v1_0/ServerInstrumentation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.javaagent.instrumentation.restlet.v1_0; | ||
|
||
import static io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge.currentContext; | ||
import static io.opentelemetry.javaagent.instrumentation.restlet.v1_0.RestletSingletons.instrumenter; | ||
import static net.bytebuddy.matcher.ElementMatchers.isMethod; | ||
import static net.bytebuddy.matcher.ElementMatchers.named; | ||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument; | ||
|
||
import io.opentelemetry.context.Context; | ||
import io.opentelemetry.context.Scope; | ||
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; | ||
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; | ||
import net.bytebuddy.asm.Advice; | ||
import net.bytebuddy.description.type.TypeDescription; | ||
import net.bytebuddy.matcher.ElementMatcher; | ||
import org.restlet.data.Request; | ||
import org.restlet.data.Response; | ||
|
||
public class ServerInstrumentation implements TypeInstrumentation { | ||
@Override | ||
public ElementMatcher<TypeDescription> typeMatcher() { | ||
return named("org.restlet.Server"); | ||
} | ||
|
||
@Override | ||
public void transform(TypeTransformer transformer) { | ||
transformer.applyAdviceToMethod( | ||
isMethod() | ||
.and(named("handle")) | ||
.and(takesArgument(0, named("org.restlet.data.Request"))) | ||
.and(takesArgument(1, named("org.restlet.data.Response"))), | ||
this.getClass().getName() + "$ServerHandleAdvice"); | ||
} | ||
|
||
@SuppressWarnings("unused") | ||
public static class ServerHandleAdvice { | ||
|
||
@Advice.OnMethodEnter(suppress = Throwable.class) | ||
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 parentContext = currentContext(); | ||
|
||
if (!instrumenter().shouldStart(parentContext, request)) { | ||
return; | ||
} | ||
|
||
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) { | ||
|
||
if (scope == null) { | ||
return; | ||
} | ||
|
||
scope.close(); | ||
|
||
if (exception != null) { | ||
instrumenter().end(context, request, response, exception); | ||
return; | ||
} | ||
|
||
// Restlet suppresses exceptions and sets the throwable in status | ||
Throwable statusThrowable = response.getStatus().getThrowable(); | ||
|
||
instrumenter().end(context, request, response, statusThrowable); | ||
} | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
...t/groovy/io/opentelemetry/javaagent/instrumentation/restlet/v1_0/RestletServerTest.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.javaagent.instrumentation.restlet.v1_0 | ||
|
||
import io.opentelemetry.instrumentation.restlet.v1_0.AbstractRestletServerTest | ||
import io.opentelemetry.instrumentation.test.AgentTestTrait | ||
import org.restlet.Restlet | ||
|
||
class RestletServerTest extends AbstractRestletServerTest implements AgentTestTrait { | ||
|
||
@Override | ||
Restlet wrapRestlet(Restlet restlet, String path){ | ||
return restlet | ||
} | ||
|
||
} |
20 changes: 20 additions & 0 deletions
20
instrumentation/restlet/restlet-1.0/library/build.gradle.kts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
plugins { | ||
id("otel.library-instrumentation") | ||
} | ||
|
||
repositories { | ||
mavenCentral() | ||
maven("https://maven.restlet.talend.com/") | ||
mavenLocal() | ||
} | ||
|
||
dependencies { | ||
|
||
compileOnly("com.google.auto.value:auto-value-annotations") | ||
annotationProcessor("com.google.auto.value:auto-value") | ||
|
||
library("org.restlet:org.restlet:1.1.5") | ||
library("com.noelios.restlet:com.noelios.restlet:1.1.5") | ||
|
||
testImplementation(project(":instrumentation:restlet:restlet-1.0:testing")) | ||
} |
35 changes: 35 additions & 0 deletions
35
...ary/src/main/java/io/opentelemetry/instrumentation/restlet/v1_0/RestletHeadersGetter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.instrumentation.restlet.v1_0; | ||
|
||
import io.opentelemetry.context.propagation.TextMapGetter; | ||
import java.util.Locale; | ||
import org.restlet.data.Form; | ||
import org.restlet.data.Request; | ||
|
||
final class RestletHeadersGetter implements TextMapGetter<Request> { | ||
|
||
@Override | ||
public Iterable<String> keys(Request carrier) { | ||
return getHeaders(carrier).getNames(); | ||
} | ||
|
||
@Override | ||
public String get(Request carrier, String key) { | ||
|
||
Form headers = getHeaders(carrier); | ||
|
||
String value = headers.getFirstValue(key); | ||
if (value != null) { | ||
return value; | ||
} | ||
return headers.getFirstValue(key.toLowerCase(Locale.ROOT)); | ||
} | ||
|
||
private static Form getHeaders(Request carrier) { | ||
return (Form) carrier.getAttributes().get("org.restlet.http.headers"); | ||
} | ||
} |
99 changes: 99 additions & 0 deletions
99
...in/java/io/opentelemetry/instrumentation/restlet/v1_0/RestletHttpAttributesExtractor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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_0; | ||
|
||
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 String method(Request request) { | ||
return request.getMethod().toString(); | ||
} | ||
|
||
@Override | ||
protected 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 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; | ||
} | ||
} |
Oops, something went wrong.