# GCP SRE & Observability — Part 4: Cloud Logging, Metrics, Dashboards & Alerting

> **Series:** GCP SRE & Observability (4 of 6) — aligned to Professional Cloud DevOps Engineer (PCDE) exam sections 3-5
> **Part 1:** `01-slis-slos-error-budgets-and-service-lifecycle.md` — SLIs, SLOs, Error Budgets & Service Lifecycle
> **Part 2:** `02-capacity-planning-autoscaling-and-incident-mitigation.md` — Capacity Planning, Autoscaling & Mitigating Incident Impact
> **Part 3:** `03-instrumenting-telemetry.md` — Instrumenting Telemetry
> **Part 4:** This file — Cloud Logging, Metrics, Dashboards & Alerting
> **Part 5:** `05-distributed-tracing-and-troubleshooting.md` — Distributed Tracing & Troubleshooting Workflows
> **Part 6:** `06-performance-monitoring-and-finops.md` — Performance Monitoring & FinOps on GCP
> **Questions:** `questions.md`

> Assumes Part 3's telemetry is already flowing — this chapter is entirely about what happens to it once it's collected: querying it, dashboarding it, and alerting on it at the depth PCDE tests.

## Table of Contents

1. [What This Chapter Covers](#what-this-chapter-covers)
2. [The Incident That Opens This Chapter](#the-incident-that-opens-this-chapter)
3. [Log Analytics: Querying Logs With SQL, Not Just LQL](#log-analytics-querying-logs-with-sql-not-just-lql)
4. [Export, Retention, and the Two Default Buckets](#export-retention-and-the-two-default-buckets)
5. [Handling Sensitive Data: Redacting PII and PHI](#handling-sensitive-data-redacting-pii-and-phi)
6. [Gemini Cloud Assist for Log Analysis](#gemini-cloud-assist-for-log-analysis)
7. [The Metrics Explorer and PromQL, Not MQL](#the-metrics-explorer-and-promql-not-mql)
8. [Dashboards as Code](#dashboards-as-code)
9. [Alert Documentation: Turning a Page Into a Playbook](#alert-documentation-turning-a-page-into-a-playbook)
10. [Third-Party Alert Routing and the Shared-Backend Risk](#third-party-alert-routing-and-the-shared-backend-risk)
11. [Cost-Control Alerting: A Different Kind of Alert Entirely](#cost-control-alerting-a-different-kind-of-alert-entirely)
12. [Terminology Map: Log/Metrics Analysis Across AWS, Azure, and GCP](#terminology-map-logmetrics-analysis-across-aws-azure-and-gcp)
13. [A Full Worked Example: Meridian's Incident-Ready Dashboard](#a-full-worked-example-meridians-incident-ready-dashboard)
14. [Common Mistakes and Interview Traps](#common-mistakes-and-interview-traps)
15. [Worked Practice Problems](#worked-practice-problems)
16. [Summary and What's Next](#summary-and-whats-next)

## What This Chapter Covers

Part 3 built the collection layer; this chapter is everything PCDE groups under "managing and analyzing logs" and "managing metrics, dashboards, and alerts" — the two exam objectives that turn raw, collected telemetry into something a human can actually query, visualize, and get paged by. [GCP Cloud Engineer Foundations Part 8](/tutorials/gcp-cloud-engineer-foundations/monitoring-logging-and-operations) already covered the Logging Query Language, basic exports, and a single alerting policy at ACE depth — this chapter goes deeper into each, plus two areas Foundations never touched: querying logs with real SQL via Log Analytics, and redacting sensitive data before it's ever queryable at all.

## The Incident That Opens This Chapter

Two weeks after Part 3's coverage-gap incident was resolved, Meridian hit a different, quieter failure: a PagerDuty integration outage on Google's side meant `shipment-api`'s burn-rate alert from Part 1 fired correctly but **never reached anyone** — the notification channel itself was down, not the alerting policy. Nobody noticed for forty minutes, because Meridian had followed Foundations Part 8's advice to "consolidate every alert onto one trusted channel" literally: one channel, no redundancy, and that one channel happened to be the one that went dark.

```mermaid
sequenceDiagram
    participant SLO as SLO burn-rate<br/>alert policy
    participant CM as Cloud Monitoring
    participant PD as PagerDuty channel<br/>(Google-hosted integration)
    participant OnCall as On-call engineer

    SLO->>CM: Burn rate exceeds threshold
    CM->>PD: Fire notification
    Note over PD: PagerDuty integration<br/>backend outage (Google side)
    PD--xOnCall: Notification never delivered
    Note over OnCall: 40 minutes pass,<br/>no page received
```

**What to notice**: the policy did exactly what it was designed to do — the failure was entirely in the delivery mechanism, a layer this course hasn't examined yet. This chapter's section on third-party alert routing explains exactly why this happened and the specific fix Meridian's team applied, later in this chapter — not a contradiction of the "one trusted channel" advice, but a real refinement of it.

## Log Analytics: Querying Logs With SQL, Not Just LQL

Foundations Part 8 taught the Logging Query Language (LQL) — genuinely closer to a real query language than keyword search, but still limited to filtering and simple functions. **Log Analytics upgrades a log bucket to also expose its contents as a linked BigQuery dataset — a live view, not a copy — queryable with full SQL: joins, aggregations, window functions, anything BigQuery itself supports.**

```bash
# Upgrade shipment-api's log bucket to Log Analytics, then create the
# linked BigQuery dataset Priya's team now queries directly for
# anything LQL's filter-and-function model can't express
gcloud logging buckets update _Default \
  --location=global \
  --project=meridian-shipment-prod \
  --enable-analytics

gcloud logging links create shipment-api-analytics \
  --bucket=_Default \
  --location=global \
  --project=meridian-shipment-prod
```

```sql
-- A query LQL genuinely can't express cleanly: correlate the top 5
-- customer IDs by error volume against their total request volume
-- in the same window, to distinguish "one customer is having a bad
-- time" from "everyone's error rate went up equally"
SELECT
  json_payload.customer_id,
  COUNTIF(severity = 'ERROR') AS error_count,
  COUNT(*) AS total_requests,
  ROUND(COUNTIF(severity = 'ERROR') / COUNT(*) * 100, 2) AS error_rate_pct
FROM `meridian-shipment-prod.shipment_api_analytics._Default._AllLogs`
WHERE timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)
GROUP BY json_payload.customer_id
ORDER BY error_count DESC
LIMIT 5
```

| | Logs Explorer + LQL | Log Analytics + SQL |
|---|---|---|
| Best fit | A quick filtered lookup during active triage — "show me errors for this service in the last 15 minutes" | Aggregation, joins, and statistical analysis across a wider window |
| Learning curve | Low — filter syntax, a handful of functions | Full SQL — BigQuery's own dialect, genuinely more powerful and more to learn |
| Cost model | Included in standard log storage | No separate ingestion/storage cost (it's a live view, not a copy) — BigQuery query cost applies per the standard on-demand or reserved-slot pricing |
| Real-time feel | Near-instant for a targeted filter | Slower for a large aggregation, same as any BigQuery query |

> [!TIP]
> **Best Practice**: reach for Logs Explorer during active incident triage, where speed matters more than analytical power — and reach for Log Analytics for the *postmortem*, where a genuinely aggregate question ("which customer segment was actually affected, and by how much") is exactly the kind SQL answers cleanly and LQL can't.

## Export, Retention, and the Two Default Buckets

Foundations Part 8 already covered exporting logs to BigQuery, Cloud Storage, and Pub/Sub — the mechanism doesn't change here. What's worth adding at this depth: **every GCP project ships with two default log buckets with meaningfully different retention, and knowing which is which avoids a real, easy mistake.**

| Bucket | Default retention | Configurable? | Holds |
|---|---|---|---|
| `_Required` | 400 days | No — fixed | Admin Activity, System Event audit logs (the always-on, free logs from Foundations Part 8) |
| `_Default` | 30 days | Yes, 1-3650 days | Everything else — application logs, Data Access audit logs if enabled |

```bash
# Extend shipment-api's _Default bucket retention to a full year —
# Meridian's actual choice after a compliance review required a
# longer lookback window than the 30-day default provided
gcloud logging buckets update _Default \
  --location=global \
  --project=meridian-shipment-prod \
  --retention-days=365
```

> [!WARNING]
> **Shortening retention on a bucket makes logs older than the new period immediately unqueryable** — Cloud Logging gives a 7-day grace period before actually deleting them, during which increasing retention again restores access, but treat that grace period as an emergency undo, not a planned workflow. Shortening retention should be a deliberate decision made with the compliance/legal team's sign-off, not a routine cost-cutting reflex — the same "deliberate, not reflexively" discipline Part 3 applied to log exclusion filters applies here to retention windows too.

## Handling Sensitive Data: Redacting PII and PHI

A log-based metric or a structured log field that captures a customer's shipment address, a payment token fragment, or any other sensitive value is a real compliance exposure the moment it's ingested — and per Part 3's "cheapest log is the one never ingested" principle, the right point to redact is *before* storage, not after.

```mermaid
flowchart LR
    App["Application<br/>emits raw log"] --> Router["Log Router"]
    Router -->|"Pub/Sub sink,<br/>bypassing default storage"| PubSub["Pub/Sub topic"]
    PubSub --> Dataflow["Dataflow pipeline"]
    Dataflow -->|"Sensitive Data Protection<br/>(Cloud DLP) API call"| DLP["Detect + de-identify<br/>PII/PHI"]
    DLP --> Redacted["Redacted log entry"]
    Redacted --> Bucket["Log bucket /<br/>BigQuery"]

    classDef raw fill:#fbe8e6,stroke:#b3261e,color:#10161c
    classDef process fill:#e5f0fa,stroke:#1d6fb8,color:#10161c
    classDef clean fill:#e5f5ea,stroke:#1f8a4c,color:#10161c
    class App raw
    class Router,PubSub,Dataflow,DLP process
    class Redacted,Bucket clean
```

**What to notice**: this pipeline deliberately routes around the default log-bucket path — a log that reaches `_Default` unredacted has already been ingested unredacted, so the whole point of this architecture is intercepting via a Pub/Sub sink *before* that happens, processing through Sensitive Data Protection (Cloud DLP), and only then writing the clean version to storage.

| De-identification method | Reversible? | Fits |
|---|---|---|
| Masking (`****`) | No | A field with no legitimate downstream need to ever see the real value again |
| Tokenization (pseudo-ID) | Yes, with the encryption key | A value support/engineering occasionally needs to re-identify with proper authorization |
| Format-preserving encryption | Yes, with the key | A field where downstream systems validate the *shape* of the data (a card-number-shaped string) even though the real value is hidden |
| Bucketing (e.g., exact age → age range) | No | A value useful in aggregate but risky as an exact match |

> [!IMPORTANT]
> `shipment-api`'s own structured logs include a `customer_address` field used for exactly one legitimate purpose — debugging a specific delivery-routing failure — and Meridian's team chose tokenization specifically because that debugging need occasionally requires the real value, with re-identification gated behind a separate, audited IAM permission rather than open to anyone who can read the log bucket.

## Gemini Cloud Assist for Log Analysis

Foundations Part 8 already introduced Gemini Cloud Assist correlating Monitoring, Logging, and Trace data for a "why did latency spike" question. The PCDE-depth addition: Gemini Cloud Assist can generate an LQL or SQL query *from a natural-language description* of what you're looking for, genuinely useful when the target is a Log Analytics dataset and the analyst doesn't already know BigQuery SQL well — asking "show me the top 5 customers by error rate in the last hour" can produce a working starting query close to the one this chapter already hand-wrote above.

> [!NOTE]
> The same caution Foundations Part 8 already established applies without modification here: treat a Gemini-generated query as a fast first draft to verify against the actual data, not a final answer to trust blindly — a subtly wrong `GROUP BY` or a misunderstood field name produces a query that runs successfully and returns a plausible-looking, wrong result, which is a harder failure to catch than a query that simply errors out.

## The Metrics Explorer and PromQL, Not MQL

Part 2 already established that PromQL, not the older Monitoring Query Language (MQL), is Cloud Monitoring's current recommended query path for new work — including inside the Metrics Explorer itself, where a PromQL query can be built either through the visual query builder or typed directly.

```promql
# A Metrics Explorer PromQL query for shipment-api's p99 latency,
# the same query language used for MIG capacity forecasting in Part 2
# and for Managed Service for Prometheus recording rules in Part 3 —
# one query language across every one of these surfaces now
histogram_quantile(0.99,
  sum(rate(run_googleapis_com:request_latencies_bucket{
    resource_type="cloud_run_revision",
    resource_label_service_name="shipment-api"
  }[5m])) by (le)
)
```

💡 **The transferable insight**: this is the same convergence Foundations Part 8's terminology map already noted for Managed Service for Prometheus specifically — PromQL has become Cloud Monitoring's lingua franca across recording rules, alerting conditions, and now the Metrics Explorer itself, meaning the PromQL skill built anywhere in this course transfers everywhere else in it, not just within one product surface.

## Dashboards as Code

A dashboard clicked together in the console is exactly the kind of undocumented, un-reviewed infrastructure [GCP DevOps & CI/CD Platform](/tutorials/gcp-devops-cicd-platform) spent its whole first course establishing shouldn't exist for anything else — Cloud Monitoring dashboards are no exception, and `google_monitoring_dashboard` manages them the same way every other piece of Meridian's infrastructure is managed.

```hcl
resource "google_monitoring_dashboard" "shipment_api_golden_signals" {
  dashboard_json = jsonencode({
    displayName = "shipment-api — Golden Signals"
    mosaicLayout = {
      columns = 12
      tiles = [
        {
          xPos = 0, yPos = 0, width = 6, height = 4
          widget = {
            title = "Request rate"
            xyChart = {
              dataSets = [{
                timeSeriesQuery = {
                  prometheusQuery = "sum(rate(run_googleapis_com:request_count{resource_label_service_name=\"shipment-api\"}[5m]))"
                }
              }]
            }
          }
        },
        {
          xPos = 6, yPos = 0, width = 6, height = 4
          widget = {
            title = "p99 latency"
            xyChart = {
              dataSets = [{
                timeSeriesQuery = {
                  prometheusQuery = "histogram_quantile(0.99, sum(rate(run_googleapis_com:request_latencies_bucket{resource_label_service_name=\"shipment-api\"}[5m])) by (le))"
                }
              }]
            }
          }
        }
      ]
    }
  })
}
```

> [!TIP]
> **Best Practice**: build one "golden signals" dashboard per service, checked into the same Terraform module as the service's own infrastructure, rather than one sprawling org-wide dashboard everyone half-maintains. A per-service dashboard reviewed in the same pull request as an infrastructure change stays accurate the way a shared, no-owner dashboard reliably doesn't.

## Alert Documentation: Turning a Page Into a Playbook

Every alerting policy supports a `documentation` field with a title, Markdown-formatted content, and up to three `Link` objects — the mechanism the exam guide's "playbooks" bullet refers to. An alert with no documentation forces the responder to reconstruct context from scratch at 3am; an alert with a good one hands them the first three diagnostic steps immediately.

```json
{
  "displayName": "shipment-api SLO — Fast Burn (page immediately)",
  "documentation": {
    "content": "**First steps**: check the Golden Signals dashboard for a request-rate or error-rate spike correlated with a recent deploy. If correlated, use Part 2's rollback runbook. If not, check for a capacity shortfall per Part 2's decision framework.",
    "mimeType": "text/markdown",
    "links": [
      { "displayName": "Golden Signals Dashboard", "url": "https://console.cloud.google.com/monitoring/dashboards/..." },
      { "displayName": "Incident Runbook", "url": "https://meridian.internal/runbooks/shipment-api" }
    ]
  }
}
```

Cloud Monitoring also ships pre-built **interactive playbook dashboards** for common Compute Engine failure shapes (host events, MIG autoscaling, health-check failures, resource-availability errors) — a genuinely useful starting point for a team that hasn't yet written its own, accessible directly from the Dashboards page's GCE-filtered category.

## Third-Party Alert Routing and the Shared-Backend Risk

Now the payoff for this chapter's opening incident: **Cloud Mobile App, PagerDuty, webhook, and Slack notification channels all route through a single shared Google-internal delivery service — meaning they are not actually independent failure domains from each other, even though they look like separate integrations.** Meridian's "one trusted channel" policy from Foundations Part 8 was correct advice for *avoiding alert fatigue across multiple noisy channels* — but it accidentally created a single point of failure at the delivery-mechanism layer, a different problem the earlier chapter never addressed because it wasn't in scope there.

```bash
# Meridian's actual fix: keep PagerDuty as the primary channel (still
# consolidated, still the one trusted path for routine triage), but
# add email as a genuinely independent-backend redundant channel on
# every P1 alerting policy specifically
gcloud beta monitoring channels create \
  --display-name="shipment-api-oncall-email-backup" \
  --type=email \
  --channel-labels=email_address=oncall-backup@meridian.example.com
```

| Notification channel type | Shares Google's internal delivery service with... |
|---|---|
| PagerDuty | Cloud Mobile App, webhook, Slack |
| Webhook | Cloud Mobile App, PagerDuty, Slack |
| Slack | Cloud Mobile App, PagerDuty, webhook |
| Email | None of the above — genuinely independent |
| Pub/Sub | None of the above — genuinely independent |

> [!IMPORTANT]
> "Consolidate alerts onto one trusted channel" (Foundations Part 8) and "add a genuinely independent redundant channel" (this chapter) are not in tension — the first avoids alert fatigue from too many noisy sources, the second protects against the single delivery mechanism itself failing. Apply both: one primary channel for routine visibility, one independent-backend channel specifically for the alerts where a missed page has real consequences.

## Cost-Control Alerting: A Different Kind of Alert Entirely

The exam guide lists "cost control" alongside SLI/SLO-based alerting under the same "configuring alerting and alerting policies" bullet — worth flagging because it's a genuinely different mechanism, not a variant of an SLO burn-rate policy. **Budget alerts live in Cloud Billing, not Cloud Monitoring**, and Foundations Part 2 already built one for Meridian's monthly spend. What's new at this depth: a **billing-metric-based Cloud Monitoring alert** for a *rate* of spend, distinct from a budget threshold — useful for catching a cost spike fast, before it accumulates enough to cross a monthly budget's own threshold.

```bash
# A Cloud Monitoring alert on billing.googleapis.com/billing/total_cost's
# rate of change — catches a runaway cost spike (an accidentally
# unbounded autoscaling policy, say) within hours, rather than waiting
# for the monthly budget alert to notice the cumulative total later
gcloud alpha monitoring policies create \
  --display-name="Unusual cost acceleration — meridian-shipment-prod" \
  --condition-display-name="Daily spend rate 3x above 7-day average" \
  --condition-filter='metric.type="billing.googleapis.com/billing/total_cost"' \
  --condition-threshold-value=3.0
```

## Terminology Map: Log/Metrics Analysis Across AWS, Azure, and GCP

| Concept | GCP | AWS | Azure | Where the mapping breaks down |
|---|---|---|---|---|
| SQL over log data | Cloud Logging Log Analytics (linked BigQuery dataset, live view) | CloudWatch Logs Insights (its own query language, not full SQL) / Athena over exported logs | Azure Monitor Logs (KQL, not SQL) | GCP is the only one of the three offering genuine full-SQL analysis natively over live log data without a separate export/copy step |
| Sensitive-data redaction in logs | Sensitive Data Protection (Cloud DLP) via a Pub/Sub + Dataflow pipeline | Macie (primarily S3-focused) + custom Lambda redaction | Purview (broader data governance, not log-pipeline-native) | GCP's DLP-in-the-log-pipeline pattern is the most directly log-native of the three |
| Dashboards as code | `google_monitoring_dashboard` (Terraform) | CloudWatch Dashboard (CloudFormation) | Azure Monitor Workbook (ARM/Bicep) | Conceptually aligned across all three |
| Alert documentation/playbooks | `documentation` field on an alert policy, GCE interactive playbook dashboards | CloudWatch Alarm description field (plain text, no rich links) | Azure Monitor Action Group + separate runbook automation | GCP's structured `Link` objects are a genuine step up from a plain description field |

## A Full Worked Example: Meridian's Incident-Ready Dashboard

The concrete sequence tying this chapter's pieces together, built in response to both incidents this chapter opened with:

```bash
# 1. Upgrade shipment-api's log bucket to Log Analytics (shown earlier)
gcloud logging buckets update _Default --location=global \
  --project=meridian-shipment-prod --enable-analytics

# 2. Terraform apply for the golden-signals dashboard (shown earlier)
terraform apply -target=google_monitoring_dashboard.shipment_api_golden_signals

# 3. Redundant email notification channel, independent of the shared
#    PagerDuty/webhook/Slack delivery backend
gcloud beta monitoring channels create \
  --display-name="shipment-api-oncall-email-backup" --type=email \
  --channel-labels=email_address=oncall-backup@meridian.example.com

# 4. Attach documentation + both notification channels to the
#    burn-rate alerting policy from Part 1
gcloud alpha monitoring policies update FAST_BURN_POLICY_ID \
  --add-notification-channels=PAGERDUTY_CHANNEL_ID,EMAIL_BACKUP_CHANNEL_ID
```

🧪 **Hands-on checkpoint**: after step 4, use Cloud Monitoring's "Send test notification" action on the updated policy and confirm the page actually arrives on *both* channels — verifying the redundant path works before an incident, not discovering during one that the backup channel was misconfigured the whole time.

## Common Mistakes and Interview Traps

| Mistake | Why it's wrong | What to say/do instead |
|---|---|---|
| Using Logs Explorer/LQL for a heavy aggregate analysis | LQL isn't built for joins, statistical aggregation, or multi-field correlation | Reach for Log Analytics' linked BigQuery dataset and real SQL for that class of question |
| Shortening log retention as a routine cost-cutting move | Logs older than the new period become immediately unqueryable, with only a 7-day grace period | Treat retention changes as deliberate, compliance-reviewed decisions, not routine cost tuning |
| Letting an application log a sensitive field with no redaction plan | Ingested-unredacted data is a real, immediate compliance exposure | Route through a Pub/Sub sink + DLP pipeline before it ever reaches a queryable bucket |
| Assuming PagerDuty, webhook, and Slack channels are independent failure domains | All three (plus Cloud Mobile App) share one Google-internal delivery backend | Pair a primary consolidated channel with a genuinely independent one (email or Pub/Sub) for high-stakes alerts |
| Treating a monthly budget alert as sufficient cost-spike detection | A budget alert only fires once cumulative spend crosses a threshold, which can be weeks into a runaway cost | Add a rate-of-change billing metric alert to catch acceleration fast, independent of the cumulative budget check |
| Clicking a dashboard together in the console for a production service | Undocumented, unreviewed, easy to silently drift from what the team actually needs | Manage it as Terraform (`google_monitoring_dashboard`), reviewed in the same PR as the service's own infrastructure |

## Worked Practice Problems

**Problem 1**: Meridian's postmortem team wants to know which of `shipment-api`'s customer segments were disproportionately affected by a recent incident, correlating error rate against total request volume per segment. Which tool fits, and why not the Logs Explorer?

*Answer*: Log Analytics' linked BigQuery dataset, queried with SQL — this requires a `GROUP BY`-style aggregation across every log entry in the incident window, correlating two computed values (error count and total count) per customer segment, which is exactly the class of analytical query LQL's filter-and-function model isn't built for. The Logs Explorer excels at a targeted, filtered lookup during active triage, not this kind of aggregate cross-segment analysis.

**Problem 2**: A PagerDuty-side outage silently swallows a real SLO burn-rate alert, and nobody notices for forty minutes despite the alerting policy itself firing correctly. What's the actual root cause, and what should change?

*Answer*: The root cause is that PagerDuty, webhook, Slack, and Cloud Mobile App notification channels all share a single Google-internal delivery backend — so a "consolidate onto one trusted channel" policy, while correct for avoiding alert fatigue, accidentally created a single point of failure at the delivery layer specifically. The fix is adding a genuinely independent-backend channel (email or Pub/Sub) as a redundant path on high-stakes alerting policies, keeping the primary consolidated channel for routine visibility.

**Problem 3**: A team wants to redact a customer's shipping address from `shipment-api`'s logs, but a specific, audited debugging workflow occasionally needs the real value back. Which de-identification method fits, and why not simple masking?

*Answer*: Tokenization — it replaces the real value with a pseudo-ID that can be reversed back to the original given the encryption key, which fits a legitimate, occasional, audited need to re-identify the value. Masking is irreversible by design, which would permanently destroy the data the debugging workflow occasionally needs — the right method depends on whether reversibility is a genuine, controlled requirement or not, not just on "how sensitive is this field."

## Summary and What's Next

This chapter turned Part 3's collected telemetry into something operationally usable: Log Analytics' linked BigQuery dataset for real SQL analysis beyond LQL's reach, retention and the `_Required`/`_Default` bucket split, a concrete DLP-based redaction pipeline for sensitive fields, PromQL as the now-unified query language across the Metrics Explorer, recording rules, and alerting conditions alike, dashboards and alert documentation managed as code and treated as first-class infrastructure, and the non-obvious shared-backend risk behind several notification channel types that look independent but aren't. Meridian's two opening incidents — a silently swallowed page and (from Part 3) a silent telemetry coverage gap — are now both closed with concrete, documented fixes rather than lingering as unaddressed gaps in the observability stack this course has been building.

**Part 5** moves from metrics and logs to the third pillar this course hasn't gone deep on yet: distributed tracing at real depth, and the systematic, multi-tool troubleshooting workflow that ties Monitoring, Logging, and Trace together into one coherent investigation instead of three disconnected tools reached for one at a time.
