The OpenTelemetry Collector is the engine of the GCP integration: it pulls metrics from Cloud Monitoring and exports them to SigNoz over OTLP. This guide deploys it as a Cloud Run service in your deployment project. This is step 3 of the GCP integration.
Prerequisites
- You have created the
signoz-integrationservice account and granted itroles/monitoring.vieweron your monitored projects. - You have connected your GCP account in SigNoz and noted your SigNoz Cloud region (from the Ingestion URL) and copied the Ingestion Key.
- The Cloud Run Admin API and the Secret Manager API are enabled in your
<deployment-project-id>. - The
gcloudCLI is installed and authenticated, or use Cloud Shell.
Which Collector image to use
Deploy the otel/opentelemetry-collector-contrib image. It bundles the googlecloudmonitoring receiver, which pulls metrics from the Cloud Monitoring API, and the health_check extension used in the deployment below.
Check the tags list for the latest version and use that tag (for example, otel/opentelemetry-collector-contrib:0.158.0) instead of latest, so deployments stay reproducible. The version must be 0.158.0 or above: earlier versions report cumulative GCP metrics in a way that prevents rate functions on counter metrics. Note that these tags have no v prefix.
Step 1: Prepare the Collector configuration
Create a file named otel-collector-config.yaml. The starter below is complete except for the metrics you want. You fill those in next, in Collect metrics, so it's normal for the metrics_list to be a placeholder now.
receivers:
# Metrics: one block per monitored project.
# See "Collect metrics" for the metrics_list per service.
googlecloudmonitoring:
project_id: "<monitored-project-id>"
collection_interval: 300s
metrics_list:
- metric_name: "compute.googleapis.com/instance/cpu/utilization"
processors:
batch:
timeout: 10s
send_batch_size: 1024
memory_limiter:
check_interval: 5s
limit_percentage: 80
spike_limit_percentage: 25
exporters:
otlphttp:
endpoint: "https://ingest.<region>.signoz.cloud:443"
headers:
"signoz-ingestion-key": "<ingestion-key>"
tls:
insecure: false
extensions:
# Serves the port Cloud Run health-checks. See the note below.
health_check:
endpoint: 0.0.0.0:8090
service:
extensions: [health_check]
pipelines:
metrics:
receivers: [googlecloudmonitoring]
processors: [memory_limiter, batch]
exporters: [otlphttp]Verify these values:
<region>: Your SigNoz Cloud region (for example,us,eu, orin). This is the region in the Ingestion URL shown on the SigNoz connection panel; use the region only, not the full URL.<ingestion-key>: Your SigNoz ingestion key, copied from the connection panel.
Step 2: Store the config in Secret Manager
Rather than baking a custom image, keep your otel-collector-config.yaml in Secret Manager and run the stock otel/opentelemetry-collector-contrib image directly. Cloud Run injects the secret as an environment variable, and the Collector reads its config from that variable at startup. Your config (and the ingestion key inside it) stays out of any image.
Create the secret from your otel-collector-config.yaml, then grant the signoz-integration service account permission to read it.
- In the deployment project, go to Security > Secret Manager > + Create secret.
- Set Name to
signoz-collector-config. - Under Secret value, choose Upload file and select your
otel-collector-config.yaml(or paste its contents into the value box). - Click Create secret.
- Open the new secret, go to the Permissions tab, and click Grant access.
- In New principals, paste
signoz-integration@<deployment-project-id>.iam.gserviceaccount.com. - In Role, select Secret Manager > Secret Manager Secret Accessor, then click Save.
Create the secret:
gcloud secrets create signoz-collector-config \
--data-file=otel-collector-config.yaml \
--project=<deployment-project-id>Grant the service account read access:
gcloud secrets add-iam-policy-binding signoz-collector-config \
--member="serviceAccount:signoz-integration@<deployment-project-id>.iam.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor" \
--project=<deployment-project-id>Step 3: Deploy to Cloud Run
Deploy the stock otel/opentelemetry-collector-contrib image as a Cloud Run service. Attach the signoz-integration service account, mount the config secret as the COLLECTOR_CONFIG environment variable, and point the Collector at it with --config=env:COLLECTOR_CONFIG.
- In the deployment project, go to Cloud Run > Deploy container > Service.
- Set the Container image URL to
otel/opentelemetry-collector-contrib:<tag>, using a tag from the tags list (0.158.0 or later). - Set Region to your
<deployment-region>. - Under Authentication, choose Require authentication (do not allow unauthenticated invocations).
- Under Ingress control, choose Internal.
- Expand Container(s), Volumes, Networking, Security:
- Container port:
8090. - Resources: 2 vCPU, 4 GiB memory.
- Security > Service account:
signoz-integration@<deployment-project-id>.iam.gserviceaccount.com. - Variables & Secrets > Reference a secret: select
signoz-collector-config, expose it as the environment variableCOLLECTOR_CONFIG, and use thelatestversion. - Container > Container arguments: add
--config=env:COLLECTOR_CONFIG. - Autoscaling: set both Minimum number of instances and Maximum number of instances to
1, so the Collector always runs and never scales to a second scraping replica. - Billing: choose Instance-based billing so CPU stays allocated between requests. With the default request-based billing, the metrics receiver's polling loop is throttled while the instance is idle.
- Container port:
- Click Create.
gcloud run deploy signoz-otel-collector \
--image=otel/opentelemetry-collector-contrib:<tag> \
--region=<deployment-region> \
--project=<deployment-project-id> \
--service-account=signoz-integration@<deployment-project-id>.iam.gserviceaccount.com \
--set-secrets=COLLECTOR_CONFIG=signoz-collector-config:latest \
--args=--config=env:COLLECTOR_CONFIG \
--port=8090 \
--ingress=internal \
--no-allow-unauthenticated \
--min-instances=1 \
--max-instances=1 \
--no-cpu-throttling \
--cpu=2 \
--memory=4GiWhy these flags:
--ingress=internaland--no-allow-unauthenticatedkeep the Collector off the public internet; it only makes outbound calls.--min-instances=1keeps one instance warm, since scaling to zero pauses metric scrapes.--no-cpu-throttlingkeeps CPU allocated between requests. Without it, Cloud Run throttles the idle instance and stalls the receiver's polling loop.--max-instances=1prevents extra replicas from scraping the same metrics and duplicating data points. Scale up (--cpu/--memory), not out.--cpu=2 --memory=4Gimatches the ~$110/month cost estimate. Drop to--cpu=1 --memory=2Gifor low volumes; scale up on memory pressure or dropped data.
Step 4: Verify the Collector is running
- In the Console, open Cloud Run > signoz-otel-collector > Logs.
- Confirm the Collector started without configuration errors. Look for
Everything is ready. Begin running and processing data. - If the revision fails to become ready, the most common cause is a port mismatch. Confirm the
health_checkextension'sendpointport matches the Cloud Run container port (8090).
A running Collector is not yet a working one: it has nothing to pull until you give it a metrics_list, and it reports healthy either way. Continue to the next step, which ends with a check that metrics actually reach SigNoz.
Next steps
- Collect metrics: configure the
googlecloudmonitoringreceiver.
After changing otel-collector-config.yaml, add a new secret version (step 2) and redeploy the service (step 3) to roll the new configuration out.
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.