An error buried in Google Cloud Logging helps nobody. Somebody has to be looking at the right query at the right moment, and nobody is looking at three in the morning. Routing GCP log-based alerts into Slack turns a log entry into a message in the channel where your team already is.
This guide connects Cloud Logging to Slack end to end: a notification channel in Cloud Monitoring, a GCP logging query, an alert policy that fires on it, and a test that proves the whole path works before you depend on it.
What this GCP and Slack setup gives you
- A Slack notification channel registered in Cloud Monitoring
- A log-based alert that fires on a specific logging query rather than on everything
- Messages arriving in a Slack channel with the log entry attached
- Sensible limits on repeat notifications, so one bad deploy doesn't produce four hundred messages
- A way to test the alert without waiting for a real incident
GCP log-based alerts and log-based metrics are not the same thing
Google Cloud offers two mechanisms with similar names, and picking the wrong one is the most common reason this setup goes sideways.
A log-based alert fires when a log entry matching your query appears. One matching entry, one incident. Use it when any occurrence matters: a payment failure, an authentication error, a stack trace in production.
A log-based metric counts matching entries over time, and you then alert on that count crossing a threshold. Use it when volume is the signal rather than existence: more than fifty 500s in five minutes, or an error rate climbing above its baseline.
Most people asking for "alerts from logs" want the first. This guide builds that, and covers the metric approach at the end for when you need it.
Step 1: Connect Slack to Cloud Monitoring
This is the step the alert depends on, so do it first. An alert policy with no notification channel fires silently and looks like nothing happened.
In the Google Cloud console, go to Monitoring, Alerting, Edit notification channels. Find the Slack row and click Add new. You'll be redirected to Slack to authorize the Google Cloud Monitoring app, then asked which channel should receive alerts.
Two things commonly block this. You need permission to install apps in the Slack workspace, which in most organizations means an admin has to approve the request. And the Monitoring app has to be invited to the destination channel before it can post there. For a private channel, run this in Slack:
/invite @Google Cloud Monitoring
The dialog asks for two values. Slack Channel Name is the channel itself, entered with its leading #. Cloud Alerting Display Name is what you'll pick from a dropdown when attaching this channel to a policy, so make it say what it's for, such as slack-prod-alerts. "Slack" on its own gets ambiguous the moment you add a second one.
Before saving, click Send test notification. A message should appear in the Slack channel within seconds. This one button separates "the integration is broken" from "my alert query is wrong" later on, and it costs nothing to press now. If the test fails here, no alert policy you build on top of this channel will ever deliver.
A note on webhooks
You may be tempted to skip the integration and point a webhook notification channel at a Slack incoming webhook URL. It won't render properly. Cloud Monitoring posts its own JSON structure, and Slack's incoming webhooks expect a payload with a top-level text field. The two don't line up.
If you need custom formatting, the working path is a Pub/Sub notification channel with a Cloud Function subscribed to it, translating Monitoring's payload into Slack's Block Kit format. That's worth doing when you want rich messages with buttons. For everything else, the native integration is less to maintain.
Step 2: Write the Cloud Logging query
An alert is only as good as the query behind it. Open Logging, Logs Explorer in the GCP console and build the query there first, where you can see what it actually matches.
Start broad, then narrow. A query for unhandled errors in a Cloud Run service:
resource.type="cloud_run_revision"
resource.labels.service_name="orders-api"
severity>=ERROR
For a specific pattern in the log body, add a regular expression match:
resource.type="k8s_container"
severity>=ERROR
jsonPayload.message=~"OutOfMemoryError"
To exclude the noise you already know about, subtract it:
resource.type="cloud_run_revision"
severity>=ERROR
NOT textPayload=~"context deadline exceeded"
Run the query over the last seven days before you go any further. The count you see is roughly how many Slack messages this alert would have sent in that period. If that number is in the hundreds, tighten the query now. An alert that fires constantly gets muted within a week, and a muted alert is worse than no alert because it creates the impression of coverage.
Step 3: Create the log-based alert
With the query still in the Logs Explorer, click Create alert above the results. The wizard carries your query across, which is why building it here rather than in the alerting console saves a round trip.
Five fields matter:
- Alert name. Write what happened, not what fired. "Orders API returning 5xx" beats "Log alert 3", because the name becomes the Slack message headline.
- Documentation. Optional, and worth filling in. It renders inside the notification, so a link to the runbook lands in Slack alongside the alert.
- Log query. Carried over from the Logs Explorer. Check it survived the transfer.
- Time between notifications. How long to wait before sending again while the condition persists. Five minutes suits most services. This is your main defence against a crash loop flooding the channel.
- Incident autoclose duration. How long an incident stays open with no further matches. Thirty minutes is a reasonable default; the seven-day default leaves stale incidents open long after the problem is gone.
On the final screen, select the Slack notification channel you created in step one. If the dropdown is empty, the channel wasn't saved, and going back is faster than finishing and debugging afterwards.
Step 4: Test it end to end in Slack
Do not skip this. An untested alert is an assumption.
Write a log entry that matches your query on purpose:
gcloud logging write orders-api-test \
'{"message": "OutOfMemoryError: synthetic test entry", "severity": "ERROR"}' \
--payload-type=json
Adjust the log name and payload so the entry satisfies your filter. Within a minute or two you should see a message in Slack. If nothing arrives, work through the failures below in order.
Once it lands, resolve the incident in Cloud Monitoring so you start from a clean state.
When to use a log-based metric instead
If the signal is a rate rather than a single event, count first and alert on the count. Create the metric from the same query:
gcloud logging metrics create orders_api_errors \
--description="ERROR and above from orders-api" \
--log-filter='resource.type="cloud_run_revision"
resource.labels.service_name="orders-api"
severity>=ERROR'
Then build an alert policy on that metric with a threshold condition, pointing at the same Slack channel. The tradeoff is latency: a metric-threshold alert has to wait for the aggregation window to close, so it's slower than a log-based alert but far quieter on noisy services.
GCP permissions you'll need
Alert configuration spans two Google Cloud products, which is why a user with full Logging access can still be unable to finish this.
roles/logging.viewerto read logs and build the queryroles/monitoring.alertPolicyEditorto create the alert policyroles/monitoring.notificationChannelEditorto register the Slack channelroles/logging.configWriteras well, if you're creating log-based metrics
Grant these at project level for the person doing the setup. If your organization restricts app installation in Slack, you'll also need a workspace admin for step one, and that approval is usually the longest part of the whole task.
Common GCP and Slack failures
The incident opens but Slack stays quiet
The policy fired with no notification channel attached, or with a channel that was never saved. Open the incident in Cloud Monitoring and check its notification history. If the channel is listed but the message didn't arrive, the Monitoring app isn't in the target Slack channel.
Nothing fires at all
Test the query in the Logs Explorer over a window where you know matching entries exist. A query that returns nothing there will never fire an alert. Watch for filters copied from another project, where resource.labels values don't match anything.
Hundreds of messages from one incident
Time between notifications is too short, or the query is too broad. Widen the notification interval first, then tighten the query. A crash-looping container can generate thousands of matching entries per minute.
Incidents never close
Autoclose is still on its long default. Reduce it, and remember it counts from the last matching entry, not from when the incident opened.
Common questions about GCP log-based alerts
Can I send GCP alerts to Slack without the Cloud Monitoring app?
Yes, through a Pub/Sub notification channel and a Cloud Function that posts to a Slack incoming webhook. It's more to build and maintain, and it's the right choice when you need custom message formatting or want to route different alerts to different channels programmatically.
How quickly does a log-based alert reach Slack?
Typically under a minute from the log entry being written. Metric-threshold alerts are slower, because they wait for the aggregation window plus the retest interval.
Do log-based alerts cost anything?
The alerting itself has no separate charge, but the logs it reads are billed under Cloud Logging ingestion, and log-based metrics count toward chargeable metrics. A very broad query is a cost decision as well as a noise one.
Can one alert notify Slack and email together?
Yes. An alert policy accepts multiple notification channels, so you can send to Slack for visibility and to email or PagerDuty for anything that needs an owner.
Why does my alert fire for logs from the wrong environment?
The query is missing a resource label. Add the service, cluster, or namespace explicitly rather than relying on the project boundary, particularly where staging and production share a project.
Where to take your GCP alerting next
Once GCP log-based alerts are landing reliably in Slack, three things are worth adding:
- Alert policies as code, defined in Terraform, so the same alerting exists in every environment without anyone rebuilding it by hand
- Log sinks to BigQuery, for the questions you want to ask after an incident rather than during one
- Service level objectives, so you alert on user-visible degradation rather than on individual log lines
Start with a handful of alerts that fire rarely and mean something. Coverage you trust beats coverage that's comprehensive and ignored.



