Correlating Camunda process instances with telemetry IDs from logging platforms

For anyone looking at this, we solved the problem by using process instance variables and the OpenTelemetry Java API. In our code that kicks off the process instances, we did something like the following.

String operationId = Span.current().getSpanContext().getTraceId();
String spanId = Span.current().getSpanContext().getSpanId();
Map<String, Object> loggingVariables = new HashMap<String, Object>();
loggingVariables.put(LoggingVariables.OPERATION_ID, operationId);
loggingVariables.put(LoggingVariables.SPAN_ID, spanId);

ProcessInstantiationBuilder builder = ProcessEngines.getProcessEngine(PROCESS_ENGINE_NAME)
  .getRuntimeService()
  .setVariables(loggingVariables);

builder.execute();

For our delegates, we have an abstract base class named WorkflowJavaDelegate that extends the Camunda JavaDelegate interface. The WorkflowJavaDelegate class’s implementation of the execute method from the interface calls an abstract method named doExecute, which each derived class defines. In that WorkflowJavaDelegate class, we fetch the variables from the DelegateExecution object, and use them to create OpenTelemetry spans.

@Override
public void execute(DelegateExecution execution) throws Exception {
  Object operationIdObj = execution.getVariables().get(LoggingVariables.OPERATION_ID);
  Object spanIdObj = execution.getVariables().get(LoggingVariables.SPAN_ID);
  String operationId = (operationIdObj != null) ? operationIdObj.toString() : "";
  String spanId = (spanIdObj != null) ? spanIdObj.toString() : "";
  
   io.opentelemetry.context.Context context = io.opentelemetry.context.Context.root()
    .with(
        Span.wrap(
           SpanContext.create(
               operationId,
               spanId,
               TraceFlags.getSampled(),
               TraceState.getDefault())));
  
  try (Scope ignored = createLogContext(execution).makeCurrent()) {
    doExecute(execution);
  }
}
1 Like