Overview
Collect GitLab CI/CD pipeline traces using the GitLab Receiver and send them to SigNoz.
Each GitLab pipeline event triggers a webhook to the OTel Collector. The receiver converts the completed pipeline and its jobs into a trace with job-level child spans.
Prerequisites
- OpenTelemetry Collector Contrib v0.123.0 or later
- Access to SigNoz (Cloud or Self-Hosted)
- A GitLab project where you have Maintainer or Owner access to configure webhooks
Setup
Step 1. Configure the GitLab Receiver
If you have a collector running, append the gitlab receiver, resource/gitlab processor, and traces pipeline to your existing config.yaml. Otherwise, create a new config.yaml with the full config below.
The collector listens on port 19418 for pipeline webhooks, stamps every trace with service.name, and exports to SigNoz over OTLP.
receivers:
gitlab:
webhook:
# Binds on all interfaces so the collector is reachable externally.
endpoint: 0.0.0.0:19418
path: /events
health_path: /health
secret: ${env:GITLAB_WEBHOOK_SECRET}
processors:
resource/gitlab:
attributes:
- key: service.name
value: <service-name>
action: upsert
exporters:
otlp:
endpoint: "ingest.<region>.signoz.cloud:443"
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}
tls:
insecure: false
service:
pipelines:
traces:
receivers: [gitlab]
processors: [resource/gitlab]
exporters: [otlp]Replace the in-file placeholders (edit these directly in the config):
<service-name>: A name to identify this pipeline source in SigNoz (e.g.gitlab-ci).<region>: Your SigNoz Cloud region.
Set these as environment variables (${env:...} resolves them at runtime):
GITLAB_WEBHOOK_SECRET: A secret string you choose. The receiver checks theX-Gitlab-Tokenheader on every request and rejects any that do not match. If omitted, no secret validation occurs.SIGNOZ_INGESTION_KEY: Your SigNoz Cloud Ingestion Key.
Step 2. Run the OTel Collector
# Set environment variables and start the collector
export GITLAB_WEBHOOK_SECRET=<your-webhook-secret>
export SIGNOZ_INGESTION_KEY=<your-ingestion-key>
./otelcol-contrib --config ./config.yaml# Run the collector in Docker, mounting the config from Step 1
docker run -d \
-e GITLAB_WEBHOOK_SECRET=<your-webhook-secret> \
-e SIGNOZ_INGESTION_KEY=<your-ingestion-key> \
-p 19418:19418 \
-v $(pwd)/config.yaml:/etc/otel/config.yaml \
otel/opentelemetry-collector-contrib:0.123.0 \
--config=/etc/otel/config.yamlSecret for credentials, ConfigMap for config, Deployment, and Service:
apiVersion: v1
kind: Secret
metadata:
name: gitlab-otel-secrets
namespace: signoz
stringData:
GITLAB_WEBHOOK_SECRET: <your-webhook-secret>
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
---
apiVersion: v1
kind: ConfigMap
metadata:
name: gitlab-otel-config
namespace: signoz
data:
config.yaml: |
receivers:
gitlab:
webhook:
endpoint: 0.0.0.0:19418
path: /events
health_path: /health
secret: ${env:GITLAB_WEBHOOK_SECRET}
processors:
resource/gitlab:
attributes:
- key: service.name
value: <service-name>
action: upsert
exporters:
otlp:
endpoint: "ingest.<region>.signoz.cloud:443"
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}
tls:
insecure: false
service:
pipelines:
traces:
receivers: [gitlab]
processors: [resource/gitlab]
exporters: [otlp]
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitlab-otel-collector
namespace: signoz
spec:
replicas: 1
selector:
matchLabels:
app: gitlab-otel-collector
template:
metadata:
labels:
app: gitlab-otel-collector
spec:
containers:
- name: collector
image: otel/opentelemetry-collector-contrib:0.123.0
command: ["/otelcol-contrib", "--config=/etc/otel/config.yaml"]
ports:
- containerPort: 19418
envFrom:
- secretRef:
name: gitlab-otel-secrets
volumeMounts:
- name: config
mountPath: /etc/otel
volumes:
- name: config
configMap:
name: gitlab-otel-config
---
apiVersion: v1
kind: Service
metadata:
name: gitlab-otel-webhook
namespace: signoz
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 19418
selector:
app: gitlab-otel-collector# Apply the manifest to your cluster
kubectl apply -f gitlab-otel-collector.yamlIf your cluster is not publicly reachable, port-forward to expose the webhook endpoint:
# Forward local port 19418 to the collector Service
kubectl port-forward svc/gitlab-otel-webhook -n signoz 19418:80Step 3. Create a GitLab webhook
In your GitLab project, go to Settings → Webhooks and add a webhook:
- URL:
https://<collector-host>:19418/events— the hostname or IP where your OTel Collector is reachable from GitLab. If port-forwarding on Kubernetes, uselocalhost.
- Secret token: The same value you set for
GITLAB_WEBHOOK_SECRET. - Trigger: Enable Pipeline events only.
Click Add webhook. Use Test → Pipeline events to confirm the collector receives the request.
Validate
Trigger a pipeline run in GitLab. Once the pipeline completes, open the Traces tab in SigNoz. Each pipeline appears as a root span with its jobs as child spans.
Click a Trace ID to open the span detail view and inspect per-job durations and statuses.


