Skip to content

Commit 3870a7f

Browse files
committed
docs: add tracing configuration guide and config examples
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2b83cec commit 3870a7f

File tree

4 files changed

+63
-12
lines changed

4 files changed

+63
-12
lines changed

config/305-config-observability.yaml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ metadata:
2121
app.kubernetes.io/version: "devel"
2222
app.kubernetes.io/part-of: pipelines-as-code
2323
data:
24-
metrics-protocol: prometheus
25-
metrics-endpoint: ":9090"
2624
_example: |
2725
################################
2826
# #
@@ -50,4 +48,18 @@ data:
5048
5149
# metrics-export-interval specifies how often metrics are exported.
5250
# Only applicable for grpc and http/protobuf protocols.
53-
# metrics-export-interval: "30s"
51+
# metrics-export-interval: "30s"
52+
53+
# tracing-protocol specifies the trace export protocol.
54+
# Supported values: "grpc", "http/protobuf", "none".
55+
# Default is "none" (tracing disabled).
56+
# tracing-protocol: "none"
57+
58+
# tracing-endpoint specifies the OTLP collector endpoint.
59+
# Required when tracing-protocol is "grpc" or "http/protobuf".
60+
# The OTEL_EXPORTER_OTLP_ENDPOINT env var takes precedence if set.
61+
# tracing-endpoint: "http://otel-collector.observability.svc.cluster.local:4317"
62+
63+
# tracing-sampling-rate controls the fraction of traces sampled.
64+
# 0.0 = none, 1.0 = all. Default is 0 (none).
65+
# tracing-sampling-rate: "1.0"
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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. 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 the ConfigMap are picked up automatically without restarting the controller. Set `tracing-protocol` to `none` or remove the tracing keys to disable tracing.
33+
34+
## Emitted spans
35+
36+
The controller emits a `PipelinesAsCode:ProcessEvent` span covering the full lifecycle of each webhook event, from receipt through PipelineRun creation. The watcher emits `waitDuration` and `executeDuration` spans for completed PipelineRuns, using the PipelineRun's actual timestamps for accurate wall-clock timing.
37+
38+
## Trace context propagation
39+
40+
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.
41+
42+
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.

pkg/kubeinteraction/labels.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func AddLabelsAndAnnotations(ctx context.Context, event *info.Event, pipelineRun
7070

7171
// Add span context for distributed tracing if available
7272
if len(carrier) > 0 {
73-
if jsonBytes, err := json.Marshal(map[string]string(carrier)); err == nil {
73+
if jsonBytes, err := json.Marshal(carrier); err == nil {
7474
if existing := pipelineRun.GetAnnotations()[keys.SpanContextAnnotation]; existing != "" {
7575
logging.FromContext(ctx).Warnf("overwriting pre-existing %s annotation on PipelineRun template; honoring initiating event trace context", keys.SpanContextAnnotation)
7676
}

pkg/reconciler/emit_traces.go

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ func extractSpanContext(pr *tektonv1.PipelineRun) (context.Context, bool) {
3434
return nil, false
3535
}
3636
carrier := propagation.MapCarrier(carrierMap)
37-
prop := propagation.TraceContext{}
38-
ctx := prop.Extract(context.Background(), carrier)
37+
ctx := otel.GetTextMapPropagator().Extract(context.Background(), carrier)
3938
sc := trace.SpanContextFromContext(ctx)
4039
if !sc.IsValid() {
4140
return nil, false
@@ -50,7 +49,7 @@ func emitTimingSpans(pr *tektonv1.PipelineRun) {
5049
return
5150
}
5251

53-
tracer := otel.GetTracerProvider().Tracer(tracing.TracerName)
52+
tracer := otel.Tracer(tracing.TracerName)
5453
commonAttrs := buildCommonAttributes(pr)
5554

5655
// Emit waitDuration: creationTimestamp -> status.startTime
@@ -64,7 +63,7 @@ func emitTimingSpans(pr *tektonv1.PipelineRun) {
6463

6564
// Emit executeDuration: status.startTime -> status.completionTime
6665
if pr.Status.StartTime != nil && pr.Status.CompletionTime != nil {
67-
execAttrs := append(commonAttrs, buildExecuteAttributes(pr)...)
66+
execAttrs := append(append([]attribute.KeyValue{}, commonAttrs...), buildExecuteAttributes(pr)...)
6867
_, execSpan := tracer.Start(parentCtx, "executeDuration",
6968
trace.WithTimestamp(pr.Status.StartTime.Time),
7069
trace.WithAttributes(execAttrs...),
@@ -91,13 +90,11 @@ func buildCommonAttributes(pr *tektonv1.PipelineRun) []attribute.KeyValue {
9190
// buildExecuteAttributes returns span attributes specific to execute_duration.
9291
func buildExecuteAttributes(pr *tektonv1.PipelineRun) []attribute.KeyValue {
9392
cond := pr.Status.GetCondition(apis.ConditionSucceeded)
94-
success := true
93+
success := false
9594
reason := ""
9695
if cond != nil {
9796
reason = cond.Reason
98-
if cond.Status == corev1.ConditionFalse {
99-
success = false
100-
}
97+
success = cond.Status == corev1.ConditionTrue
10198
}
10299
return []attribute.KeyValue{
103100
tracing.DeliverySuccessKey.Bool(success),

0 commit comments

Comments
 (0)