Book TOC · Previous · Chapter 6 of 7 · Next

Chapter 6: Production Observability, OpenTelemetry Distributed Tracing & AI-Assisted Troubleshooting

Subsections Covered: 4.3 (5 Considerations · 10 Custom Visual Diagrams)

Chapter Focus: Structured JSON logging (trace correlation), OpenTelemetry instrumentation, Cloud Trace latency waterfalls, Cloud Profiler flame graphs, Error Reporting, and Gemini Cloud Assist.


Subsection 4.3: Troubleshooting and observability

Section 4: Integrating Applications with Google Cloud Services

The Big Picture

When a monolith fails, a single stack trace in one file tells you what broke. When a request flows across an API Gateway, three Cloud Run microservices, a Pub/Sub topic, and Cloud Spanner, and p99 latency suddenly jumps from 120ms to 4.5 seconds for 3% of users, traditional plaintext logging leaves you completely blind. Subsection 4.3 tests whether you can engineer a complete observability pipeline across five pillars:

  1. The Unstructured Plaintext Log Trap (4.3a, 4.3c): Printing multiline plaintext strings (console.log("Error for user " + uid)) to stdout. Cloud Logging treats each newline as a separate DEFAULT-severity log entry, breaking stack traces into 20 disconnected lines and preventing field-based filtering (jsonPayload.user_id="123") and automatic Error Reporting exception grouping.
  2. Broken Distributed Trace Context Across Hops (4.3a, 4.3d): Instrumenting microservices with OpenTelemetry or Cloud Trace, but forgetting to propagate the traceparent (W3C Trace Context) or X-Cloud-Trace-Context HTTP header on outbound fetch/grpc requests—and forgetting to inject the logging.googleapis.com/trace field into structured JSON logs. Without header propagation, a single user checkout splinters into 5 unlinked single-service traces, and clicking a slow span in Cloud Trace shows zero associated logs!
  3. Confusing Latency Tracing (Cloud Trace) with Code-Level CPU/Heap Hotspots (Cloud Profiler) (4.3b): Using Cloud Trace to figure out which line of Go/Java code is burning 90% CPU or leaking memory (Cloud Trace shows RPC/span duration across services, whereas Cloud Profiler uses low-overhead continuous statistical sampling to render flame graphs of exact functions, CPU time, and heap allocations).
  4. Ignoring AI-Assisted Root-Cause Synthesis (4.3e): Spending 45 minutes manually correlating log fields, metric spikes, and deployment revisions during an incident instead of using Gemini Cloud Assist in Google Cloud Observability to summarize log anomalies, explain cryptic GKE/Cloud Run error codes, and generate Log Analytics (SQL) / PromQL queries.
1. Code Instrumentation & Context Propagation (4.3a, 4.3d) Incoming Request (W3C traceparent / X-Cloud-Trace-Context) Microservice Code (OpenTelemetry SDK) Downstream Microservice / DB Cloud Run Built-in Agent or Ops Agent / GKE Collector Microservice Code --[Propagate Trace Header]--> Downstream Microservice / DB Microservice Code --[Emit Single-Line Structured JSON to stdout • severity: ]--> Cloud Run Built-in Agent 2. Google Cloud Observability Suite (4.3b, 4.3c) Cloud Run Built-in Agent or Ops Agent / GKE Collector Cloud Logging • Log Router Sinks (BigQuery / GCS Archive / PubSub) • Log-Based Metrics Error Reporting • Groups & Deduplicates Exceptions • Fires New-Error Alerts Cloud Trace • Waterfall Latency Graphs • Correlated Logs in Span View Cloud Monitoring • Golden Signals (Latency, Traffic, Errors, Saturation) • Uptime Checks & SLO Burn-Rate Alerts Microservice Code (OpenTelemetry SDK) Cloud Profiler • CPU & Memory Heap Flame Graphs Microservice Code --[Emit Single-Line Structured JSON to stdout • severity: ]--> Cloud Run Built-in Agent Cloud Logging --[Auto-Extracts Unhandled Stack Traces]--> Error Reporting Microservice Code --[Continuous Statistical Sampling (<5% Overhead)]--> Cloud Profiler 3. AI-Assisted Observability (4.3e) Gemini Cloud Assist • Log Entry & Stack Trace Explanation • Natural-Language Log Analytics SQL Generation • Automated Incident Root-Cause Investigation Log & Trace & Mon

