Automatic OpenTelemetry instrumentation for CIB seven (Camunda 7 fork)
This plugin automatically instruments every BPMN process execution in CIB seven with:
- Distributed traces (spans per process instance and per task) → Jaeger / Grafana Tempo
- Metrics (counters, histograms for start/end/duration/outcome) → Prometheus / Grafana
Zero changes to BPMN files required. Add a few Maven dependencies and you're done.
Caution
This plugin is not yet published to Maven Central or the CIB seven community Maven repository. Publishing is currently in progress. To use it now, you must build and install it locally:
git clone https://github.com/krixerx/cibseven-opentelemetry-plugin.git
cd cibseven-opentelemetry-plugin
mvn clean installThis installs the artifact into your local ~/.m2 repository, making it available to your projects.
Add the OpenTelemetry Instrumentation BOM to your <dependencyManagement> section:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-instrumentation-bom</artifactId>
<version>2.10.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>Then add the plugin and the OpenTelemetry Spring Boot starter to your <dependencies>:
<dependency>
<groupId>org.cibseven.community</groupId>
<artifactId>cibseven-opentelemetry-plugin</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>Note: The
spring-boot-starter-loggingexclusion prevents conflicts with your application's existing logging configuration.
spring.application.name=my-bpm-app
# OTLP endpoint (point to your OTel Collector or Jaeger)
otel.exporter.otlp.endpoint=http://localhost:4318
otel.exporter.otlp.protocol=http/protobuf
otel.traces.exporter=otlp
otel.metrics.exporter=otlp
otel.traces.sampler=parentbased_always_onEvery process instance is now traced automatically.
Trace: loan-application (instance abc-123)
├── receive-application 50ms
├── credit-check 2.3s ← bottleneck visible!
├── manual-review 4h ← human task duration
└── send-decision-letter 200ms
Each span carries BPMN attributes:
| Attribute | Example |
|---|---|
bpmn.process.definition |
loan-application:1:abc |
bpmn.process.instance |
abc-123 |
bpmn.activity.id |
creditCheck |
bpmn.activity.name |
Credit Check |
bpmn.activity.type |
serviceTask |
bpmn.outcome |
completed / rejected |
| Metric | Type | Description |
|---|---|---|
bpmn.process.started |
Counter | Process instances started |
bpmn.process.ended |
Counter | Process instances ended (with outcome) |
bpmn.process.duration |
Histogram | Full process duration in ms |
bpmn.task.started |
Counter | Tasks started |
bpmn.task.ended |
Counter | Tasks ended (with outcome) |
bpmn.task.duration |
Histogram | Task duration in ms |
bpmn.task.active |
Gauge | Tasks currently in progress |
# Completion rate per task
rate(bpmn_task_ended{outcome="completed"}[5m]) / rate(bpmn_task_started[5m])
# Average task duration
rate(bpmn_task_duration_sum[5m]) / rate(bpmn_task_duration_count[5m])
# Tasks currently in progress
bpmn_task_active
# Rejection rate
rate(bpmn_task_ended{outcome="rejected"}[5m]) / rate(bpmn_task_started[5m])
cd docker-example
docker-compose up -dThen open:
- Jaeger UI → http://localhost:16686
The example sends traces directly to Jaeger via OTLP — no separate OTel Collector needed.
CIB seven (Spring Boot)
│
│ ProcessEnginePlugin (auto-registered at startup)
▼
OpenTelemetryBpmnParseListener
│ (fires once per process definition at deploy time)
▼
OpenTelemetryExecutionListener ←── all task types
OpenTelemetryTaskListener ←── user tasks (CREATE/COMPLETE/DELETE)
│
▼
OpenTelemetry SDK
├── Tracer → Spans → OTLP → Jaeger
└── Meter → Metrics → Prometheus → Grafana
Set a process variable taskOutcome before completing a task to record a custom outcome:
// In your JavaDelegate or task complete handler:
taskService.setVariable(taskId, "taskOutcome", "rejected");
taskService.complete(taskId);
// → span attribute bpmn.task.outcome = "rejected"
// → metric: bpmn.task.ended{outcome="rejected"}- Java 17+
- CIB seven 2.x (or Camunda 7.x — API compatible)
- Spring Boot 3.x
- OpenTelemetry instrumentation BOM 2.x
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/my-feature) - Commit your changes
- Open a Pull Request
See CONTRIBUTING.md for details.
Apache License 2.0 — see LICENSE
- CIB seven — Open-source Camunda 7 fork
- cibseven-community-hub — Community extensions
- OpenTelemetry Java