Add OpenTelemetry tracing for CI job execution

What does this MR do?

Implements the Runner instrumentation for https://handbook.gitlab.com/handbook/engineering/architecture/design-documents/ci_job_telemetry/.

This merge request adds tracing capabilities to GitLab Runner, allowing it to track and monitor job execution across different systems. The changes introduce support for OpenTelemetry (OTEL),.

The implementation includes:

  • New tracing configuration that can be passed from GitLab to the runner via job specifications
  • Support for multiple trace export endpoints with different protocols (HTTP and gRPC)
  • OIDC Authentication
  • Automatic span creation around job execution to capture timing and metadata
  • A multi-exporter system that can send traces to multiple destinations simultaneously

Why was this MR needed?

Unfortunately, you have to add some code to make the program do new things 😁

What's the best way to test this MR?

👇 Sample output:

2026-04-03T05:05:21.845Z	info	Traces	{"resource": {"service.instance.id": "98234565-bcd8-42c7-a668-f32de615b915", "service.name": "otelcol-contrib", "service.version": "0.149.0"}, "otelcol.component.id": "debug", "otelcol.component.kind": "exporter", "otelcol.signal": "traces", "resource spans": 1, "spans": 1}
2026-04-03T05:05:21.846Z	info	ResourceSpans #0
Resource SchemaURL: https://opentelemetry.io/schemas/1.40.0
Resource attributes:
     -> service.name: Str(runner)
     -> service.version: Str(v1.11.1-0.20260325042159-f4b0c5976ba0+dirty)
ScopeSpans #0
ScopeSpans SchemaURL:
InstrumentationScope gitlab-ci-runner
Span #0
    Trace ID       : 0000000000000000000000000000034d
    Parent ID      :
    ID             : 0759569b581963b9
    Name           : job_execution
    Kind           : Internal
    Start time     : 2026-04-03 05:05:18.72521 +0000 UTC
    End time       : 2026-04-03 05:05:22.261392583 +0000 UTC
    Status code    : Unset
    Status message :
    DroppedAttributesCount: 0
    DroppedEventsCount: 0
    DroppedLinksCount: 0
Attributes:
     -> ci.job.id: Int(668)
     -> ci.project.id: Int(42)
     -> ci.pipeline.id: Str(845)
     -> ci.pipeline.source: Str(web)
     -> ci.runner.id: Int(25)
     -> ci.runner.executor: Str(docker)
     -> ci.job.status: Str(success)
	{"resource": {"service.instance.id": "98234565-bcd8-42c7-a668-f32de615b915", "service.name": "otelcol-contrib", "service.version": "0.149.0"}, "otelcol.component.id": "debug", "otelcol.component.kind": "exporter", "otelcol.signal": "traces"}

What are the relevant issue numbers?

Relates to Feature negotiation, OTLP export client, and fi... (#39231 - closed).

Edited by Taka Nishida

Merge request reports

Loading