JAX-RS: add code.namespace and code.function attributes (#2805)
This commit is contained in:
parent
437547d949
commit
d1ff1e12ac
|
@ -6,12 +6,14 @@
|
|||
package io.opentelemetry.javaagent.instrumentation.jaxrs.v1_0;
|
||||
|
||||
import io.opentelemetry.api.trace.Span;
|
||||
import io.opentelemetry.api.trace.SpanBuilder;
|
||||
import io.opentelemetry.api.trace.SpanKind;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.instrumentation.api.servlet.ServletContextPath;
|
||||
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
|
||||
import io.opentelemetry.instrumentation.api.tracer.ServerSpan;
|
||||
import io.opentelemetry.javaagent.instrumentation.api.ClassHierarchyIterable;
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
@ -49,7 +51,17 @@ public class JaxRsAnnotationsTracer extends BaseTracer {
|
|||
updateServerSpanName(parentContext, serverSpan, pathBasedSpanName);
|
||||
}
|
||||
|
||||
return startSpan(parentContext, spanName, SpanKind.INTERNAL);
|
||||
SpanBuilder spanBuilder = spanBuilder(parentContext, spanName, SpanKind.INTERNAL);
|
||||
setCodeAttributes(spanBuilder, target, method);
|
||||
Span span = spanBuilder.startSpan();
|
||||
return parentContext.with(span);
|
||||
}
|
||||
|
||||
private void setCodeAttributes(SpanBuilder spanBuilder, Class<?> target, Method method) {
|
||||
spanBuilder.setAttribute(SemanticAttributes.CODE_NAMESPACE, target.getName());
|
||||
if (method != null) {
|
||||
spanBuilder.setAttribute(SemanticAttributes.CODE_FUNCTION, method.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateServerSpanName(Context context, Span span, String spanName) {
|
||||
|
|
|
@ -8,6 +8,7 @@ import static io.opentelemetry.instrumentation.test.utils.ClassUtils.getClassNam
|
|||
import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderServerTrace
|
||||
|
||||
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
|
||||
import javax.ws.rs.DELETE
|
||||
import javax.ws.rs.GET
|
||||
import javax.ws.rs.HEAD
|
||||
|
@ -21,12 +22,13 @@ class JaxRsAnnotations1InstrumentationTest extends AgentInstrumentationSpecifica
|
|||
|
||||
def "instrumentation can be used as root span and resource is set to METHOD PATH"() {
|
||||
setup:
|
||||
new Jax() {
|
||||
def jax = new Jax() {
|
||||
@POST
|
||||
@Path("/a")
|
||||
void call() {
|
||||
}
|
||||
}.call()
|
||||
}
|
||||
jax.call()
|
||||
|
||||
expect:
|
||||
assertTraces(1) {
|
||||
|
@ -34,6 +36,8 @@ class JaxRsAnnotations1InstrumentationTest extends AgentInstrumentationSpecifica
|
|||
span(0) {
|
||||
name "/a"
|
||||
attributes {
|
||||
"${SemanticAttributes.CODE_NAMESPACE.key}" jax.getClass().getName()
|
||||
"${SemanticAttributes.CODE_FUNCTION.key}" "call"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -61,6 +65,8 @@ class JaxRsAnnotations1InstrumentationTest extends AgentInstrumentationSpecifica
|
|||
name "${className}.call"
|
||||
childOf span(0)
|
||||
attributes {
|
||||
"${SemanticAttributes.CODE_NAMESPACE.key}" obj.getClass().getName()
|
||||
"${SemanticAttributes.CODE_FUNCTION.key}" "call"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderSer
|
|||
|
||||
import io.dropwizard.testing.junit.ResourceTestRule
|
||||
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
|
||||
import org.junit.ClassRule
|
||||
import spock.lang.Shared
|
||||
import spock.lang.Unroll
|
||||
|
@ -47,6 +48,8 @@ class JerseyTest extends AgentInstrumentationSpecification {
|
|||
childOf span(0)
|
||||
name controllerName
|
||||
attributes {
|
||||
"${SemanticAttributes.CODE_NAMESPACE.key}" ~/Resource[$]Test*/
|
||||
"${SemanticAttributes.CODE_FUNCTION.key}" "hello"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -83,6 +86,8 @@ class JerseyTest extends AgentInstrumentationSpecification {
|
|||
name controller1Name
|
||||
kind INTERNAL
|
||||
attributes {
|
||||
"${SemanticAttributes.CODE_NAMESPACE.key}" ~/Resource[$]Test*/
|
||||
"${SemanticAttributes.CODE_FUNCTION.key}" "nested"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,11 +8,13 @@ package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
|
|||
import static io.opentelemetry.api.trace.SpanKind.INTERNAL;
|
||||
|
||||
import io.opentelemetry.api.trace.Span;
|
||||
import io.opentelemetry.api.trace.SpanBuilder;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.instrumentation.api.servlet.ServletContextPath;
|
||||
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
|
||||
import io.opentelemetry.instrumentation.api.tracer.ServerSpan;
|
||||
import io.opentelemetry.javaagent.instrumentation.api.ClassHierarchyIterable;
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
@ -48,7 +50,9 @@ public class JaxRsAnnotationsTracer extends BaseTracer {
|
|||
// We create span and immediately update its name
|
||||
// We do that in order to reuse logic inside updateSpanNames method, which is used externally as
|
||||
// well.
|
||||
Span span = spanBuilder(parentContext, "jax-rs.request", INTERNAL).startSpan();
|
||||
SpanBuilder spanBuilder = spanBuilder(parentContext, "jax-rs.request", INTERNAL);
|
||||
setCodeAttributes(spanBuilder, target, method);
|
||||
Span span = spanBuilder.startSpan();
|
||||
updateSpanNames(
|
||||
parentContext, span, ServerSpan.fromContextOrNull(parentContext), target, method);
|
||||
return parentContext.with(span);
|
||||
|
@ -56,7 +60,14 @@ public class JaxRsAnnotationsTracer extends BaseTracer {
|
|||
|
||||
public void updateSpanNames(
|
||||
Context context, Span span, Span serverSpan, Class<?> target, Method method) {
|
||||
String pathBasedSpanName = ServletContextPath.prepend(context, getPathSpanName(target, method));
|
||||
String pathBasedSpanName = getPathSpanName(target, method);
|
||||
// If path based name is empty skip prepending context path so that path based name would
|
||||
// remain as an empty string for which we skip updating span name. Path base span name is
|
||||
// empty when method and class don't have a jax-rs path annotation, this can happen when
|
||||
// creating an "abort" span, see RequestContextHelper.
|
||||
if (!pathBasedSpanName.isEmpty()) {
|
||||
pathBasedSpanName = ServletContextPath.prepend(context, pathBasedSpanName);
|
||||
}
|
||||
if (serverSpan == null) {
|
||||
updateSpanName(span, pathBasedSpanName);
|
||||
} else {
|
||||
|
@ -71,6 +82,13 @@ public class JaxRsAnnotationsTracer extends BaseTracer {
|
|||
}
|
||||
}
|
||||
|
||||
private void setCodeAttributes(SpanBuilder spanBuilder, Class<?> target, Method method) {
|
||||
spanBuilder.setAttribute(SemanticAttributes.CODE_NAMESPACE, target.getName());
|
||||
if (method != null) {
|
||||
spanBuilder.setAttribute(SemanticAttributes.CODE_FUNCTION, method.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the span name given a JaxRS annotated method. Results are cached so this method can be
|
||||
* called multiple times without significantly impacting performance.
|
||||
|
|
|
@ -8,6 +8,7 @@ import static io.opentelemetry.instrumentation.test.utils.ClassUtils.getClassNam
|
|||
import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderServerTrace
|
||||
|
||||
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
|
||||
import javax.ws.rs.DELETE
|
||||
import javax.ws.rs.GET
|
||||
import javax.ws.rs.HEAD
|
||||
|
@ -21,12 +22,13 @@ abstract class JaxRsAnnotationsInstrumentationTest extends AgentInstrumentationS
|
|||
|
||||
def "instrumentation can be used as root span and resource is set to METHOD PATH"() {
|
||||
setup:
|
||||
new Jax() {
|
||||
def jax = new Jax() {
|
||||
@POST
|
||||
@Path("/a")
|
||||
void call() {
|
||||
}
|
||||
}.call()
|
||||
}
|
||||
jax.call()
|
||||
|
||||
expect:
|
||||
assertTraces(1) {
|
||||
|
@ -34,6 +36,8 @@ abstract class JaxRsAnnotationsInstrumentationTest extends AgentInstrumentationS
|
|||
span(0) {
|
||||
name "/a"
|
||||
attributes {
|
||||
"${SemanticAttributes.CODE_NAMESPACE.key}" jax.getClass().getName()
|
||||
"${SemanticAttributes.CODE_FUNCTION.key}" "call"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -61,6 +65,8 @@ abstract class JaxRsAnnotationsInstrumentationTest extends AgentInstrumentationS
|
|||
name "${className}.call"
|
||||
childOf span(0)
|
||||
attributes {
|
||||
"${SemanticAttributes.CODE_NAMESPACE.key}" obj.getClass().getName()
|
||||
"${SemanticAttributes.CODE_FUNCTION.key}" "call"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import static io.opentelemetry.api.trace.SpanKind.SERVER
|
|||
import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderServerTrace
|
||||
|
||||
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
|
||||
import javax.ws.rs.container.ContainerRequestContext
|
||||
import javax.ws.rs.container.ContainerRequestFilter
|
||||
import javax.ws.rs.container.PreMatching
|
||||
|
@ -83,8 +84,15 @@ abstract class JaxRsFilterTest extends AgentInstrumentationSpecification {
|
|||
span(1) {
|
||||
childOf span(0)
|
||||
name controllerName
|
||||
if (!runsOnServer()) {
|
||||
if (abortPrematch) {
|
||||
attributes {
|
||||
"${SemanticAttributes.CODE_NAMESPACE.key}" "JaxRsFilterTest\$PrematchRequestFilter"
|
||||
"${SemanticAttributes.CODE_FUNCTION.key}" "filter"
|
||||
}
|
||||
} else {
|
||||
attributes {
|
||||
"${SemanticAttributes.CODE_NAMESPACE.key}" ~/Resource[$]Test*/
|
||||
"${SemanticAttributes.CODE_FUNCTION.key}" "hello"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -135,9 +143,9 @@ abstract class JaxRsFilterTest extends AgentInstrumentationSpecification {
|
|||
childOf span(0)
|
||||
name controller1Name
|
||||
kind INTERNAL
|
||||
if (!runsOnServer()) {
|
||||
attributes {
|
||||
}
|
||||
attributes {
|
||||
"${SemanticAttributes.CODE_NAMESPACE.key}" ~/Resource[$]Test*/
|
||||
"${SemanticAttributes.CODE_FUNCTION.key}" "nested"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -222,6 +222,8 @@ abstract class JaxRsHttpServerTest<S> extends HttpServerTest<S> implements Agent
|
|||
}
|
||||
childOf((SpanData) parent)
|
||||
attributes {
|
||||
"${SemanticAttributes.CODE_NAMESPACE.key}" "JaxRsTestResource"
|
||||
"${SemanticAttributes.CODE_FUNCTION.key}" methodName
|
||||
if (isCancelled) {
|
||||
"jaxrs.canceled" true
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue