Remove ResponseSingletons (#5981)

This commit is contained in:
Lauri Tulmin 2022-05-05 18:38:55 +03:00 committed by GitHub
parent 8c65b99d30
commit f43c92d244
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 191 additions and 113 deletions

View File

@ -17,6 +17,7 @@ import io.opentelemetry.javaagent.bootstrap.CallDepth;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import io.opentelemetry.javaagent.instrumentation.servlet.ServletRequestContext;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import net.bytebuddy.asm.Advice;
@ -34,7 +35,7 @@ import net.bytebuddy.matcher.ElementMatcher;
* ServletResponse, Throwable, CallDepth, ServletRequestContext, Context, Scope)} can get it from
* context and set required span attribute.
*/
public class HttpServletResponseInstrumentation implements TypeInstrumentation {
public class Servlet2HttpServletResponseInstrumentation implements TypeInstrumentation {
@Override
public ElementMatcher<ClassLoader> classLoaderOptimization() {
return hasClassesNamed("javax.servlet.http.HttpServletResponse");
@ -49,10 +50,12 @@ public class HttpServletResponseInstrumentation implements TypeInstrumentation {
public void transform(TypeTransformer transformer) {
transformer.applyAdviceToMethod(
namedOneOf("sendError", "setStatus"),
HttpServletResponseInstrumentation.class.getName() + "$Servlet2ResponseStatusAdvice");
Servlet2HttpServletResponseInstrumentation.class.getName()
+ "$Servlet2ResponseStatusAdvice");
transformer.applyAdviceToMethod(
named("sendRedirect"),
HttpServletResponseInstrumentation.class.getName() + "$Servlet2ResponseRedirectAdvice");
Servlet2HttpServletResponseInstrumentation.class.getName()
+ "$Servlet2ResponseRedirectAdvice");
}
@SuppressWarnings("unused")

View File

@ -11,14 +11,16 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.instrumentation.servlet.common.response.HttpServletResponseInstrumentation;
import io.opentelemetry.javaagent.instrumentation.servlet.common.service.ServletAndFilterInstrumentation;
import io.opentelemetry.javaagent.instrumentation.servlet.javax.response.JavaxResponseInstrumentationFactory;
import java.util.Arrays;
import java.util.List;
import net.bytebuddy.matcher.ElementMatcher;
@AutoService(InstrumentationModule.class)
public class Servlet2InstrumentationModule extends InstrumentationModule {
private static final String BASE_PACKAGE = "javax.servlet";
public Servlet2InstrumentationModule() {
super("servlet", "servlet-2.2");
}
@ -32,10 +34,13 @@ public class Servlet2InstrumentationModule extends InstrumentationModule {
@Override
public List<TypeInstrumentation> typeInstrumentations() {
return Arrays.asList(
new HttpServletResponseInstrumentation(),
new ServletAndFilterInstrumentation(
"javax.servlet",
Servlet2InstrumentationModule.class.getPackage().getName() + ".Servlet2Advice"),
JavaxResponseInstrumentationFactory.create());
new Servlet2HttpServletResponseInstrumentation(),
new ServletAndFilterInstrumentation(BASE_PACKAGE, adviceClassName(".Servlet2Advice")),
new HttpServletResponseInstrumentation(
BASE_PACKAGE, adviceClassName(".Servlet2ResponseSendAdvice")));
}
private static String adviceClassName(String suffix) {
return Servlet2InstrumentationModule.class.getPackage().getName() + suffix;
}
}

View File

@ -3,21 +3,20 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.servlet.javax.response;
package io.opentelemetry.javaagent.instrumentation.servlet.v2_2;
import static io.opentelemetry.javaagent.instrumentation.servlet.javax.response.ResponseSingletons.instrumenter;
import static io.opentelemetry.javaagent.instrumentation.servlet.v2_2.Servlet2Singletons.responseInstrumenter;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.util.ClassAndMethod;
import io.opentelemetry.javaagent.bootstrap.CallDepth;
import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge;
import io.opentelemetry.javaagent.instrumentation.servlet.common.response.HttpServletResponseAdviceHelper;
import javax.servlet.http.HttpServletResponse;
import net.bytebuddy.asm.Advice;
@SuppressWarnings("unused")
public class ResponseSendAdvice {
public class Servlet2ResponseSendAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void start(
@ -31,14 +30,14 @@ public class ResponseSendAdvice {
if (callDepth.getAndIncrement() > 0) {
return;
}
Context parentContext = Java8BytecodeBridge.currentContext();
// Don't want to generate a new top-level span
if (Java8BytecodeBridge.spanFromContext(parentContext).getSpanContext().isValid()) {
classAndMethod = ClassAndMethod.create(declaringClass, methodName);
if (instrumenter().shouldStart(parentContext, classAndMethod)) {
context = instrumenter().start(parentContext, classAndMethod);
scope = context.makeCurrent();
}
HttpServletResponseAdviceHelper.StartResult result =
HttpServletResponseAdviceHelper.startSpan(
responseInstrumenter(), declaringClass, methodName);
if (result != null) {
classAndMethod = result.getClassAndMethod();
context = result.getContext();
scope = result.getScope();
}
}
@ -52,7 +51,8 @@ public class ResponseSendAdvice {
if (callDepth.decrementAndGet() > 0) {
return;
}
HttpServletResponseAdviceHelper.stopSpan(
instrumenter(), throwable, context, scope, classAndMethod);
responseInstrumenter(), throwable, context, scope, classAndMethod);
}
}

View File

@ -7,9 +7,11 @@ package io.opentelemetry.javaagent.instrumentation.servlet.v2_2;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
import io.opentelemetry.instrumentation.api.util.ClassAndMethod;
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.common.response.ResponseInstrumenterFactory;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -17,6 +19,7 @@ public final class Servlet2Singletons {
private static final String INSTRUMENTATION_NAME = "io.opentelemetry.servlet-2.2";
private static final Servlet2Helper HELPER;
private static final Instrumenter<ClassAndMethod, Void> RESPONSE_INSTRUMENTER;
static {
Servlet2HttpAttributesGetter httpAttributesGetter =
@ -35,11 +38,16 @@ public final class Servlet2Singletons {
httpAttributesGetter);
HELPER = new Servlet2Helper(instrumenter);
RESPONSE_INSTRUMENTER = ResponseInstrumenterFactory.createInstrumenter(INSTRUMENTATION_NAME);
}
public static Servlet2Helper helper() {
return HELPER;
}
public static Instrumenter<ClassAndMethod, Void> responseInstrumenter() {
return RESPONSE_INSTRUMENTER;
}
private Servlet2Singletons() {}
}

View File

@ -14,8 +14,8 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.instrumentation.servlet.common.async.AsyncContextInstrumentation;
import io.opentelemetry.javaagent.instrumentation.servlet.common.async.AsyncContextStartInstrumentation;
import io.opentelemetry.javaagent.instrumentation.servlet.common.async.AsyncStartInstrumentation;
import io.opentelemetry.javaagent.instrumentation.servlet.common.response.HttpServletResponseInstrumentation;
import io.opentelemetry.javaagent.instrumentation.servlet.common.service.ServletAndFilterInstrumentation;
import io.opentelemetry.javaagent.instrumentation.servlet.javax.response.JavaxResponseInstrumentationFactory;
import java.util.List;
import net.bytebuddy.matcher.ElementMatcher;
@ -44,7 +44,8 @@ public class Servlet3InstrumentationModule extends InstrumentationModule {
adviceClassName(".Servlet3Advice"),
adviceClassName(".Servlet3InitAdvice"),
adviceClassName(".Servlet3FilterInitAdvice")),
JavaxResponseInstrumentationFactory.create());
new HttpServletResponseInstrumentation(
BASE_PACKAGE, adviceClassName(".Servlet3ResponseSendAdvice")));
}
private static String adviceClassName(String suffix) {

View File

@ -0,0 +1,58 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.servlet.v3_0;
import static io.opentelemetry.javaagent.instrumentation.servlet.v3_0.Servlet3Singletons.responseInstrumenter;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.util.ClassAndMethod;
import io.opentelemetry.javaagent.bootstrap.CallDepth;
import io.opentelemetry.javaagent.instrumentation.servlet.common.response.HttpServletResponseAdviceHelper;
import javax.servlet.http.HttpServletResponse;
import net.bytebuddy.asm.Advice;
@SuppressWarnings("unused")
public class Servlet3ResponseSendAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void start(
@Advice.Origin("#t") Class<?> declaringClass,
@Advice.Origin("#m") String methodName,
@Advice.Local("otelMethod") ClassAndMethod classAndMethod,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope,
@Advice.Local("otelCallDepth") CallDepth callDepth) {
callDepth = CallDepth.forClass(HttpServletResponse.class);
if (callDepth.getAndIncrement() > 0) {
return;
}
HttpServletResponseAdviceHelper.StartResult result =
HttpServletResponseAdviceHelper.startSpan(
responseInstrumenter(), declaringClass, methodName);
if (result != null) {
classAndMethod = result.getClassAndMethod();
context = result.getContext();
scope = result.getScope();
}
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void stopSpan(
@Advice.Thrown Throwable throwable,
@Advice.Local("otelMethod") ClassAndMethod classAndMethod,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope,
@Advice.Local("otelCallDepth") CallDepth callDepth) {
if (callDepth.decrementAndGet() > 0) {
return;
}
HttpServletResponseAdviceHelper.stopSpan(
responseInstrumenter(), throwable, context, scope, classAndMethod);
}
}

View File

@ -7,11 +7,13 @@ package io.opentelemetry.javaagent.instrumentation.servlet.v3_0;
import io.opentelemetry.instrumentation.api.field.VirtualField;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.util.ClassAndMethod;
import io.opentelemetry.javaagent.bootstrap.servlet.MappingResolver;
import io.opentelemetry.javaagent.instrumentation.servlet.ServletHelper;
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.common.response.ResponseInstrumenterFactory;
import javax.servlet.Filter;
import javax.servlet.Servlet;
import javax.servlet.http.HttpServletRequest;
@ -34,10 +36,17 @@ public final class Servlet3Singletons {
private static final VirtualField<Filter, MappingResolver.Factory> FILTER_MAPPING_RESOLVER =
VirtualField.find(Filter.class, MappingResolver.Factory.class);
private static final Instrumenter<ClassAndMethod, Void> RESPONSE_INSTRUMENTER =
ResponseInstrumenterFactory.createInstrumenter(INSTRUMENTATION_NAME);
public static ServletHelper<HttpServletRequest, HttpServletResponse> helper() {
return HELPER;
}
public static Instrumenter<ClassAndMethod, Void> responseInstrumenter() {
return RESPONSE_INSTRUMENTER;
}
public static MappingResolver getMappingResolver(Object servletOrFilter) {
MappingResolver.Factory factory = getMappingResolverFactory(servletOrFilter);
if (factory != null) {

View File

@ -7,11 +7,13 @@ package io.opentelemetry.javaagent.instrumentation.servlet.v5_0;
import io.opentelemetry.instrumentation.api.field.VirtualField;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.util.ClassAndMethod;
import io.opentelemetry.javaagent.bootstrap.servlet.MappingResolver;
import io.opentelemetry.javaagent.instrumentation.servlet.ServletHelper;
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.common.response.ResponseInstrumenterFactory;
import jakarta.servlet.Filter;
import jakarta.servlet.Servlet;
import jakarta.servlet.http.HttpServletRequest;
@ -35,10 +37,17 @@ public final class Servlet5Singletons {
private static final VirtualField<Filter, MappingResolver.Factory> FILTER_MAPPING_RESOLVER =
VirtualField.find(Filter.class, MappingResolver.Factory.class);
private static final Instrumenter<ClassAndMethod, Void> RESPONSE_INSTRUMENTER =
ResponseInstrumenterFactory.createInstrumenter(INSTRUMENTATION_NAME);
public static ServletHelper<HttpServletRequest, HttpServletResponse> helper() {
return HELPER;
}
public static Instrumenter<ClassAndMethod, Void> responseInstrumenter() {
return RESPONSE_INSTRUMENTER;
}
public static MappingResolver getMappingResolver(Object servletOrFilter) {
MappingResolver.Factory factory = getMappingResolverFactory(servletOrFilter);
if (factory != null) {

View File

@ -5,13 +5,12 @@
package io.opentelemetry.javaagent.instrumentation.servlet.v5_0.response;
import static io.opentelemetry.javaagent.instrumentation.servlet.v5_0.response.ResponseSingletons.instrumenter;
import static io.opentelemetry.javaagent.instrumentation.servlet.v5_0.Servlet5Singletons.responseInstrumenter;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.util.ClassAndMethod;
import io.opentelemetry.javaagent.bootstrap.CallDepth;
import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge;
import io.opentelemetry.javaagent.instrumentation.servlet.common.response.HttpServletResponseAdviceHelper;
import jakarta.servlet.http.HttpServletResponse;
import net.bytebuddy.asm.Advice;
@ -33,14 +32,13 @@ public class ResponseSendAdvice {
return;
}
Context parentContext = Java8BytecodeBridge.currentContext();
// Don't want to generate a new top-level span
if (Java8BytecodeBridge.spanFromContext(parentContext).getSpanContext().isValid()) {
classAndMethod = ClassAndMethod.create(declaringClass, methodName);
if (instrumenter().shouldStart(parentContext, classAndMethod)) {
context = instrumenter().start(parentContext, classAndMethod);
scope = context.makeCurrent();
}
HttpServletResponseAdviceHelper.StartResult result =
HttpServletResponseAdviceHelper.startSpan(
responseInstrumenter(), declaringClass, methodName);
if (result != null) {
classAndMethod = result.getClassAndMethod();
context = result.getContext();
scope = result.getScope();
}
}
@ -54,7 +52,8 @@ public class ResponseSendAdvice {
if (callDepth.decrementAndGet() > 0) {
return;
}
HttpServletResponseAdviceHelper.stopSpan(
instrumenter(), throwable, context, scope, classAndMethod);
responseInstrumenter(), throwable, context, scope, classAndMethod);
}
}

View File

@ -1,27 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.servlet.v5_0.response;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.util.ClassAndMethod;
import io.opentelemetry.instrumentation.api.util.SpanNames;
public class ResponseSingletons {
private static final Instrumenter<ClassAndMethod, Void> INSTRUMENTER;
static {
INSTRUMENTER =
Instrumenter.<ClassAndMethod, Void>builder(
GlobalOpenTelemetry.get(), "io.opentelemetry.servlet-5.0", SpanNames::fromMethod)
.newInstrumenter();
}
public static Instrumenter<ClassAndMethod, Void> instrumenter() {
return INSTRUMENTER;
}
}

View File

@ -9,8 +9,50 @@ import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.util.ClassAndMethod;
import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge;
public class HttpServletResponseAdviceHelper {
public static StartResult startSpan(
Instrumenter<ClassAndMethod, Void> instrumenter, Class<?> declaringClass, String methodName) {
Context parentContext = Java8BytecodeBridge.currentContext();
// Don't want to generate a new top-level span
if (Java8BytecodeBridge.spanFromContext(parentContext).getSpanContext().isValid()) {
ClassAndMethod classAndMethod = ClassAndMethod.create(declaringClass, methodName);
if (instrumenter.shouldStart(parentContext, classAndMethod)) {
Context context = instrumenter.start(parentContext, classAndMethod);
Scope scope = context.makeCurrent();
return new StartResult(classAndMethod, context, scope);
}
}
return null;
}
public static final class StartResult {
private final ClassAndMethod classAndMethod;
private final Context context;
private final Scope scope;
private StartResult(ClassAndMethod classAndMethod, Context context, Scope scope) {
this.classAndMethod = classAndMethod;
this.context = context;
this.scope = scope;
}
public ClassAndMethod getClassAndMethod() {
return classAndMethod;
}
public Context getContext() {
return context;
}
public Scope getScope() {
return scope;
}
}
public static void stopSpan(
Instrumenter<ClassAndMethod, Void> instrumenter,
Throwable throwable,

View File

@ -0,0 +1,22 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.servlet.common.response;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.util.ClassAndMethod;
import io.opentelemetry.instrumentation.api.util.SpanNames;
public final class ResponseInstrumenterFactory {
public static Instrumenter<ClassAndMethod, Void> createInstrumenter(String instrumentationName) {
return Instrumenter.<ClassAndMethod, Void>builder(
GlobalOpenTelemetry.get(), instrumentationName, SpanNames::fromMethod)
.newInstrumenter();
}
private ResponseInstrumenterFactory() {}
}

View File

@ -1,22 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.servlet.javax.response;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.instrumentation.servlet.common.response.HttpServletResponseInstrumentation;
public final class JavaxResponseInstrumentationFactory {
private static final String BASE_PACKAGE = "javax.servlet";
public static TypeInstrumentation create() {
return new HttpServletResponseInstrumentation(
BASE_PACKAGE,
JavaxResponseInstrumentationFactory.class.getPackage().getName() + ".ResponseSendAdvice");
}
private JavaxResponseInstrumentationFactory() {}
}

View File

@ -1,29 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.servlet.javax.response;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.util.ClassAndMethod;
import io.opentelemetry.instrumentation.api.util.SpanNames;
public class ResponseSingletons {
private static final Instrumenter<ClassAndMethod, Void> INSTRUMENTER;
static {
INSTRUMENTER =
Instrumenter.<ClassAndMethod, Void>builder(
GlobalOpenTelemetry.get(),
"io.opentelemetry.servlet-javax-common",
SpanNames::fromMethod)
.newInstrumenter();
}
public static Instrumenter<ClassAndMethod, Void> instrumenter() {
return INSTRUMENTER;
}
}