GCP Log-Based Metrics Explained: Counters, Distributions, Alerts

A log-based metric turns matching Cloud Logging entries into a time-series metric in Cloud Monitoring. You write a filter that selects the log entries you care about, and GCP counts or measures them over time, giving you charts, dashboards, and alerting without changing a single line of application code.

Simple explanation

Cloud Logging receives log entries from your services. Cloud Monitoring stores numeric time-series data. These two systems work together but serve different purposes: logs are events, metrics are numbers over time.

Log-based metrics bridge the two. You write a Logging Query Language filter that matches specific log entries, for example every ERROR log from your payment service. Cloud Logging applies that filter as entries arrive, increments a counter (or extracts a value), and sends the result to Cloud Monitoring as a time-series metric. From that point, it behaves exactly like any other GCP metric: you can chart it, set thresholds, and attach alerts.

The key insight: your application does not need to know this metric exists. If the signal is already in your logs, you can make it observable without touching your code.

Think of it this way

A log entry is like a diary entry: “At 2:03 pm, the payment failed for order #8821.” A metric is like a daily tally: “Yesterday there were 47 payment failures.” Log-based metrics are the process that reads your diary and keeps the tally automatically, in real time, without you writing any extra code.

Already emitting structured logs?

If your service writes structured JSON logs with numeric fields like duration_ms or response_size, you can create a distribution metric right now. No code changes, no redeployment needed. The signal is already there.

Why teams use log-based metrics

  • Count recurring errors. You know your service logs a specific error message when a downstream call fails. A counter metric lets you alert when that error appears more than N times per minute.
  • Track latency from structured logs. If your service emits structured JSON logs with a duration_ms field, a distribution metric lets you chart p99 latency without adding an instrumentation library.
  • Monitor business events in logs. Order placed, payment declined, user signup. These signals may already be in your application logs. Log-based metrics expose them to Cloud Monitoring dashboards without new instrumentation.
  • Alert on patterns without adding code. A third-party library you cannot modify logs a deprecation warning. A log-based counter lets you alert when that warning appears, without touching the library.
  • Get visibility faster. Deploying a new metric instrumentation library takes days. Writing a log-based metric filter takes minutes. For rapid incident investigation or short-lived signals, log-based metrics are often the fastest path.
Real scenario

Your app already logs {“message”: “payment_declined”, “reason”: “insufficient_funds”, “amount_usd”: 49.99} on every failed charge. With a counter metric you can alert when payment failures exceed 50 per minute. With a distribution metric on amount_usd you can track the distribution of failed charge amounts over the day. Zero code changes, zero redeploys.

How log-based metrics work

The flow has five steps:

  1. Logs arrive in Cloud Logging. Your services, infrastructure, and GCP-managed resources write log entries continuously.
  2. A filter selects matching entries. You define a Logging Query Language (LQL) filter that matches the entries you care about. This is the same filter syntax used in Logs Explorer.
  3. Cloud Logging converts matches into a metric. For each matching entry, Cloud Logging either increments a counter or extracts a numeric value, depending on the metric type you chose.
  4. Cloud Monitoring stores the time series. The resulting metric data lands in Cloud Monitoring under the logging.googleapis.com/user/ namespace.
  5. You chart, alert, and investigate. The metric is now available in Metrics Explorer, dashboards, and alerting policies.
No historical backfill

Log-based metrics only capture data from log entries that arrive after the metric is created. If you create a metric today, you will not see data from last week. Create your critical metrics before incidents happen, not during them when you will need historical context most.

Counter metrics vs distribution metrics

Log-based metrics come in two types. Choosing the right one depends on the question you are trying to answer.

CounterDistribution
What it storesCount of matching log entriesStatistical summary of a numeric value extracted from each matching entry
Best use caseHow often did this happen?What is the range and spread of this value?
ExampleCount of ERROR logs per minuteDistribution of request durations in milliseconds
Output typeCumulative integerHistogram: min, max, mean, percentiles

Counter metrics

A counter metric increments by 1 for each log entry that matches the filter. Use counters when you care about frequency: how many errors, how many retries, how many auth failures. Counter metrics are cumulative, meaning the value only goes up. In Metrics Explorer, apply a rate alignment to see counts per minute or per second rather than a monotonically increasing total.

Distribution metrics

A distribution metric extracts a numeric value from a specified field in each matching log entry and records the statistical distribution of those values over each time window. You define a value extractor that points to the field, for example EXTRACT(jsonPayload.duration_ms).

