diff --git a/.fossa.yml b/.fossa.yml index 69f579717200..9b36f19b216e 100644 --- a/.fossa.yml +++ b/.fossa.yml @@ -85,6 +85,9 @@ targets: - type: gradle path: ./ target: ':instrumentation:c3p0-0.9:library' + - type: gradle + path: ./ + target: ':instrumentation:camel-2.20:bootstrap' - type: gradle path: ./ target: ':instrumentation:camel-2.20:javaagent' diff --git a/instrumentation/camel-2.20/bootstrap/build.gradle.kts b/instrumentation/camel-2.20/bootstrap/build.gradle.kts new file mode 100644 index 000000000000..072a96df450f --- /dev/null +++ b/instrumentation/camel-2.20/bootstrap/build.gradle.kts @@ -0,0 +1,3 @@ +plugins { + id("otel.javaagent-bootstrap") +} diff --git a/instrumentation/camel-2.20/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/apachecamel/ContextWithScope.java b/instrumentation/camel-2.20/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/apachecamel/ContextWithScope.java new file mode 100644 index 000000000000..e16679df6f42 --- /dev/null +++ b/instrumentation/camel-2.20/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/apachecamel/ContextWithScope.java @@ -0,0 +1,47 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.bootstrap.apachecamel; + +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import javax.annotation.Nullable; + +public class ContextWithScope { + @Nullable private final ContextWithScope parent; + @Nullable private final Context context; + @Nullable private final Scope scope; + + public ContextWithScope(ContextWithScope parent, Context context, Scope scope) { + this.parent = parent; + this.context = context; + this.scope = scope; + } + + public static ContextWithScope activate(ContextWithScope parent, Context context) { + Scope scope = context != null ? context.makeCurrent() : null; + return new ContextWithScope(parent, context, scope); + } + + public Context getContext() { + return context; + } + + public ContextWithScope getParent() { + return parent; + } + + public void deactivate() { + if (scope == null) { + return; + } + scope.close(); + } + + @Override + public String toString() { + return "ContextWithScope [context=" + context + ", scope=" + scope + "]"; + } +} diff --git a/instrumentation/camel-2.20/javaagent/build.gradle.kts b/instrumentation/camel-2.20/javaagent/build.gradle.kts index f989bd74af05..ec81cba1cdef 100644 --- a/instrumentation/camel-2.20/javaagent/build.gradle.kts +++ b/instrumentation/camel-2.20/javaagent/build.gradle.kts @@ -30,6 +30,7 @@ dependencies { compileOnly("com.google.auto.value:auto-value-annotations") annotationProcessor("com.google.auto.value:auto-value") + bootstrap(project(":instrumentation:camel-2.20:bootstrap")) testInstrumentation(project(":instrumentation:apache-httpclient:apache-httpclient-2.0:javaagent")) testInstrumentation(project(":instrumentation:servlet:servlet-3.0:javaagent")) diff --git a/instrumentation/camel-2.20/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachecamel/ActiveContextManager.java b/instrumentation/camel-2.20/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachecamel/ActiveContextManager.java index 9816cf15c155..e07b3bf6a7d4 100644 --- a/instrumentation/camel-2.20/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachecamel/ActiveContextManager.java +++ b/instrumentation/camel-2.20/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachecamel/ActiveContextManager.java @@ -23,13 +23,11 @@ package io.opentelemetry.javaagent.instrumentation.apachecamel; -import static io.opentelemetry.javaagent.instrumentation.apachecamel.CamelSingletons.instrumenter; import static java.util.logging.Level.FINE; import io.opentelemetry.context.Context; -import io.opentelemetry.context.Scope; +import io.opentelemetry.javaagent.bootstrap.apachecamel.ContextWithScope; import java.util.logging.Logger; -import javax.annotation.Nullable; import org.apache.camel.Exchange; /** Utility class for managing active contexts as a stack associated with an exchange. */ @@ -45,13 +43,12 @@ private ActiveContextManager() {} * This method activates the supplied context for the supplied exchange. If an existing context is * found for the exchange it will be pushed onto a stack. * - * @param context The exchange - * @param request The context + * @param context The context + * @param exchange The exchange */ - public static void activate(Context context, CamelRequest request) { - Exchange exchange = request.getExchange(); + public static void activate(Context context, Exchange exchange) { ContextWithScope parent = exchange.getProperty(ACTIVE_CONTEXT_PROPERTY, ContextWithScope.class); - ContextWithScope contextWithScope = ContextWithScope.activate(parent, context, request); + ContextWithScope contextWithScope = ContextWithScope.activate(parent, context); exchange.setProperty(ACTIVE_CONTEXT_PROPERTY, contextWithScope); logger.log(FINE, "Activated a span: {0}", contextWithScope); } @@ -68,50 +65,12 @@ public static Context deactivate(Exchange exchange) { exchange.getProperty(ACTIVE_CONTEXT_PROPERTY, ContextWithScope.class); if (contextWithScope != null) { - contextWithScope.deactivate(exchange.getException()); + contextWithScope.deactivate(); exchange.setProperty(ACTIVE_CONTEXT_PROPERTY, contextWithScope.getParent()); logger.log(FINE, "Deactivated span: {0}", contextWithScope); - return contextWithScope.context; + return contextWithScope.getContext(); } return null; } - - private static class ContextWithScope { - @Nullable private final ContextWithScope parent; - @Nullable private final Context context; - private final CamelRequest request; - @Nullable private final Scope scope; - - public ContextWithScope( - ContextWithScope parent, Context context, CamelRequest request, Scope scope) { - this.parent = parent; - this.context = context; - this.request = request; - this.scope = scope; - } - - public static ContextWithScope activate( - ContextWithScope parent, Context context, CamelRequest request) { - Scope scope = context != null ? context.makeCurrent() : null; - return new ContextWithScope(parent, context, request, scope); - } - - public ContextWithScope getParent() { - return parent; - } - - public void deactivate(Exception exception) { - if (scope == null) { - return; - } - scope.close(); - instrumenter().end(context, request, null, exception); - } - - @Override - public String toString() { - return "ContextWithScope [context=" + context + ", scope=" + scope + "]"; - } - } } diff --git a/instrumentation/camel-2.20/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachecamel/CamelEventNotifier.java b/instrumentation/camel-2.20/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachecamel/CamelEventNotifier.java index f28c7e2a2987..478fc3827fc0 100644 --- a/instrumentation/camel-2.20/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachecamel/CamelEventNotifier.java +++ b/instrumentation/camel-2.20/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachecamel/CamelEventNotifier.java @@ -30,6 +30,7 @@ import io.opentelemetry.context.Context; import java.util.EventObject; import java.util.logging.Logger; +import org.apache.camel.Exchange; import org.apache.camel.management.event.ExchangeSendingEvent; import org.apache.camel.management.event.ExchangeSentEvent; import org.apache.camel.support.EventNotifierSupport; @@ -63,7 +64,7 @@ private static void onExchangeSending(ExchangeSendingEvent ese) { sd.getInitiatorSpanKind()); Context context = startOnExchangeSending(request); - ActiveContextManager.activate(context, request); + ActiveContextManager.activate(context, request.getExchange()); CamelPropagationUtil.injectParent(context, ese.getExchange().getIn().getHeaders()); logger.log(FINE, "[Exchange sending] Initiator span started: {0}", context); @@ -84,7 +85,12 @@ private static void onExchangeSent(ExchangeSentEvent event) { return; } - Context context = ActiveContextManager.deactivate(event.getExchange()); + Exchange exchange = event.getExchange(); + Context context = ActiveContextManager.deactivate(exchange); + CamelRequest request = + CamelRequest.create( + sd, exchange, event.getEndpoint(), CamelDirection.OUTBOUND, sd.getInitiatorSpanKind()); + instrumenter().end(context, request, null, exchange.getException()); logger.log(FINE, "[Exchange sent] Initiator span finished: {0}", context); } diff --git a/instrumentation/camel-2.20/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachecamel/CamelRoutePolicy.java b/instrumentation/camel-2.20/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachecamel/CamelRoutePolicy.java index 30301e3534f0..bf8919f854c0 100644 --- a/instrumentation/camel-2.20/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachecamel/CamelRoutePolicy.java +++ b/instrumentation/camel-2.20/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachecamel/CamelRoutePolicy.java @@ -56,7 +56,7 @@ private static Context spanOnExchangeBegin( return null; } Context context = instrumenter().start(parentContext, request); - ActiveContextManager.activate(context, request); + ActiveContextManager.activate(context, exchange); return context; } @@ -80,7 +80,12 @@ public void onExchangeBegin(Route route, Exchange exchange) { /** Route exchange done. Get active CAMEL span, finish, remove from CAMEL holder. */ @Override public void onExchangeDone(Route route, Exchange exchange) { + SpanDecorator sd = getSpanDecorator(route.getEndpoint()); Context context = ActiveContextManager.deactivate(exchange); + CamelRequest request = + CamelRequest.create( + sd, exchange, route.getEndpoint(), CamelDirection.INBOUND, SpanKind.INTERNAL); + instrumenter().end(context, request, null, exchange.getException()); logger.log(FINE, "[Route finished] Receiver span finished {0}", context); } } diff --git a/settings.gradle.kts b/settings.gradle.kts index fe6aa42fb942..bd441c065616 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -181,6 +181,7 @@ include(":instrumentation:azure-core:azure-core-1.36:library-instrumentation-sha include(":instrumentation:c3p0-0.9:javaagent") include(":instrumentation:c3p0-0.9:library") include(":instrumentation:c3p0-0.9:testing") +include(":instrumentation:camel-2.20:bootstrap") include(":instrumentation:camel-2.20:javaagent") include(":instrumentation:camel-2.20:javaagent-unit-tests") include(":instrumentation:cassandra:cassandra-3.0:javaagent")