Metrics vs Logs vs Traces¶
1. Decision¶
Implement the Three Pillars of Observability (Metrics, Logs, Traces) using OpenTelemetry as the unified telemetry collection standard: use Metrics for real-time aggregation, monitoring, and automated alerting; use Structured Logs for detailed contextual root-cause debugging; use Distributed Tracing to visualize end-to-end request latency across microservice call graphs.
2. 30-Second Answer¶
Modern cloud-native observability requires combining three complementary data types:
1. Metrics (Numeric Aggregations): Numerical values aggregated over time intervals (e.g. CPU %, HTTP QPS, p99 Latency). They are lightweight, cheap to store, highly queryable (Prometheus / Datadog), and ideal for automated alerting and real-time SLA dashboards.
2. Logs (Contextual Events): Structured JSON text records of discrete events (e.g. PaymentFailed, exception stack traces). They provide full, rich contextual details required to debug specific root causes, but consume heavy storage (Elasticsearch / Loki).
3. Traces (Request Lifecycles): Directed Acyclic Graphs (DAGs) of spans representing the path of a single HTTP/gRPC request as it traverses across microservice boundaries (Jaeger / Tempo). Traces pinpoint exact bottleneck hops causing end-to-end latency spikes.
3. Decision Matrix¶
| Option | Best For | Avoid When | Data Volume / Cost | Query Speed | Primary Use Case | Operational Tooling |
|---|---|---|---|---|---|---|
| Metrics (Numeric) | Real-time monitoring dashboards, automated alerting (Prometheus / Grafana), SLO/SLA tracking, trend analysis | Debugging specific individual user errors, inspecting full stack traces | Very Low (Compact time-series numerical data) | Ultra-Fast (<10ms Prometheus TSDB range query) | Detect THAT a problem is happening (Alerting) | Prometheus, VictoriaMetrics, Datadog |
| Logs (Event Records) | Root-cause analysis, investigating specific error stack traces, audit trails, detailed event history | Real-time global metric alerting (parsing terabytes of logs for alerts is slow and expensive) | High (Terabytes of structured JSON data) | Medium to Slow (Lucene index search e.g. Elasticsearch / Loki) | Understand WHY a problem happened (Debugging) | OpenSearch, Loki, Elasticsearch |
| Traces (Spans) | Pinpointing latency bottlenecks across multi-service call chains (A \(\rightarrow\) B \(\rightarrow\) C), microservice dependency graphs | Isolated single-monolith debugging | Medium to High (Depends on Sampling Rate e.g. 5-10%) | Fast (Span ID lookup in Jaeger / Tempo) | Identify WHERE in the system a problem happened (Localization) | OpenTelemetry, Jaeger, Grafana Tempo |
4. Selection Rules¶
| Requirement | Best Choice | Rationale / Example |
|---|---|---|
| Automated PagerDuty Alerting on Service Degradation | Metrics (Prometheus) | Alert if sum(rate(http_requests_total{status=~"5.."}[5m])) > 10 |
| Investigate Specific User Payment Failure Stack Trace | Structured Logs (Loki/ES) | Query user_id="usr_123" AND event="PaymentFailed" to read full exception |
| Identify Which Microservice Is Causing 3s Latency Spikes | Distributed Traces (Tempo) | Trace waterfall graph highlights 2,800ms bottleneck in Inventory-Service span |
| Unified Vendor-Neutral Telemetry SDK Instrumenting Code | OpenTelemetry (OTel) | Single OTel SDK exports Metrics, Logs, and Traces to any backend destination |
5. Tradeoffs¶
- Numeric Storage Efficiency (Metrics) vs Contextual Detail (Logs)
- Gain (Metrics): Tiny storage footprint; retain 1 year of QPS metrics for pennies.
- Lose (Metrics): Zero contextual detail (cannot tell which user ID failed).
- End-to-End Latency Visibility (Traces) vs Network & Storage Overhead
- Gain (Traces): Visualizes request propagation paths across 50 microservices automatically.
- Lose (Traces): 100% tracing ingestion consumes massive network bandwidth and disk space (requires Sampling).
- Structured JSON Logs vs Storage Inflation
- Gain (Logs): Searchable key-value attributes (
tenant_id,db_latency_ms) enable precise querying. - Lose (Logs): Ingesting terabytes of un-sampled JSON logs per day incurs massive Datadog/Elasticsearch bills.
- OpenTelemetry Standardization vs Proprietary Agent Simplicity
- Gain (OTel): 100% vendor-agnostic; switch from Datadog to Grafana Tempo without changing app code.
- Lose (OTel): Configuring OTel Collector pipelines and exporters requires initial DevOps setup.
- Trace Context Propagation Overhead
- Gain: Links logs, metrics, and traces together using a unified
trace_id. - Lose: App code and HTTP/gRPC clients MUST pass
traceparentheaders down the network call tree.
6. Interview Counter Questions¶
- What are the "Three Pillars of Observability" and how do they work together to resolve an incident?
- How does
trace_idcorrelation link Logs, Metrics, and Traces together in Grafana? - What is OpenTelemetry (OTel) and why has it become the industry standard over proprietary vendor SDKs?
- What is the difference between Tail-Based Sampling and Head-Based Sampling in Distributed Tracing?
- Why are Metrics better than Logs for real-time alerting?
- How does Prometheus store time-series metrics efficiently (TSDB chunk compression)?
- What is the RED Method (Rate, Errors, Duration) vs USE Method (Utilization, Saturation, Errors)?
- How do you control logging costs in high-volume microservice environments?
- What is the OTel Collector and what are its 3 pipeline components (Receivers, Processors, Exporters)?
- How does eBPF-based auto-instrumentation (Cilium Hubble / Pixie) complement manual OpenTelemetry code instrumentation?
7. Gold Standard Answers¶
- Metrics detect THAT a problem exists (Alert fires: p99 latency \(>2\text{s}\)). Traces localize WHERE the bottleneck is (
Payment-ServiceRPC hop). Logs explain WHY it failed (PostgreSQL connection pool exhausted). - Embed the current
trace_idinside structured JSON log outputs ({"trace_id": "abc123", "msg": "failed"}). In Grafana, clicking a metric spike opens the Trace graph, and clicking a trace span filters Logs matching thattrace_id. - OpenTelemetry (CNCF standard) provides vendor-neutral APIs, SDKs, and Collector pipelines. It allows developers to instrument code once and export telemetry to any backend (Prometheus, Jaeger, Datadog, New Relic).
- Head-Based: Decides to sample a trace at request start (e.g. random 5% sample). Misses rare 500 errors! Tail-Based: Buffers 100% of spans in memory; samples and persists 100% of traces containing errors or high latency.
- Metrics are pre-aggregated numbers (tiny storage footprint). Querying 100,000 requests/sec via Prometheus takes \(<10\text{ms}\). Searching terabytes of text logs to calculate error rates takes minutes and thrashes disk I/O.
- Prometheus TSDB uses Gorilla compression (XOR delta-of-delta timestamp and value compression), packing time-series metrics into ~1.37 bytes per sample in memory/disk.
- RED Method (Request-focused): Rate (QPS), Errors (5xx rate), Duration (Latency SLAs). USE Method (Resource-focused): Utilization (% busy), Saturation (Queue depth), Errors (Device errors).
- Implement: (1) Log Level tuning (WARN/ERROR in prod; DEBUG off), (2) Dynamic Sampling, (3) Filtering verbose health checks at OTel Collector, (4) Indexing only critical keys in Grafana Loki.
- Receivers: Ingest data (OTLP, Prometheus format). Processors: Batch, filter, memory-limit, or sample telemetry. Exporters: Send telemetry to backends (Jaeger, Prometheus, Datadog).
- eBPF automatically intercepts network calls and HTTP requests at the Linux kernel layer with ZERO code modification or SDKs. OTel provides deep in-code business context (user IDs, domain attributes).
8. Common Mistakes¶
- Using raw un-sampled logs to calculate high-velocity QPS metrics, causing massive log ingestion bills.
- Instrumenting code using proprietary vendor SDKs (Datadog/NewRelic SDKs), causing permanent vendor lock-in.
- Collecting 100% Head-Based trace samples in high-traffic applications, blowing out network bandwidth and storage costs.
- Outputting un-structured plain-text log strings instead of structured JSON logs (
{"level": "ERROR", "msg": ...}). - Failing to correlate logs with traces by omitting
trace_idfields in application logging configurations.
9. Keywords¶
Observability, Three Pillars, Metrics, Logs, Traces, OpenTelemetry (OTel), OTLP, OTel Collector, Jaeger, Prometheus, Grafana Tempo, Loki, Trace ID, Spans, Head-Based Sampling, Tail-Based Sampling, RED Method, USE Method, TSDB, eBPF.
10. Cheat Sheet¶
- Three Pillars Roles:
- Metrics \(\rightarrow\) Detect THAT a problem exists (Prometheus Alerting).
- Traces \(\rightarrow\) Identify WHERE in the call chain the bottleneck lives (Jaeger/Tempo).
- Logs \(\rightarrow\) Explain WHY the error happened (OpenSearch/Loki JSON stack traces).
- Correlation: Always inject
trace_idinto structured JSON logs to link Traces directly to Logs in Grafana. - Instrumentation Standard: Use OpenTelemetry (OTel) for vendor-agnostic code instrumentation and telemetry pipelines.
- Tracing Sampling: Use Tail-Based Sampling in OTel Collector to capture 100% of error/high-latency traces while dropping 95% of normal traces.
- Monitoring Frameworks: Use RED Method (Rate, Errors, Duration) for APIs; use USE Method (Utilization, Saturation, Errors) for Infrastructure.
- Cost Control: Store Metrics for long-term trends; sample Logs and Traces to control cloud storage bills.