Use distribution metrics when you care about the spread: p99 latency from HTTP access logs, the distribution of order amounts from a payment service, or the range of database query durations from a slow query log. You need structured logs with numeric fields to use distribution metrics effectively.

Analogy

Counter metrics are like counting how many cars pass a toll booth per hour. Distribution metrics are like recording the speed of each car and tracking the min, max, average, and percentiles. Same log stream, different questions.

Log-based metrics vs log-based alerts vs custom application metrics

These three approaches sound similar but are different tools. Here is how to choose between them.

ApproachHow it worksBest when
Log-based metricFilter creates a time series in Cloud MonitoringYou want charts, trends, threshold-based alerting, and long-term data
Log-based alertAlert fires directly on matching log entries, no metric createdYou want immediate notification on a specific log pattern, no trend data needed
Custom application metricApplication code emits metric data via OpenTelemetry or Monitoring APIYou need signals not present in logs, sub-second resolution, or rich label dimensions

Use a log-based metric when you want to chart trends over time, set threshold-based alerts with duration conditions, or combine the signal with other metrics on a dashboard. Use a log-based alert when you want an immediate notification on a specific log entry and do not need time-series history. Use custom application metrics when the signal does not appear in logs at all.

Picking the right tool

Log-based metric: “Show me a chart of how many 500 errors happened each hour over the last week.”
Log-based alert: “Page me the moment ‘database corruption detected’ appears anywhere in the logs, regardless of frequency.”
Custom application metric: “Track the current depth of our in-memory job queue.” That value never appears in any log; it only exists in code.

Project-scoped vs bucket-scoped log-based metrics

Log-based metrics come in two scopes that determine which log entries they can filter against.

Project-scoped metrics (the default)

A project-scoped log-based metric filters across all log entries in the project’s _Default log bucket. This is the standard type. When you create a metric through the console or with gcloud logging metrics create without specifying a bucket, you get a project-scoped metric.

Bucket-scoped metrics

A bucket-scoped log-based metric filters against log entries in a specific named log bucket. This matters when your organization routes logs to non-default buckets, such as a dedicated analytics bucket, a bucket in a centralized logging project, or a bucket with a custom retention policy.

If your organization routes application logs to a bucket named app-logs in a separate logging project, a project-scoped metric in the originating project will not see those routed entries. A bucket-scoped metric targeting app-logs will. You create bucket-scoped metrics through the Cloud Logging API or the Log-based Metrics page in the console by specifying the full bucket resource path.

Just getting started?

For most teams, project-scoped metrics cover everything you need. Bucket-scoped metrics become relevant when your organization uses log routing, centralized logging projects, or custom log buckets. If none of those apply, you can skip this distinction entirely for now.

Prerequisites and limitations

  • Permissions. Creating log-based metrics requires the logging.logMetrics.create permission. The roles/logging.admin role includes this. If you get a permission error, check with your project owner.
  • No historical backfill. Metrics only capture data from the moment of creation. Past log entries are not processed.
  • Label cardinality. Each unique combination of label values creates a separate time series. High-cardinality labels like user IDs or request IDs create enormous numbers of time series, increasing cost and degrading query performance.
  • Filter uses Logging Query Language. The filter is LQL, the same syntax used in Logs Explorer, not SQL. The : operator is a substring match; =~ is regex.
  • Data delay. After creating a metric, expect a few minutes before data appears in Cloud Monitoring. This is normal propagation delay.
  • Distribution metrics require numeric fields. The target field must be a number in the log payload. You cannot extract a string field as a distribution value.

Create a log-based metric in the console

The console is the easiest starting point, especially when building your filter iteratively.

  1. Open Cloud Logging in the GCP Console and go to Log-based Metrics in the left sidebar.
  2. Click Create Metric and choose Counter or Distribution.
  3. Give the metric a name and description. Names must be unique within the project.
  4. Write your filter in the Build filter box. Test the filter in Logs Explorer first to confirm it matches the right entries before saving.
  5. For distribution metrics, specify the value extractor field path, for example jsonPayload.duration_ms.
  6. Optionally add labels by specifying field paths and extractor expressions.
  7. Click Create Metric. Data will begin appearing in Cloud Monitoring within a few minutes.

Once created, view the metric in Metrics Explorer by searching for its name under the logging.googleapis.com/user/ namespace.

Test your filter first

Before saving a metric, paste your filter into Logs Explorer and verify it returns the exact log entries you expect. Saving a metric with a broken or overly broad filter means you will collect the wrong data from day one.

