|
| 1 | +--- |
| 2 | +title: Distributed Tracing |
| 3 | +weight: 5 |
| 4 | +--- |
| 5 | + |
| 6 | +This page describes how to enable OpenTelemetry distributed tracing for Pipelines-as-Code. When enabled, PaC emits trace spans for webhook event processing and PipelineRun lifecycle timing. |
| 7 | + |
| 8 | +## Enabling tracing |
| 9 | + |
| 10 | +The ConfigMap `pipelines-as-code-config-observability` controls tracing configuration. It must exist in the same namespace as the Pipelines-as-Code controller and watcher deployments. See [config/305-config-observability.yaml](https://github.com/tektoncd/pipelines-as-code/blob/main/config/305-config-observability.yaml) for the full example. |
| 11 | + |
| 12 | +It contains the following tracing fields: |
| 13 | + |
| 14 | +* `tracing-protocol`: Export protocol. Supported values: `grpc`, `http/protobuf`, `none`. Default is `none` (tracing disabled). |
| 15 | +* `tracing-endpoint`: OTLP collector endpoint. Required when protocol is not `none`. The `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable takes precedence if set. |
| 16 | +* `tracing-sampling-rate`: Fraction of traces to sample. `0.0` = none, `1.0` = all. Default is `0`. |
| 17 | + |
| 18 | +### Example |
| 19 | + |
| 20 | +```yaml |
| 21 | +apiVersion: v1 |
| 22 | +kind: ConfigMap |
| 23 | +metadata: |
| 24 | + name: pipelines-as-code-config-observability |
| 25 | + namespace: pipelines-as-code |
| 26 | +data: |
| 27 | + tracing-protocol: grpc |
| 28 | + tracing-endpoint: "http://otel-collector.observability.svc.cluster.local:4317" |
| 29 | + tracing-sampling-rate: "1.0" |
| 30 | +``` |
| 31 | +
|
| 32 | +Changes to `tracing-protocol`, `tracing-endpoint`, and `tracing-sampling-rate` require restarting the controller and watcher pods. The trace exporter is created once at startup from the ConfigMap values at that time. Set `tracing-protocol` to `none` or remove the tracing keys to disable tracing. |
| 33 | + |
| 34 | +The controller and watcher locate this ConfigMap by name via the `CONFIG_OBSERVABILITY_NAME` environment variable set in their deployment manifests. Operator-based installations may manage this differently; consult the operator documentation for details. |
| 35 | + |
| 36 | +## Emitted spans |
| 37 | + |
| 38 | +The controller emits a `PipelinesAsCode:ProcessEvent` span for each webhook event. The watcher emits `waitDuration` and `executeDuration` spans for completed PipelineRuns. |
| 39 | + |
| 40 | +### Webhook event span (`PipelinesAsCode:ProcessEvent`) |
| 41 | + |
| 42 | +[OTel VCS semantic conventions](https://opentelemetry.io/docs/specs/semconv/attributes-registry/vcs/): |
| 43 | + |
| 44 | +| Attribute | Source | |
| 45 | +| --- | --- | |
| 46 | +| `vcs.provider.name` | Git provider name | |
| 47 | +| `vcs.repository.url.full` | Repository URL | |
| 48 | +| `vcs.ref.head.revision` | Head commit SHA | |
| 49 | + |
| 50 | +PaC-specific: |
| 51 | + |
| 52 | +| Attribute | Source | |
| 53 | +| --- | --- | |
| 54 | +| `pipelinesascode.tekton.dev.event_type` | Webhook event type | |
| 55 | + |
| 56 | +### PipelineRun timing spans (`waitDuration`, `executeDuration`) |
| 57 | + |
| 58 | +Tekton-compatible bare keys (match Tekton's own reconciler spans for correlation): |
| 59 | + |
| 60 | +| Attribute | Source | |
| 61 | +| --- | --- | |
| 62 | +| `namespace` | PipelineRun namespace | |
| 63 | +| `pipelinerun` | PipelineRun name | |
| 64 | + |
| 65 | +Cross-service delivery attributes (`delivery.tekton.dev.*`): |
| 66 | + |
| 67 | +| Attribute | Source | |
| 68 | +| --- | --- | |
| 69 | +| `delivery.tekton.dev.pipelinerun_uid` | PipelineRun UID | |
| 70 | +| `delivery.tekton.dev.result_message` | First failing TaskRun message; omitted on success; truncated to 1024 bytes | |
| 71 | + |
| 72 | +Additional `delivery.tekton.dev.*` attributes are sourced from [configurable PipelineRun labels](#configuring-label-sourced-attributes). |
| 73 | + |
| 74 | +[OTel CI/CD semantic conventions](https://opentelemetry.io/docs/specs/semconv/attributes-registry/cicd/) (`executeDuration` only): |
| 75 | + |
| 76 | +| Attribute | Source | |
| 77 | +| --- | --- | |
| 78 | +| `cicd.pipeline.result` | Outcome enum (see below) | |
| 79 | + |
| 80 | +### `cicd.pipeline.result` enum |
| 81 | + |
| 82 | +| Condition | Value | |
| 83 | +| --- | --- | |
| 84 | +| `Status=True` | `success` | |
| 85 | +| `Status=False`, reason `Failed` | `failure` | |
| 86 | +| `Status=False`, reason `PipelineRunTimeout` | `timeout` | |
| 87 | +| `Status=False`, reason `Cancelled` or `CancelledRunningFinally` | `cancellation` | |
| 88 | +| `Status=False`, any other reason | `error` | |
| 89 | + |
| 90 | +## Configuring label-sourced attributes |
| 91 | + |
| 92 | +Some span attributes are read from PipelineRun labels. The label names are configurable via the main `pipelines-as-code` ConfigMap so deployments can point at their existing labels without rewriting producers: |
| 93 | + |
| 94 | +| ConfigMap key | PipelineRun label read (default) | Span attribute emitted | |
| 95 | +| --- | --- | --- | |
| 96 | +| `tracing-label-action` | `delivery.tekton.dev/action` | `cicd.pipeline.action.name` | |
| 97 | +| `tracing-label-application` | `delivery.tekton.dev/application` | `delivery.tekton.dev.application` | |
| 98 | +| `tracing-label-component` | `delivery.tekton.dev/component` | `delivery.tekton.dev.component` | |
| 99 | + |
| 100 | +Setting a ConfigMap key to the empty string disables emission of that label-sourced attribute. Only label-sourced attributes are affected; all other span attributes are always emitted. The emitted span attribute keys are fixed regardless of which labels are read, so cross-service queries work uniformly. |
| 101 | + |
| 102 | +Unlike the observability ConfigMap above (which requires a pod restart), changes to these label mappings are picked up automatically without restarting pods. |
| 103 | + |
| 104 | +## Trace context propagation |
| 105 | + |
| 106 | +When Pipelines-as-Code creates a PipelineRun, it sets the `tekton.dev/pipelinerunSpanContext` annotation with a JSON-encoded OTel TextMapCarrier containing the W3C `traceparent`. PaC tracing works independently — you get PaC spans regardless of whether Tekton Pipelines has tracing enabled. |
| 107 | + |
| 108 | +If Tekton Pipelines is also configured with tracing pointing at the same collector, its reconciler spans appear as children of the PaC span, providing a single end-to-end trace from webhook receipt through task execution. See the [Tekton Pipelines tracing documentation](https://github.com/tektoncd/pipeline/blob/main/docs/developers/tracing.md) for Tekton's independent tracing setup. |
| 109 | + |
| 110 | +## Deploying a trace collector |
| 111 | + |
| 112 | +Pipelines-as-Code exports traces using the standard OpenTelemetry Protocol (OTLP). You need a running OTLP-compatible collector for the `tracing-endpoint` to point to. Common options include: |
| 113 | + |
| 114 | +* [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/) -- the vendor-neutral reference collector |
| 115 | +* [Jaeger](https://www.jaegertracing.io/docs/latest/getting-started/) -- supports OTLP ingestion natively since v1.35 |
| 116 | + |
| 117 | +Deploying and operating a collector is outside the scope of Pipelines-as-Code. Refer to your organization's observability infrastructure or the links above for setup instructions. |
0 commit comments