Consideration 4.3a: Instrumenting code to facilitate troubleshooting using metrics, logs, and traces in Google Cloud Observability

Instrumenting code to facilitate troubleshooting using metrics, logs, and traces in Google Cloud Observability
Google Cloud natively supports OpenTelemetry as the standard SDK for capturing distributed traces, custom application metrics, and logs across Python, Go, Java,...
  • Vendor-Neutral Instrumentation with OpenTelemetry (OTel): Google Cloud natively supports OpenTelemetry as the standard SDK for capturing distributed traces, custom application metrics, and logs across Python, Go, Java, Node.js, and .NET, exporting telemetry directly to Cloud Trace, Cloud Monitoring, and Cloud Logging (or via the Google Cloud Ops Agent / OpenTelemetry Collector on GKE and Compute Engine).
  • Structured JSON Logging Special Fields (Memorize These!):
  • When your application writes a single-line JSON object to stdout or stderr, the built-in logging agent on Cloud Run, GKE, and Cloud Functions automatically parses it into jsonPayload (instead of textPayload) and maps special keys to top-level LogEntry metadata:
  • severity: (DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY) — enables severity filtering and Error Reporting detection.
  • message: The primary human-readable log summary shown in Logs Explorer.
  • logging.googleapis.com/trace: Formatted as projects/PROJECT_ID/traces/TRACE_ID — links the log entry directly inside the Cloud Trace waterfall view!
  • logging.googleapis.com/spanId: Hex span ID linking the log to the exact child span.
  • httpRequest: Structured object (requestMethod, requestUrl, status, latency) enabling automatic HTTP latency sorting.
Structured JSON Logging Special Fields (Memorize These!) Architecture (4.3a)
Instrumenting code to facilitate troubleshooting using metrics, logs, and traces in Google Cloud Observability.
Key Implementation Patterns
  • Correlating Logs and Traces: Use Modify the application logging code to output JSON. Include the current trace ID in the "logging.googleapis.com/trace" field. Output logs as JSON and include the trace ID in the specific logging.googleapis.com/trace field to enable automatic correlation.
  • Custom Metrics Instrumentation: Use Use the Cloud Monitoring client library to create a custom metric. Instrument your code to write data to this metric. Custom metrics allow you to instrument application code to track specific business data like sales counts. (Avoid alternative: The Ops Agent collects infrastructure metrics (CPU, Memory), not application-specific business metrics.)
  • Structured Logging for Querying: Use Update the application code to output log entries as serialized JSON objects. Structured logging (JSON) allows Cloud Logging to parse fields automatically, enabling precise and efficient filtering. (Avoid alternative: Saved searches do not change the underlying data structure, leaving the filtering inefficient.)

Key Takeaways (4.3a)

  • Cloud Run captures stdout/stderr automatically, but JSON format (Structured Logging) unlocks advanced features.
  • To correlate logs with traces, you must inject the logging.googleapis.com/trace field into your JSON logs.
  • The trace field value must include the project ID: projects/[PROJECT_ID]/traces/[TRACE_ID].
  • Plain text logs cannot be automatically correlated with traces by the Cloud Console UI.

Consideration 4.3b: Identifying and resolving issues using Google Cloud Observability

Identifying and resolving issues using Google Cloud Observability — Choosing the Right Observability Tool for
Identifying and resolving issues using Google Cloud Observability.
  • Choosing the Right Observability Tool for the Symptom:
  • "Which microservice or database query in an end-to-end checkout request is causing high latency?" → Cloud Trace (waterfall latency graph across services).
  • "Why is my Go/Java/Python container on GKE consuming 95% CPU or leaking heap memory in production?" → Cloud Profiler (continuous low-overhead statistical profiling rendering flame graphs where bar width = percentage of total CPU time or memory allocated by that function call path).
  • "Is our public web frontend reachable from Europe, Asia, and North America right now?" → Cloud Monitoring Global Uptime Checks paired with an Alerting Policy.
  • Log Router Sinks & Log-Based Metrics:
  • Log-Based Metrics: Turn matching log entries (e.g., jsonPayload.payment_status="DECLINED") into a counter or distribution metric in Cloud Monitoring for dashboards and alerting.
  • Log Router Sinks: Route logs matching an inclusion filter to:
  • Cloud Storage (Archive / Coldline bucket with Locked Retention Policy): Lowest-cost long-term compliance archiving (e.g., 7-year HIPAA/PCI audit logs).
  • BigQuery: Rich SQL analytics and cross-table joins across millions of log events.
  • Cloud Pub/Sub: Real-time streaming to external SIEM tools (Splunk/Datadog) or automated security remediation functions.
