-
Notifications
You must be signed in to change notification settings - Fork 1k
Added initial commit of camunda instrumentation #12830
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 36 commits
a631796
979c377
4fbdbf8
7b268c0
c6aa4c2
80b0e67
b267316
fb19def
b44bc9d
26df3f1
9fb1aed
d7f179f
308f6a8
fd44b57
bdd9ea1
628d839
75f3fdc
0cd3185
3f9833a
38ff7f0
7fcfa7d
da9e851
4355c63
c5718bc
193cd63
d60eaf3
cc90160
6e797eb
e484aa7
f938b85
2aa9616
3277d7e
a3fd09c
1f4d357
0c9ac2d
ad4f524
0a2a414
bcf17bf
7aa48b4
096fb01
d0d2c6c
4f13543
305c58a
5e151e3
1298c3f
b6d1b32
35ae48e
bb18387
9e5df91
78bc660
62e9317
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| plugins { | ||
| id("otel.javaagent-instrumentation") | ||
| } | ||
|
|
||
| muzzle { | ||
| pass { | ||
| group.set("org.camunda.bpm") | ||
| module.set("camunda-engine") | ||
|
|
||
| // have not tested with versions prior to 7.18.0 | ||
| versions.set("[7.18.0,)") | ||
| extraDependency("org.camunda.bpm:camunda-external-task-client:7.18.0") | ||
| } | ||
| } | ||
|
|
||
| dependencies { | ||
| implementation(project(":instrumentation:camunda:camunda-7.0:library")) | ||
|
|
||
| library("org.camunda.bpm:camunda-engine:7.18.0") | ||
| library("org.camunda.bpm:camunda-external-task-client:7.18.0") | ||
|
|
||
| annotationProcessor("com.google.auto.value:auto-value:1.6") | ||
|
|
||
| testImplementation(project(":instrumentation:camunda:camunda-7.0:testing")) | ||
| testImplementation("com.h2database:h2:2.2.224") | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| /* | ||
| * Copyright The OpenTelemetry Authors | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| package io.opentelemetry.javaagent.instrumentation.camunda.v7_0.behavior; | ||
|
|
||
| import io.opentelemetry.api.GlobalOpenTelemetry; | ||
| import io.opentelemetry.api.OpenTelemetry; | ||
| import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; | ||
| import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder; | ||
| import io.opentelemetry.instrumentation.camunda.v7_0.behavior.CamundaBehaviorSpanNameExtractor; | ||
| import io.opentelemetry.instrumentation.camunda.v7_0.common.CamundaCommonRequest; | ||
| import io.opentelemetry.instrumentation.camunda.v7_0.common.CamundaVariableAttributeExtractor; | ||
|
|
||
| public class CamundaBehaviorSingletons { | ||
|
|
||
| private static final Instrumenter<CamundaCommonRequest, String> instrumenter; | ||
|
|
||
| private static final OpenTelemetry opentelemetry; | ||
|
|
||
| static { | ||
| opentelemetry = GlobalOpenTelemetry.get(); | ||
|
|
||
| InstrumenterBuilder<CamundaCommonRequest, String> builder = | ||
cb645j marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Instrumenter.<CamundaCommonRequest, String>builder( | ||
| opentelemetry, | ||
| "io.opentelemetry.camunda-behavior", | ||
cb645j marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| new CamundaBehaviorSpanNameExtractor()) | ||
| .addAttributesExtractor(new CamundaVariableAttributeExtractor()); | ||
|
|
||
| instrumenter = builder.buildInstrumenter(); | ||
| } | ||
|
|
||
| public static OpenTelemetry getOpentelemetry() { | ||
| return opentelemetry; | ||
| } | ||
|
|
||
| public static Instrumenter<CamundaCommonRequest, String> getInstumenter() { | ||
| return instrumenter; | ||
| } | ||
|
|
||
| private CamundaBehaviorSingletons() {} | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| /* | ||
| * Copyright The OpenTelemetry Authors | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| package io.opentelemetry.javaagent.instrumentation.camunda.v7_0.behavior; | ||
|
|
||
| import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; | ||
| import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasSuperType; | ||
| import static io.opentelemetry.javaagent.instrumentation.camunda.v7_0.behavior.CamundaBehaviorSingletons.getInstumenter; | ||
| import static io.opentelemetry.javaagent.instrumentation.camunda.v7_0.behavior.CamundaBehaviorSingletons.getOpentelemetry; | ||
| import static net.bytebuddy.matcher.ElementMatchers.named; | ||
|
|
||
| import io.opentelemetry.api.trace.SpanContext; | ||
| import io.opentelemetry.context.Context; | ||
| import io.opentelemetry.context.Scope; | ||
| import io.opentelemetry.instrumentation.camunda.v7_0.behavior.CamundaActivityExecutionGetter; | ||
| import io.opentelemetry.instrumentation.camunda.v7_0.behavior.CamundaVariableMapSetter; | ||
| import io.opentelemetry.instrumentation.camunda.v7_0.common.CamundaCommonRequest; | ||
| import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; | ||
| import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; | ||
| import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; | ||
| import java.util.Optional; | ||
| import net.bytebuddy.asm.Advice; | ||
| import net.bytebuddy.description.type.TypeDescription; | ||
| import net.bytebuddy.matcher.ElementMatcher; | ||
| import net.bytebuddy.matcher.ElementMatchers; | ||
| import org.camunda.bpm.engine.impl.pvm.delegate.ActivityExecution; | ||
| import org.camunda.bpm.engine.variable.VariableMap; | ||
|
|
||
| public class CamundaCallableElementActivityBehaviorInstrumentation implements TypeInstrumentation { | ||
|
|
||
| @Override | ||
| public ElementMatcher<ClassLoader> classLoaderOptimization() { | ||
| return hasClassesNamed( | ||
| "org.camunda.bpm.engine.impl.bpmn.behavior.CallableElementActivityBehavior"); | ||
| } | ||
|
|
||
| @Override | ||
| public ElementMatcher<TypeDescription> typeMatcher() { | ||
| return hasSuperType( | ||
| named("org.camunda.bpm.engine.impl.bpmn.behavior.CallableElementActivityBehavior")); | ||
| } | ||
|
|
||
| @Override | ||
| public void transform(TypeTransformer transformer) { | ||
| transformer.applyAdviceToMethod( | ||
| ElementMatchers.isMethod().and(ElementMatchers.named("startInstance")), | ||
cb645j marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| this.getClass().getName() + "$CamundaCallableElementActivityBehaviorAdvice"); | ||
| } | ||
|
|
||
| @SuppressWarnings("unused") | ||
| public static class CamundaCallableElementActivityBehaviorAdvice { | ||
|
|
||
| @Advice.OnMethodEnter(suppress = Throwable.class) | ||
| public static void addTracingEnter( | ||
| @Advice.Argument(0) ActivityExecution execution, | ||
| @Advice.Argument(1) VariableMap variables, | ||
| @Advice.Local("request") CamundaCommonRequest request, | ||
| @Advice.Local("otelParentScope") Scope parentScope, | ||
| @Advice.Local("otelContext") Context context, | ||
| @Advice.Local("otelScope") Scope scope) { | ||
|
|
||
| if (execution == null) { | ||
| // log warning | ||
cb645j marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return; | ||
| } | ||
|
|
||
| request = new CamundaCommonRequest(); | ||
| request.setProcessDefinitionId(Optional.ofNullable(execution.getProcessDefinitionId())); | ||
| request.setProcessInstanceId(Optional.ofNullable(execution.getProcessInstanceId())); | ||
| request.setActivityId(Optional.ofNullable(execution.getCurrentActivityId())); | ||
| request.setActivityName(Optional.ofNullable(execution.getCurrentActivityName())); | ||
| request.setBusinessKey(Optional.ofNullable(execution.getProcessBusinessKey())); | ||
|
|
||
| Context parentContext = | ||
| getOpentelemetry() | ||
| .getPropagators() | ||
| .getTextMapPropagator() | ||
| .extract( | ||
| Java8BytecodeBridge.currentContext(), | ||
| execution, | ||
| new CamundaActivityExecutionGetter()); | ||
|
|
||
| parentScope = parentContext.makeCurrent(); | ||
|
|
||
| if (getInstumenter().shouldStart(Java8BytecodeBridge.currentContext(), request)) { | ||
| context = getInstumenter().start(Java8BytecodeBridge.currentContext(), request); | ||
| scope = context.makeCurrent(); | ||
|
|
||
| // Inject subflow trace context as pi variables so they are propagated and | ||
| // accessible | ||
|
|
||
| SpanContext currentSpanContext = | ||
| Java8BytecodeBridge.spanFromContext(context).getSpanContext(); | ||
| if (currentSpanContext.isValid()) { | ||
| getOpentelemetry() | ||
| .getPropagators() | ||
| .getTextMapPropagator() | ||
| .inject(context, variables, new CamundaVariableMapSetter()); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) | ||
| public static void closeTrace( | ||
| @Advice.Argument(0) ActivityExecution execution, | ||
| @Advice.Local("request") CamundaCommonRequest request, | ||
| @Advice.Local("otelParentScope") Scope parentScope, | ||
| @Advice.Local("otelContext") Context context, | ||
| @Advice.Local("otelScope") Scope scope, | ||
| @Advice.Thrown Throwable throwable) { | ||
|
|
||
| if (context != null && scope != null) { | ||
| getInstumenter().end(context, request, "NA", throwable); | ||
cb645j marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| scope.close(); | ||
| } | ||
|
|
||
| if (parentScope != null) { | ||
| parentScope.close(); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| /* | ||
| * Copyright The OpenTelemetry Authors | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| package io.opentelemetry.javaagent.instrumentation.camunda.v7_0.behavior; | ||
|
|
||
| import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; | ||
|
|
||
| import com.google.auto.service.AutoService; | ||
| import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; | ||
| import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; | ||
| import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; | ||
| import java.util.Arrays; | ||
| import java.util.Collections; | ||
| import java.util.List; | ||
| import net.bytebuddy.matcher.ElementMatcher; | ||
|
|
||
| @AutoService(InstrumentationModule.class) | ||
| public class CamundaCallableElementActivityBehaviorModule extends InstrumentationModule { | ||
|
|
||
| public CamundaCallableElementActivityBehaviorModule() { | ||
| super("camunda", "camunda-7.0", "camunda-behavior", "camunda-behavior-7_18"); | ||
cb645j marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| @Override | ||
| public boolean defaultEnabled(ConfigProperties config) { | ||
| return config.getBoolean("otel.instrumentation.common.default-enabled", true); | ||
| } | ||
|
||
|
|
||
| @Override | ||
| public List<TypeInstrumentation> typeInstrumentations() { | ||
| return Collections.singletonList(new CamundaCallableElementActivityBehaviorInstrumentation()); | ||
| } | ||
|
|
||
| @Override | ||
| public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() { | ||
| return hasClassesNamed( | ||
| "org.camunda.bpm.engine.impl.bpmn.behavior.CallableElementActivityBehavior"); | ||
| } | ||
|
|
||
| String[] helperClassnames = { | ||
| "io.opentelemetry.javaagent.instrumentation.camunda.v7_0.behavior", | ||
| "io.opentelemetry.instrumentation.camunda.v7_0.behavior", | ||
| "io.opentelemetry.instrumentation.camunda.v7_0.common" | ||
| }; | ||
|
|
||
| @Override | ||
| public boolean isHelperClass(String classname) { | ||
| return super.isHelperClass(classname) | ||
| || Arrays.stream(helperClassnames).anyMatch(c -> classname.startsWith(c)); | ||
| } | ||
cb645j marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.