Create a log-based metric with gcloud

The gcloud logging metrics create command handles both counters and distribution metrics. Use this for scripting metric setup as part of infrastructure provisioning.

Counter metric

# Count ERROR logs from a specific Cloud Run service
gcloud logging metrics create api-error-count \
  --description="Count of error log entries from api-service" \
  --log-filter='severity>=ERROR
    resource.type="cloud_run_revision"
    resource.labels.service_name="api-service"'

Distribution metric

# Distribution of request durations extracted from structured logs
gcloud logging metrics create api-request-duration \
  --description="Distribution of request durations in milliseconds" \
  --log-filter='resource.type="cloud_run_revision"
    resource.labels.service_name="api-service"
    jsonPayload.message="Request completed"' \
  --value-extractor='EXTRACT(jsonPayload.duration_ms)'

The structured log entry this reads from would look like:

{
  "severity": "INFO",
  "message": "Request completed",
  "duration_ms": 142,
  "endpoint": "/api/orders",
  "status_code": 200
}

Common operations

# List all log-based metrics in a project
gcloud logging metrics list --project=my-project

# Describe a specific metric
gcloud logging metrics describe api-error-count --project=my-project

# Delete a metric
gcloud logging metrics delete api-error-count --project=my-project

Add labels carefully

Labels let you break a metric into dimensions. A request duration metric labeled by endpoint gives you a separate time series per API path, so you can compare p99 latency for /api/orders vs /api/users. This is powerful, and it is also where most teams accidentally create expensive problems.

Low-cardinality vs high-cardinality

Low-cardinality labels have a small, bounded set of possible values: HTTP method (GET, POST, DELETE: five values at most), status code category (2xx, 4xx, 5xx: three values), environment (prod, staging: two values). Each unique label value adds one time series per metric. A label with five possible values adds five time series. That is fine.

High-cardinality labels have unbounded or very large value sets: user ID, request ID, session token, IP address, order ID. If your service handles 100,000 unique users, extracting jsonPayload.user_id as a label creates 100,000 time series. This inflates Cloud Monitoring costs, degrades query performance, and can trigger quota limits. See Metrics in GCP for a deeper explanation of how label cardinality affects time-series storage.

# Safe: low-cardinality label (bounded set of HTTP methods)
gcloud logging metrics create request-count-by-method \
  --description="Request count by HTTP method" \
  --log-filter='resource.type="cloud_run_revision"
    resource.labels.service_name="api-service"' \
  --label-extractors='http_method=EXTRACT(jsonPayload.method)'

# Avoid: high-cardinality label (unique per request, creates millions of time series)
# --label-extractors='request_id=EXTRACT(jsonPayload.request_id)'
High-cardinality labels will cost you

Never extract user IDs, request IDs, session tokens, or order IDs as labels. Each unique value creates a new time series. At scale this results in millions of time series, dramatically higher costs, and queries that become too slow to be useful. If you cannot list every possible label value in one sentence, it is not safe to use as a label.

Use log-based metrics in dashboards and alerts

Once created, log-based metrics appear in Cloud Monitoring under the logging.googleapis.com/user/ namespace and behave like any other metric in the platform.

Metrics Explorer and dashboards

Open Metrics Explorer, search for your metric by name under the logging.googleapis.com/user/ namespace, and add it to a chart. From there, add the chart to a Cloud Monitoring dashboard. Counter metrics are cumulative, so apply a rate alignment to see per-minute counts rather than a monotonically increasing total.

Alerting policies

Log-based metrics work as conditions in alerting policies. Create an alerting policy, add a metric-threshold condition, and select your log-based metric. You can alert when an error count exceeds a threshold per minute, when p99 latency from a distribution metric goes above a value, or when a counter drops to zero (metric absence).

Dashboard pattern worth knowing

Place your error log count chart next to your request count chart on the same dashboard. When error count spikes align with a traffic increase, the problem is likely load-related. When error count spikes without a corresponding traffic change, look at recent deployments or downstream dependencies. This correlation is one of the fastest ways to narrow down a cause during incident response.

Log-based metrics are especially useful during production debugging because they let you slice a signal by log field values rather than just by resource or service. An error count labeled by endpoint tells you which path is failing. Without the label, you only know something is wrong.