Log Router Sinks & Log-Based Metrics Architecture (4.3b)
Identifying and resolving issues using Google Cloud Observability.
Key Implementation Patterns
  • Identifying Latency in Microservices: Use Use Cloud Trace to analyze the request latency and visualize the call chain across the microservices. Cloud Trace provides distributed tracing and waterfall views to pinpoint latency bottlenecks in microservices architectures. (Avoid alternative: Cloud Logging is used for analyzing text-based logs and errors, not for visualizing latency distribution across microservices.)
  • Debugging High CPU Costs: Use Install the Cloud Profiler agent in your application to collect CPU usage data. Cloud Profiler provides low-overhead, continuous profiling suitable for production to identify resource-intensive functions. (Avoid alternative: Logging every function call creates high performance overhead and produces data that is difficult to analyze for CPU profiling.)

Key Takeaways (4.3b)

  • Use Cloud Logging for analyzing specific error messages and event logs.
  • Use Cloud Monitoring for tracking system health and resource metrics like CPU and memory.
  • Use Cloud Trace for analyzing latency and visualizing request paths in distributed microservices.
  • Use Cloud Profiler for optimizing code-level resource consumption (CPU/Memory) within a service.

Consideration 4.3c: Managing application issues using Error Reporting

Managing application issues using Error Reporting — How Error Reporting Groups Exceptions
Error Reporting continuously scans log streams, parses stack traces by language framework, groups billions of identical crashes into deduplicated Error Issues,...
  • How Error Reporting Groups Exceptions: Error Reporting continuously scans log streams, parses stack traces by language framework, groups billions of identical crashes into deduplicated Error Issues, tracks first-seen/last-seen versions and occurrence counts, links directly to source code repositories, and sends alerts when a brand-new exception appears after a deployment.
  • Formatting Logs So Error Reporting Captures Them Automatically:
  • If a Node.js or Python app on GKE prints a multiline stack trace as plain text without formatting, GKE's container log driver splits every line into a separate log entry, and Error Reporting fails to recognize it!
  • To guarantee automatic ingestion into Error Reporting from stdout/stderr: emit a single-line structured JSON log with severity: "ERROR" (or higher) AND include the full formatted stack trace in stack_trace (or message / exception), or set "@type": "type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent" along with serviceContext: {"service": "...", "version": "..."}.
Formatting Logs So Error Reporting Captures Them Automatically Architecture (4.3c)
Managing application issues using Error Reporting.
Key Implementation Patterns
  • Formatting Logs for Error Reporting on Cloud Run: Use Change the log output to a JSON object with the stack trace in the message field. Structured JSON logging with a message field allows Error Reporting to parse stack traces automatically. (Avoid alternative: Cloud Run is a managed service that does not support installing agents manually.)
  • Configuring Error Notifications: Use Select 'Turn on notifications' in the Error Reporting list page. Error Reporting native notifications alert only on new error groups, not every occurrence. (Avoid alternative: Log-based alerts trigger on query matches (every error) rather than grouping them.)
  • Manual Error Reporting via Client Libraries: Use Use the Error Reporting client library to call report_exception within the except block. The client library allows manual reporting of handled exceptions without crashing the app. (Avoid alternative: Standard output is treated as INFO level logging, which Error Reporting ignores.)

Key Takeaways (4.3c)

  • Cloud Run captures stdout and stderr automatically.
  • Plain text logs may not be correctly parsed by Error Reporting.
  • Structured Logging (JSON) is preferred over plain text for programmatic analysis.
  • To trigger Error Reporting via logs, the JSON object must contain the stack trace in the message field.

