Google Cloud Monitoring
Monitor your Google Cloud project — Compute Engine VMs, Cloud SQL instances, HTTP(S) load balancers, Pub/Sub subscriptions, and Cloud Storage buckets — through Cloud Monitoring, with curated dashboards and alerts you import in one step.
Cloud Monitoring (the metrics half of Google Cloud Observability, formerly
Stackdriver) is a polled API rather than a scrape endpoint, but no adapter is
needed: the LeanSignal agent gateway is an OpenTelemetry Collector
distribution and bundles the
googlecloudmonitoring receiver,
which reads the time series you name with a read-only service account. The
gateway keeps full fidelity locally and forwards only the demanded subset to
your central dataplane — so polling broadly stays cheap, and importing a demand
is what decides which Google Cloud series are stored centrally.
The panels and alerts cover the five services most projects run on — Compute Engine, Cloud SQL, Cloud Load Balancing, Pub/Sub, and Cloud Storage — with the thresholds Google Cloud operators actually page on: server state, disk headroom, 5xx ratios, backend latency, and subscription backlog age.
Prerequisites
Section titled “Prerequisites”- A LeanSignal agent gateway deployed and connected — one per cluster or
environment. If you haven’t deployed it yet, follow
Install the agent (source:
LeanSignal/leansignal-agent). It should show as Connected under Agents in the LeanSignal app. - Network reachability to the gateway’s OTLP port —
4317(gRPC) or4318(HTTP). See Agent configuration. - A read-only Google Cloud identity — a service account with the
Monitoring Viewer (
roles/monitoring.viewer) role on each project you poll, reachable through Application Default Credentials — and an OpenTelemetry Collector running thegooglecloudmonitoringreceiver, which the LeanSignal agent gateway already bundles. Both configured in Setup. - Editor or admin role in the LeanSignal app (importing a demand creates dashboards and alert rules).
Two pieces: a read-only Google Cloud identity, and a collector running the
googlecloudmonitoring receiver that polls Cloud Monitoring and forwards OTLP
to the gateway.
1. Google Cloud — a read-only identity. Create a service account with the Monitoring Viewer role on every project you poll:
PROJECT=my-project-idgcloud iam service-accounts create leansignal-monitor \ --project "$PROJECT" --display-name "LeanSignal metric reader"
gcloud projects add-iam-policy-binding "$PROJECT" \ --member "serviceAccount:leansignal-monitor@$PROJECT.iam.gserviceaccount.com" \ --role roles/monitoring.viewer
# Only if the collector runs outside Google Cloud:gcloud iam service-accounts keys create /etc/leansignal-agent/gcp-key.json \ --iam-account "leansignal-monitor@$PROJECT.iam.gserviceaccount.com"The receiver authenticates with Application Default Credentials. On GKE use
Workload Identity, on a VM use the attached service account — nothing else to
configure. Off Google Cloud, point GOOGLE_APPLICATION_CREDENTIALS at the key
file above (for a systemd install, add it to
/etc/leansignal-agent/agent.env).
2. Collector — poll Cloud Monitoring, forward OTLP to the gateway (not a
SaaS endpoint). metrics_list is the whole poll surface: one entry per metric
type, and the dashboards chart exactly these.
receivers: # One receiver per project — add googlecloudmonitoring/<other-project> blocks # and list them all in the pipeline below. googlecloudmonitoring: project_id: my-project-id collection_interval: 300s # minimum 60s; each poll is one API call per metric metrics_list: # Compute Engine - metric_name: "compute.googleapis.com/instance/cpu/utilization" - metric_name: "compute.googleapis.com/instance/cpu/reserved_cores" - metric_name: "compute.googleapis.com/instance/network/received_bytes_count" - metric_name: "compute.googleapis.com/instance/network/sent_bytes_count" - metric_name: "compute.googleapis.com/instance/network/received_packets_count" - metric_name: "compute.googleapis.com/instance/network/sent_packets_count" - metric_name: "compute.googleapis.com/instance/disk/read_bytes_count" - metric_name: "compute.googleapis.com/instance/disk/write_bytes_count" - metric_name: "compute.googleapis.com/instance/disk/read_ops_count" - metric_name: "compute.googleapis.com/instance/disk/write_ops_count" # Cloud SQL - metric_name: "cloudsql.googleapis.com/database/up" - metric_name: "cloudsql.googleapis.com/database/cpu/utilization" - metric_name: "cloudsql.googleapis.com/database/memory/utilization" - metric_name: "cloudsql.googleapis.com/database/disk/utilization" - metric_name: "cloudsql.googleapis.com/database/disk/bytes_used" - metric_name: "cloudsql.googleapis.com/database/disk/quota" - metric_name: "cloudsql.googleapis.com/database/network/connections" - metric_name: "cloudsql.googleapis.com/database/replication/replica_lag" # Cloud Load Balancing - metric_name: "loadbalancing.googleapis.com/https/request_count" - metric_name: "loadbalancing.googleapis.com/https/backend_latencies" # Pub/Sub - metric_name: "pubsub.googleapis.com/subscription/num_undelivered_messages" - metric_name: "pubsub.googleapis.com/subscription/oldest_unacked_message_age" - metric_name: "pubsub.googleapis.com/subscription/sent_message_count" - metric_name: "pubsub.googleapis.com/subscription/ack_message_count" - metric_name: "pubsub.googleapis.com/subscription/dead_letter_message_count" - metric_name: "pubsub.googleapis.com/subscription/expired_ack_deadlines_count" # Cloud Storage - metric_name: "storage.googleapis.com/storage/total_bytes" - metric_name: "storage.googleapis.com/api/request_count"
processors: # Required — Google Cloud's *_count metrics are delta temporality, which a # Prometheus store cannot hold. Accumulates them into cumulative series. deltatocumulative: {} # Required — see "Google Cloud units" below. Keeps metric names as the GCP # metric type, with dots and slashes as underscores. transform/gcp_units: error_mode: ignore metric_statements: - set(metric.unit, "") where IsMatch(metric.name, "googleapis") batch: {}
exporters: otlp: endpoint: leansignal-agent:4317 # per-cluster gateway (use :4318 for HTTP) tls: insecure: true # in-cluster plaintext; provide ca_file for TLS
service: pipelines: metrics: receivers: [googlecloudmonitoring] processors: [deltatocumulative, transform/gcp_units, batch] exporters: [otlp]Running this on the gateway itself instead? Add the googlecloudmonitoring
receiver and both processors to its own config, then add them to its
metrics/all pipeline — the otlp exporter and the separate service block
above are only for a standalone collector.
To confirm metrics are arriving, look for the compute_googleapis_com_* family
in the LeanSignal app under Metrics with the source set to Available, or
on the gateway host:
curl -s http://127.0.0.1:8428/api/v1/label/__name__/values | grep -o '[a-z]*_googleapis_com_[a-z_]*' | sort -u | headLogs and traces
Section titled “Logs and traces”Cloud Logging reaches the gateway through Pub/Sub, the export path Google
itself is built around: create a log sink that routes the logs you want to
a Pub/Sub topic, give the collector a subscription on it, and point the
gateway’s bundled googlecloudpubsub receiver at that subscription — the
streams then behave like any other logs.
gcloud logging sinks create leansignal-logs \ pubsub.googleapis.com/projects/my-project-id/topics/leansignal-logs \ --log-filter='resource.type="cloud_run_revision" OR resource.type="gce_instance"'extensions: googlecloudlogentry_encoding:
receivers: googlecloudpubsub: project: my-project-id subscription: projects/my-project-id/subscriptions/leansignal-logs encoding: googlecloudlogentry_encoding # decodes Cloud Logging LogEntry JSONGrant the sink’s writer identity (printed by gcloud logging sinks create)
roles/pubsub.publisher on the topic, and the collector’s service account
roles/pubsub.subscriber on the subscription. Then add googlecloudpubsub to
a logs pipeline exporting OTLP to the gateway (or to the gateway’s own
logs/all pipeline), and list the extension under service.extensions. Keep the sink filter tight — Cloud Logging exports
everything the filter matches, and a subscription with no subscriber running
retains messages until they expire.
Traces are an application concern, not a Cloud Monitoring one — instrument the workloads running on Google Cloud with the OpenTelemetry SDKs (see the runtime integrations) and point them at the gateway.
Demands
Section titled “Demands”Google Cloud Monitoring ships as a ready-made demand in three variants. You don’t copy any JSON — in the LeanSignal app go to Demands, press the ˅ arrow on the Add Demand button (the arrow opens the import menu), choose Import from catalog…, and pick the variant. Each variant below lists the slug that identifies its published bundle. See Integrations for the full import flow.
The variants are nested — Standard is a superset of Essential, Extended a superset of Standard. Pick whichever is closest to what you need and treat it as a starting point: after import everything is a normal, editable copy, so retune thresholds, add or drop panels, and adjust queries for your environment — your edits reshape the demand automatically. Start small and re-import a larger variant later if you outgrow it.
The failure signals. 1 dashboard · 10 panels · 5 alerts — CPU, server state, disk headroom, 5xx responses, and subscription backlog at a glance.
Import this variant from the catalog. Its demand slug:
google-cloud-monitoring-otel-demand-essentialDashboard — CPU utilization, Network in / out, Server up, CPU utilization, Disk utilization, Requests, 5xx responses, Oldest unacked message age, Undelivered messages, and Bytes stored.
Alerts (5)
| Alert | Severity | Fires when |
|---|---|---|
| Load balancer high 5xx ratio | warning | 5xx > 5% of requests for 10m |
| Cloud SQL instance down | critical | instance not serving for 10m |
| Cloud SQL disk nearly full | critical | > 90% of disk used for 15m |
| Pub/Sub backlog aging | warning | oldest unacked message > 10m old, for 10m |
| Pub/Sub backlog growing | warning | > 1000 undelivered messages for 15m |
Well-rounded coverage. 1 dashboard · 17 panels · 9 alerts — adds disk throughput, memory, connections, backend latency, and delivery throughput. The recommended default.
Import this variant from the catalog. Its demand slug:
google-cloud-monitoring-otel-demand-standardDashboard — everything in Essential, plus Disk read / write, Disk IOPS, Memory utilization, Connections, Backend latency (p95), Sent / acknowledged messages, and API requests by method.
Alerts (9)
| Alert | Severity | Fires when |
|---|---|---|
| Load balancer high 5xx ratio | warning | 5xx > 5% of requests for 10m |
| Cloud SQL instance down | critical | instance not serving for 10m |
| Cloud SQL disk nearly full | critical | > 90% of disk used for 15m |
| Pub/Sub backlog aging | warning | oldest unacked message > 10m old, for 10m |
| Pub/Sub backlog growing | warning | > 1000 undelivered messages for 15m |
| Compute Engine high CPU | warning | > 90% CPU for 30m |
| Cloud SQL high CPU | warning | > 90% CPU for 15m |
| Cloud SQL high memory | warning | > 90% memory for 15m |
| Load balancer slow backends | warning | p95 backend latency > 2s for 15m |
Deep project visibility. 1 dashboard · 24 panels · 12 alerts — packet rates, disk quota headroom, replica lag, response-class mix, dead letters, and API errors for projects you need to diagnose, not just watch.
Import this variant from the catalog. Its demand slug:
google-cloud-monitoring-otel-demand-extendedDashboard — everything in Standard, plus Packets in / out, Allocated vCPUs, Disk used vs quota, Replica lag, Responses by class, Dead letters and expired acks, and Failed API requests.
Alerts (12)
| Alert | Severity | Fires when |
|---|---|---|
| Load balancer high 5xx ratio | warning | 5xx > 5% of requests for 10m |
| Cloud SQL instance down | critical | instance not serving for 10m |
| Cloud SQL disk nearly full | critical | > 90% of disk used for 15m |
| Pub/Sub backlog aging | warning | oldest unacked message > 10m old, for 10m |
| Pub/Sub backlog growing | warning | > 1000 undelivered messages for 15m |
| Compute Engine high CPU | warning | > 90% CPU for 30m |
| Cloud SQL high CPU | warning | > 90% CPU for 15m |
| Cloud SQL high memory | warning | > 90% memory for 15m |
| Load balancer slow backends | warning | p95 backend latency > 2s for 15m |
| Cloud SQL replica lag | warning | replica > 60s behind for 15m |
| Pub/Sub expired acknowledgements | warning | any expired ack deadline for 15m |
| Cloud Storage request errors | warning | > 0.1 failed requests/s for 15m |
Dashboards
Section titled “Dashboards”Each variant imports one Google Cloud Monitoring dashboard, its panels grouped into
collapsible sections. Every dashboard carries an Instance filter (on the
project_id label), so one import covers the whole fleet — view every instance
at once, or focus on one. Legends are sortable tables showing last/mean/max per
series, so the outlier instance stands out. Dashboards are demand-driven:
importing one tells your agents to forward exactly the timeseries its panels
query, and nothing else. Panels are ordinary Perses panels — edit queries, add
panels, or retune them after import, and your changes reshape the demand
automatically.
Alerts
Section titled “Alerts”Thresholds are conservative starting points — tune them to your workload.
Next steps
Section titled “Next steps”- Demand-driven observability — why importing a demand also shapes what your agents collect.
- Agent configuration — the full agent config surface.
Thanks for your feedback!
Report sent — thank you!