Implement trace context initialization in Rails for CI job telemetry
## Summary Implement trace context initialization in Rails so that all telemetry spans for a CI pipeline hierarchy share the same `trace_id`, with each job as a top-level span within the pipeline trace. The trace context and OTEL Collector endpoint(s) are passed to the Runner via the unified `features.tracing` object in the job payload response. ## Job payload change Add a `tracing` object to the `features` in the `/api/v4/jobs/request` response. Its presence signals that telemetry is enabled for the job; when absent, the Runner skips all telemetry instrumentation. ```json { "features": { "tracing": { "trace_id": "000000000000000000000000001e240a", "span_parent_id": "00000000075bcd15", "otel_endpoints": [ "https://otel-collector.gitlab.net/v1/traces" ] } } } ``` | Field | Type | Description | |-------|------|-------------| | `trace_id` | String (32-char hex) | Deterministically derived from the **root** `pipeline_id`. All jobs across the pipeline hierarchy (parent and child pipelines) share this trace ID. | | `span_parent_id` | String (16-char hex), optional | Present only for child pipeline jobs. Derived from the trigger (bridge) job's database ID (`format('%016x', bridge.id)`), so child pipeline job spans nest under the trigger job in the trace tree. Absent for top-level pipeline jobs (Runner creates root-level spans). | | `otel_endpoints` | Array of strings (max 2) | OTLP/HTTP endpoint URLs. First entry is GitLab's Collector (Rails application setting, gitlab-org/gitlab#591941). Optional second entry is a customer-configured BYO OTLP endpoint (project/group setting, future). Runner exports spans to all endpoints in parallel. | ## Requirements 1. Generate `trace_id` deterministically from the **root** `pipeline_id` (for example, zero-padded hex representation). Child pipelines inherit the root pipeline's trace ID. 2. For child pipeline jobs, generate `span_parent_id` from the trigger (bridge) job's database ID (`format('%016x', bridge.id)`), so child pipeline spans nest under the trigger job in the trace tree. Omit `span_parent_id` for top-level pipeline jobs. 3. Only include `features.tracing` when: - The `ci_job_telemetry` feature flag is enabled for the project (see gitlab-org/gitlab#590588), **and** - The CI telemetry OTEL Collector endpoint application setting is configured (see gitlab-org/gitlab#591941) 4. Populate `otel_endpoints` with the configured OTEL Collector endpoint URL from the Rails application setting as the first entry. A future per-project/group BYO endpoint may be added as a second entry. 5. Include `ci.pipeline.id` and `ci.pipeline.source` as resource attributes in OTLP spans emitted by Rails (alongside `ci.job.id`, `ci.project.id`) — needed to identify the specific pipeline a job belongs to, since `trace_id` maps to the root pipeline ## Architecture Reference - [Job payload changes](https://handbook.gitlab.com/handbook/engineering/architecture/design-documents/ci_job_telemetry/#job-payload-changes) - [Multi-source trace context coordination](https://handbook.gitlab.com/handbook/engineering/architecture/design-documents/ci_job_telemetry/#multi-source-trace-context-coordination) - [Design decision: OTEL Collector endpoint configuration](https://handbook.gitlab.com/handbook/engineering/architecture/design-documents/ci_job_telemetry/#design-decisions) ## Dependencies - Feature negotiation (gitlab-org/gitlab#590588) must be implemented first — `features.tracing` is only included when the feature flag is enabled - OTEL Collector endpoint application setting (gitlab-org/gitlab#591941) — the endpoint URL must be configured for `features.tracing` to be included - Coordinate with ~"group::runner core" on job payload schema changes (&20633) ## Parent Epic gitlab-org&20945
issue