Consideration 4.3d: Using trace IDs to correlate trace spans across services

Using trace IDs to correlate trace spans across services — Why Distributed Traces Break Across Microservice Ho
Cloud Load Balancing and Cloud Run automatically generate a root trace header on incoming requests, but they do not magically copy that header into your...
  • Why Distributed Traces Break Across Microservice Hops: Cloud Load Balancing and Cloud Run automatically generate a root trace header on incoming requests, but they do not magically copy that header into your application's outbound http.get() or fetch() calls!
  • Propagating Trace Context Headers:
  • Your application code (or OpenTelemetry HTTP/gRPC auto-instrumentation interceptor) must extract the incoming trace header—either the W3C standard traceparent (00-<trace-id>-<span-id>-<flags>) or Google's X-Cloud-Trace-Context (TRACE_ID/SPAN_ID;o=TRACE_TRUE)—and inject it into the HTTP headers of every outbound request to downstream services.
  • For asynchronous Pub/Sub hops, pass the traceparent context inside Pub/Sub message attributes so the subscriber can link its processing span back to the publisher's parent trace!
  • Adding Custom Child Spans for Internal Bottlenecks: By default, auto-instrumentation only creates spans for incoming/outgoing HTTP/gRPC requests. If a single microservice takes 3 seconds internally (e.g., running an image resize, regex parse, or local cache serialization) and shows up as one giant opaque block in Cloud Trace, use the OpenTelemetry / Cloud Trace SDK (tracer.start_as_current_span("resize_image")) to wrap internal functions in custom child spans.
Propagating Trace Context Headers Architecture (4.3d)
Using trace IDs to correlate trace spans across services.
Key Implementation Patterns
  • Correlating Logs and Traces in Structured Logging: Use Add a logging.googleapis.com/trace field to the JSON log object with the value projects/[PROJECT_ID]/traces/[TRACE_ID]. Structured logs must include the logging.googleapis.com/trace field with the full trace resource path to correlate with Cloud Trace.
  • Standardizing Header Formats (W3C vs. B3): Use Configure the OpenTelemetry services to use a composite propagator that supports both W3C Trace Context and B3 headers. Configuring propagators to accept both header formats ensures the new system can understand trace context sent by the legacy system.
  • Propagating Context via Pub/Sub Attributes: Use Modify Service A to inject the trace context into the Pub/Sub message attributes. Modify Service B to extract this context and use it to start the span. You must manually propagate the trace context via message attributes to link traces across Pub/Sub boundaries.

Key Takeaways (4.3d)

  • Cloud Run automatically captures stdout as logs; JSON format allows for structured logging.
  • Correlation between Cloud Logging and Cloud Trace is not automatic for application logs; it requires explicit linking.
  • Use the special JSON field logging.googleapis.com/trace to provide the link.
  • The trace field value must use the full resource name format: projects/[PROJECT_ID]/traces/[TRACE_ID].

Consideration 4.3e: Using Gemini Cloud Assist

Using Gemini Cloud Assist — Accelerating Incident Triage with Gemini Cloud Assist
Integrated directly into Logs Explorer, Cloud Monitoring, Cloud Trace, and Error Reporting, Gemini Cloud Assist provides four core developer capabilities:.
  • Accelerating Incident Triage with Gemini Cloud Assist: Integrated directly into Logs Explorer, Cloud Monitoring, Cloud Trace, and Error Reporting, Gemini Cloud Assist provides four core developer capabilities:
  • Log Entry & Stack Trace Summarization: Click "Explain this log entry" on a cryptic GKE, Cloud Run, or IAM audit log to get an immediate plain-English explanation of the root cause and exact remediation steps.
  • Natural-Language Query Generation: Translate plain-English questions ("Show me all 5xx errors on the checkout service in the last 2 hours grouped by user region") into valid Logging query language, Log Analytics SQL, or PromQL.
  • Cloud Assist Investigations (Root-Cause Correlation): Automatically correlates spikes in Cloud Monitoring error/latency metrics with recent Cloud Run revision / GKE deployment rollouts, Cloud Trace bottleneck spans, and Cloud Logging anomalies to pinpoint what changed when an incident started.
