Convert liberty instrumentation to instrumenter api (#4205)

* Convert liberty instrumentation to instrumenter api

* review comment
This commit is contained in:
Lauri Tulmin 2021-09-28 19:22:55 +03:00 committed by GitHub
parent 0b08391413
commit 8e54d540bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 129 additions and 151 deletions

View File

@ -10,11 +10,11 @@ import static io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming.Sour
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.servlet.AppServerBridge;
import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming;
import io.opentelemetry.instrumentation.servlet.v3_0.Servlet3Accessor;
import io.opentelemetry.javaagent.instrumentation.jetty.common.JettyHelper;
import io.opentelemetry.javaagent.instrumentation.servlet.ServletInstrumenterBuilder;
import io.opentelemetry.javaagent.instrumentation.servlet.ServletRequestContext;
import io.opentelemetry.javaagent.instrumentation.servlet.ServletResponseContext;
import io.opentelemetry.javaagent.instrumentation.servlet.v3_0.Servlet3Accessor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

View File

@ -0,0 +1,48 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.liberty;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.servlet.AppServerBridge;
import io.opentelemetry.instrumentation.servlet.ServletAccessor;
import io.opentelemetry.javaagent.instrumentation.servlet.ServletHelper;
import io.opentelemetry.javaagent.instrumentation.servlet.ServletRequestContext;
import io.opentelemetry.javaagent.instrumentation.servlet.ServletResponseContext;
public class LibertyHelper<REQUEST, RESPONSE> extends ServletHelper<REQUEST, RESPONSE> {
public LibertyHelper(
Instrumenter<ServletRequestContext<REQUEST>, ServletResponseContext<RESPONSE>> instrumenter,
ServletAccessor<REQUEST, RESPONSE> accessor) {
super(instrumenter, accessor);
}
public void end(
ServletRequestContext<REQUEST> requestContext,
REQUEST request,
RESPONSE response,
Throwable throwable,
Context context,
Scope scope) {
if (scope == null) {
return;
}
scope.close();
if (throwable == null) {
throwable = AppServerBridge.getException(context);
}
ServletResponseContext<RESPONSE> responseContext =
new ServletResponseContext<>(response, throwable);
if (throwable != null || mustEndOnHandlerMethodExit(request)) {
instrumenter.end(context, requestContext, responseContext, throwable);
}
}
}

View File

@ -1,34 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.liberty;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.servlet.AppServerBridge;
import io.opentelemetry.instrumentation.servlet.v3_0.Servlet3HttpServerTracer;
import javax.servlet.http.HttpServletRequest;
public class LibertyHttpServerTracer extends Servlet3HttpServerTracer {
private static final LibertyHttpServerTracer TRACER = new LibertyHttpServerTracer();
public static LibertyHttpServerTracer tracer() {
return TRACER;
}
public Context startSpan(HttpServletRequest request) {
return startSpan(request, "HTTP " + request.getMethod(), /* servlet= */ false);
}
@Override
protected Context customizeContext(Context context, HttpServletRequest httpServletRequest) {
context = super.customizeContext(context, httpServletRequest);
return AppServerBridge.init(context);
}
@Override
protected String getInstrumentationName() {
return "io.opentelemetry.liberty";
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.liberty;
import static io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming.Source.CONTAINER;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.servlet.AppServerBridge;
import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming;
import io.opentelemetry.javaagent.instrumentation.servlet.ServletInstrumenterBuilder;
import io.opentelemetry.javaagent.instrumentation.servlet.ServletRequestContext;
import io.opentelemetry.javaagent.instrumentation.servlet.ServletResponseContext;
import io.opentelemetry.javaagent.instrumentation.servlet.v3_0.Servlet3Accessor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public final class LibertySingletons {
private static final String INSTRUMENTATION_NAME = "io.opentelemetry.liberty";
private static final Instrumenter<
ServletRequestContext<HttpServletRequest>, ServletResponseContext<HttpServletResponse>>
INSTRUMENTER =
ServletInstrumenterBuilder.<HttpServletRequest, HttpServletResponse>create()
.addContextCustomizer(
(context, request, attributes) -> {
context = ServerSpanNaming.init(context, CONTAINER);
return AppServerBridge.init(context);
})
.build(INSTRUMENTATION_NAME, Servlet3Accessor.INSTANCE);
private static final LibertyHelper<HttpServletRequest, HttpServletResponse> HELPER =
new LibertyHelper<>(INSTRUMENTER, Servlet3Accessor.INSTANCE);
public static LibertyHelper<HttpServletRequest, HttpServletResponse> helper() {
return HELPER;
}
private LibertySingletons() {}
}

View File

@ -5,16 +5,16 @@
package io.opentelemetry.javaagent.instrumentation.liberty;
import static io.opentelemetry.javaagent.instrumentation.liberty.LibertyHttpServerTracer.tracer;
import static io.opentelemetry.javaagent.instrumentation.liberty.LibertySingletons.helper;
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.instrumentation.api.servlet.AppServerBridge;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import io.opentelemetry.javaagent.instrumentation.servlet.common.service.ServletAndFilterAdviceHelper;
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
import io.opentelemetry.javaagent.instrumentation.servlet.ServletRequestContext;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
@ -70,41 +70,22 @@ public class LibertyWebAppInstrumentation implements TypeInstrumentation {
@Advice.Argument(0) ServletRequest servletRequest,
@Advice.Argument(1) ServletResponse servletResponse,
@Advice.Thrown Throwable throwable) {
ThreadLocalContext ctx = ThreadLocalContext.endRequest();
if (ctx == null) {
return;
}
Context context = ctx.getContext();
Scope scope = ctx.getScope();
if (scope == null) {
return;
}
scope.close();
if (context == null) {
// an existing span was found
ThreadLocalContext requestInfo = ThreadLocalContext.endRequest();
if (requestInfo == null) {
return;
}
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
tracer().setPrincipal(context, request);
Throwable error = throwable;
if (error == null) {
error = AppServerBridge.getException(context);
}
if (error != null) {
tracer().endExceptionally(context, error, response);
return;
}
if (ServletAndFilterAdviceHelper.mustEndOnHandlerMethodExit(tracer(), request)) {
tracer().end(context, response);
}
helper()
.end(
requestInfo.getRequestContext(),
request,
response,
throwable,
requestInfo.getContext(),
requestInfo.getScope());
}
}
@ -113,20 +94,27 @@ public class LibertyWebAppInstrumentation implements TypeInstrumentation {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onEnter() {
ThreadLocalContext ctx = ThreadLocalContext.get();
if (ctx == null || !ctx.startSpan()) {
ThreadLocalContext requestInfo = ThreadLocalContext.get();
if (requestInfo == null || !requestInfo.startSpan()) {
return;
}
Context context = tracer().startSpan(ctx.getRequest());
Context parentContext = Java8BytecodeBridge.currentContext();
ServletRequestContext<HttpServletRequest> requestContext = requestInfo.getRequestContext();
if (!helper().shouldStart(parentContext, requestContext)) {
return;
}
Context context = helper().start(parentContext, requestContext);
Scope scope = context.makeCurrent();
ctx.setContext(context);
ctx.setScope(scope);
requestInfo.setContext(context);
requestInfo.setScope(scope);
// Must be set here since Liberty RequestProcessors can use startAsync outside of servlet
// scope.
tracer().setAsyncListenerResponse(ctx.getRequest(), ctx.getResponse());
helper().setAsyncListenerResponse(requestInfo.getRequest(), requestInfo.getResponse());
}
}
}

View File

@ -7,6 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.liberty;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.instrumentation.servlet.ServletRequestContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -14,15 +15,15 @@ public class ThreadLocalContext {
private static final ThreadLocal<ThreadLocalContext> local = new ThreadLocal<>();
private final HttpServletRequest request;
private final HttpServletResponse response;
private final ServletRequestContext<HttpServletRequest> requestContext;
private Context context;
private Scope scope;
private boolean started;
private ThreadLocalContext(HttpServletRequest request, HttpServletResponse response) {
this.request = request;
this.response = response;
this.requestContext = new ServletRequestContext<>(request);
}
public Context getContext() {
@ -42,7 +43,11 @@ public class ThreadLocalContext {
}
public HttpServletRequest getRequest() {
return request;
return requestContext.request();
}
public ServletRequestContext<HttpServletRequest> getRequestContext() {
return requestContext;
}
public HttpServletResponse getResponse() {

View File

@ -17,8 +17,8 @@ muzzle {
dependencies {
compileOnly("javax.servlet:javax.servlet-api:3.0.1")
api(project(":instrumentation:servlet:servlet-3.0:library"))
api(project(":instrumentation:servlet:servlet-common:javaagent"))
api(project(":instrumentation:servlet:servlet-javax-common:library"))
testInstrumentation(project(":instrumentation:jetty:jetty-8.0:javaagent"))
testInstrumentation(project(":instrumentation:servlet:servlet-javax-common:javaagent"))
@ -29,7 +29,6 @@ dependencies {
testLibrary("org.apache.tomcat.embed:tomcat-embed-jasper:8.0.41")
// Jetty 10 seems to refuse to run on java8.
// TODO: we need to setup separate test for Jetty 10 when that is released.
latestDepTestLibrary("org.eclipse.jetty:jetty-server:9.+")
latestDepTestLibrary("org.eclipse.jetty:jetty-servlet:9.+")

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.servlet.v3_0;
package io.opentelemetry.javaagent.instrumentation.servlet.v3_0;
import io.opentelemetry.instrumentation.servlet.ServletAsyncListener;
import io.opentelemetry.instrumentation.servlet.javax.JavaxServletAccessor;

View File

@ -11,7 +11,6 @@ import static io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming.Sour
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.servlet.MappingResolver;
import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming;
import io.opentelemetry.instrumentation.servlet.v3_0.Servlet3Accessor;
import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
import io.opentelemetry.javaagent.instrumentation.servlet.ServletHelper;

View File

@ -1,9 +0,0 @@
plugins {
id("otel.library-instrumentation")
}
dependencies {
api(project(":instrumentation:servlet:servlet-javax-common:library"))
compileOnly("javax.servlet:javax.servlet-api:3.0.1")
}

View File

@ -1,54 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.servlet.v3_0;
import static io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming.Source.FILTER;
import static io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming.Source.SERVLET;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.servlet.MappingResolver;
import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming;
import io.opentelemetry.instrumentation.servlet.javax.JavaxServletHttpServerTracer;
import io.opentelemetry.instrumentation.servlet.naming.ServletSpanNameProvider;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Deprecated
public class Servlet3HttpServerTracer extends JavaxServletHttpServerTracer<HttpServletResponse> {
private static final Servlet3HttpServerTracer TRACER = new Servlet3HttpServerTracer();
private static final ServletSpanNameProvider<HttpServletRequest> SPAN_NAME_PROVIDER =
new ServletSpanNameProvider<>(Servlet3Accessor.INSTANCE);
protected Servlet3HttpServerTracer() {
super(Servlet3Accessor.INSTANCE);
}
public static Servlet3HttpServerTracer tracer() {
return TRACER;
}
public Context startSpan(
HttpServletRequest request, MappingResolver mappingResolver, boolean servlet) {
return startSpan(request, SPAN_NAME_PROVIDER.getSpanName(mappingResolver, request), servlet);
}
public Context updateContext(
Context context,
HttpServletRequest request,
MappingResolver mappingResolver,
boolean servlet) {
ServerSpanNaming.updateServerSpanName(
context,
servlet ? SERVLET : FILTER,
() -> SPAN_NAME_PROVIDER.getSpanNameOrNull(mappingResolver, request));
return addServletContextPath(context, request);
}
@Override
protected String getInstrumentationName() {
return "io.opentelemetry.servlet-3.0";
}
}

View File

@ -47,13 +47,8 @@ public class ServletHelper<REQUEST, RESPONSE> extends BaseServletHelper<REQUEST,
ServletResponseContext<RESPONSE> responseContext =
new ServletResponseContext<>(response, throwable);
if (throwable != null) {
if (throwable != null || mustEndOnHandlerMethodExit(request)) {
instrumenter.end(context, requestContext, responseContext, throwable);
return;
}
if (mustEndOnHandlerMethodExit(request)) {
instrumenter.end(context, requestContext, responseContext, null);
}
}

View File

@ -6,7 +6,7 @@
package io.opentelemetry.javaagent.instrumentation.tomcat.v7_0;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.servlet.v3_0.Servlet3Accessor;
import io.opentelemetry.javaagent.instrumentation.servlet.v3_0.Servlet3Accessor;
import io.opentelemetry.javaagent.instrumentation.servlet.v3_0.Servlet3Singletons;
import io.opentelemetry.javaagent.instrumentation.tomcat.common.TomcatHelper;
import io.opentelemetry.javaagent.instrumentation.tomcat.common.TomcatInstrumenterBuilder;

View File

@ -308,7 +308,6 @@ include(":instrumentation:servlet:servlet-common:javaagent")
include(":instrumentation:servlet:servlet-javax-common:library")
include(":instrumentation:servlet:servlet-javax-common:javaagent")
include(":instrumentation:servlet:servlet-2.2:javaagent")
include(":instrumentation:servlet:servlet-3.0:library")
include(":instrumentation:servlet:servlet-3.0:javaagent")
include(":instrumentation:servlet:servlet-5.0:javaagent")
include(":instrumentation:spark-2.3:javaagent")