Troubleshooting
Webhook returns 400 Bad Request
Symptom: GitLab reports a failed webhook delivery with HTTP 400.
Likely causes:
- Secret mismatch: the
secretinconfig.yamldoes not match the Secret token in GitLab webhook settings. Verify both values are identical. - Wrong event type: the receiver only processes
Pipeline Hookevents. Other event types (includingJob Hook) are rejected. Ensure only Pipeline events is enabled. - Missing required headers: if you configured
required_headers, every request must include those headers with matching values.
Fix: Correct the mismatched value and re-test with Test → Pipeline events in GitLab.
Traces do not appear in SigNoz
Symptom: The webhook succeeds (HTTP 200 or 204) but no traces show up in SigNoz.
Likely causes:
- Pipeline still running: the receiver skips in-progress pipelines and returns HTTP 204. Wait for completion.
- Exporter misconfiguration: verify
endpointandsignoz-ingestion-keyare correct. Check collector logs for export errors. - Network or firewall: ensure the collector can reach
ingest.<region>.signoz.cloud:443.
Fix: Check collector logs (docker logs <container> or kubectl logs) for errors. Trigger a new pipeline and confirm completion before checking SigNoz.
Webhook delivery fails in GitLab
Symptom: GitLab cannot reach the webhook URL at all (connection timeout or refused).
Likely causes:
- Collector not running: verify the collector process is up and listening on the configured port.
- Firewall or network: the collector must be reachable from GitLab. For self-managed GitLab, check network policies. For GitLab.com SaaS, the collector must be publicly accessible or tunneled.
- Wrong URL: verify the URL includes the correct host, port (
19418), and path (/events).
Fix: Test connectivity with curl https://<collector-host>:19418/health — a healthy collector returns {"text": "GitLab receiver webhook is healthy"}.
Limitations
- Traces only: no metrics or logs.
- Pipeline events only: the receiver processes
Pipeline Hookwebhooks only. Other event types (includingJob Hook) are not processed and return an error. - No child or multi-project pipelines: parent-child pipeline relationships are not preserved; each pipeline produces a separate independent trace.
- No manual instrumentation correlation: trace IDs are a SHA-256 hash of the pipeline ID and
finished_attimestamp, available only after completion. Application-level spans cannot be correlated with pipeline spans. - Alpha stability: receiver is in alpha. Config schema may change in future
otelcol-contribreleases.
Next Steps
- Set up trace-based alerts to get notified on pipeline failures or duration regressions.
- Explore the Traces view to filter and analyze pipeline runs.
- CI/CD Monitoring overview for other supported integrations.
Get Help
If you need help with the steps in this topic, please reach out to us on SigNoz Community Slack. If you are a SigNoz Cloud user, please use in product chat support located at the bottom right corner of your SigNoz instance or contact us at cloud-support@signoz.io.