When to use log-based metrics

  • Your application already emits structured logs with numeric fields, and you want those as metrics without code changes.
  • You need to count occurrences of a specific error message, warning, or business event that appears in logs.
  • You are monitoring a service you cannot modify: a third-party component, a managed GCP service with limited metric output, or a legacy system.
  • You need a quick signal during an ongoing incident, faster than deploying new instrumentation.
  • You are monitoring Cloud Run or monitoring GKE workloads that already produce structured log output.
  • You want to monitor a log-defined condition over time with threshold alerting, not just receive a one-time notification.

When not to use log-based metrics

Check built-in metrics first

Before creating a log-based metric, search the Cloud Monitoring metric browser for your service. Cloud Run, GKE, Pub/Sub, Cloud SQL, and dozens of other GCP services already expose rich built-in metrics. Using a built-in metric costs nothing extra to create, requires no filter to maintain, and often has richer label support. See the Cloud Monitoring overview for a starting point.

  • The signal is not in your logs. Log-based metrics cannot measure something your application does not log. For signals that require code instrumentation, use custom metrics via OpenTelemetry or the Cloud Monitoring API.
  • You need sub-minute resolution. Log-based metrics aggregate over time windows. If you need second-by-second visibility, application-level metrics are more appropriate.
  • A built-in metric already exists. Cloud Run, GKE, Cloud SQL, and most GCP services emit rich built-in metrics. Check what is available before building a log-based metric for something already measured.
  • You need historical data from before today. If you need to analyze logs retrospectively, use Logs Explorer or export to BigQuery. Log-based metrics only go back to when the metric was created.
  • Your log volume is extremely high and the filter is broad. Very high-volume log streams with broad filters have cardinality and cost implications. Consider log sampling or BigQuery exports for batch analysis instead.

Common beginner mistakes

  1. Expecting historical data after creating the metric. Log-based metrics only capture entries arriving after creation. There is no backfill. Create your metrics proactively, not reactively during an incident when you will need historical context most.
  2. Writing a filter that is too broad. A filter of just severity>=ERROR captures every error from every service and resource type in the project. Always scope to a specific resource.type and service name to avoid noise and inflated cardinality.
  3. Using high-cardinality values as labels. Extracting jsonPayload.user_id or jsonPayload.request_id as a label creates one time series per unique value. At scale this means millions of time series, significantly higher costs, and degraded query performance.
  4. Confusing LQL with other query syntaxes. Log-based metric filters use Logging Query Language, the same syntax as Logs Explorer. The : operator is a substring match. =~ is regex. These are not SQL operators. Mixing up the syntax produces filters that silently match nothing.
  5. Building a log-based metric when a built-in metric already exists. GCP emits hundreds of built-in metrics for Cloud Run, GKE, Cloud Storage, and more. Building a log-based metric for request count when run.googleapis.com/request_count already exists adds filter maintenance overhead for no benefit. Check what is available first.

Frequently asked questions

What is the difference between a counter metric and a distribution metric?

A counter metric increments by 1 for each log entry matching a filter. Use it to count how often something happened. A distribution metric extracts a numeric value from each matching log entry and records the statistical distribution of those values: min, max, mean, and percentiles. Use it when you care about the range and spread of values, like request latency or response sizes.

Do log-based metrics apply retroactively to historical logs?

No. Log-based metrics are computed in real time as log entries arrive. Creating a metric does not backfill data from before the metric was created. You will only see data from the moment you create the metric onward. Create important metrics before incidents happen, not during them.

When should I use log-based metrics instead of custom application metrics?

Use log-based metrics when your application already emits logs that contain the signal you need and you want to avoid changing or redeploying application code. If your service logs structured JSON with fields like duration_ms or status_code, you can turn those into metrics immediately. Use custom application metrics when you need signals that do not already appear in logs, or when you need sub-second resolution.

Can I alert on a log-based metric?

Yes. Log-based metrics appear in Cloud Monitoring under the logging.googleapis.com/user/ namespace. You can use them in alerting policy conditions, Metrics Explorer charts, and dashboards exactly like built-in metrics. Create an alerting policy and select your log-based metric as the condition target.

What labels are safe to extract from log entries?

Only extract labels with a small, bounded set of possible values. Safe examples: HTTP method (GET, POST, DELETE), status code category (2xx, 4xx, 5xx), service name, region, or environment. Unsafe examples: user IDs, request IDs, session tokens, or any field where every log entry could have a unique value. High-cardinality labels create one time series per unique label value, which inflates cost and slows queries.

Last verified: 25 March 2026 Cloud services change frequently. Verify details against official documentation before making infrastructure decisions.