operations:logging, gemini, gke:workloads Architecture Architecture (4.3e)
Production architecture and service trade-offs for using gemini cloud assist across operations:logging, gemini, gke:workloads.
Key Implementation Patterns
  • Log Entry Explanation: Use Select the log entry in the Logs Explorer and click "Explain this log entry" to generate an analysis. Gemini Cloud Assist provides an in-context 'Explain this log entry' feature to summarize errors and suggest fixes. (Avoid alternative: Searching external forums requires leaving the console and is less efficient than integrated tools.)
  • Troubleshooting GKE Workloads: Use Use the Gemini Cloud Assist feature in the console to analyze the workload and explain the error. Gemini Cloud Assist provides AI-driven analysis and summarization of errors directly in the console. (Avoid alternative: Manual log inspection via CLI contradicts the requirement to avoid parsing raw logs.)
  • Natural Language to Log Queries: Use Enter your request in natural language in the Gemini assistance pane within Logs Explorer to generate the query. Gemini in Logs Explorer translates natural language descriptions into valid Logging Query Language (LQL) syntax. (Avoid alternative: Error Reporting focuses on application crashes with stack traces, not necessarily standard HTTP 404 logs.)

Key Takeaways (4.3e)

  • Gemini Cloud Assist is integrated into Logs Explorer to help interpret complex errors.
  • The 'Explain this log entry' feature provides summaries and actionable fixes without leaving the console.
  • Using integrated AI tools reduces context switching and accelerates troubleshooting compared to manual external searches.
  • CrashLoopBackOff indicates a Pod is repeatedly failing to start.

Quick Decision Cheat Sheet (Subsection 4.3)

If the Scenario Requires...
Choose This Google Cloud Pattern
Avoid This Common Mistake
"Filter Cloud Run logs in Logs Explorer by custom fields like order_id and customer_tier"
Write single-line structured JSON to stdout (parsed automatically into jsonPayload.order_id)
Writing unstructured plain text (textPayload) and running slow regex searches
"Waterfall graph in Cloud Trace shows 4 sequential 300ms database queries taking 1200ms total"
Refactor application code to execute the independent queries concurrently (Promise.all / asyncio.gather / goroutines) or via a single batch/JOIN query
Adding more GKE nodes or increasing Cloud Run CPU (does not fix sequential network round-trip waits!)
"See fine-grained timing of 3 internal helper functions inside a single microservice span in Cloud Trace"
Instrument the internal functions with custom child spans using the OpenTelemetry / Cloud Trace SDK
Adding time.sleep() or relying only on load-balancer HTTP logs
"Alert the on-call team immediately whenever a public web application stops responding from external regions"
Configure a Cloud Monitoring Global Uptime Check + Alerting Policy
Checking only container CPU utilization (a deadlocked server can sit at 1% CPU while returning 502s!)
"Quickly diagnose a complex multi-service incident and generate Log Analytics SQL queries using natural language"
Use Gemini Cloud Assist in Google Cloud Observability
Manually exporting gigabytes of logs to CSV for local spreadsheet inspection

Further Reading (Subsection 4.3)

  • Correlate log entries — This guide explains exactly how to create JSON-formatted logs with the correct trace field to enable correlation in Cloud Run.
  • Structured logging — Provides an overview of how special fields in JSON payloads are interpreted by Cloud Logging.
  • User-defined metrics overview — Provides the official definition of user-defined (custom) metrics, explaining that they are metrics you define and write time-series data for using the API.
  • Creating custom metrics — A guide on how to programmatically create and write data to custom metrics using client libraries.
  • Cloud Trace overview — Explains how Cloud Trace collects latency data from applications and displays it in the Google Cloud console, helping to find performance bottlenecks.
  • Microservices Observability — A blog post detailing how distributed tracing is essential for identifying latency issues in microservices architectures.

Book TOC · Previous · Chapter 6 of 7 · Next

AwesomeGCP.com Learning

The approach taken is a question-led learning approach: you explore realistic project scenarios where you need to make decisions or take actions to achieve business goals within specific constraints. Instead of passive learning, you are challenged to think and work through the options to master the Professional Cloud Developer (PCD) certification!

Practice PCD Questions