Production Observability & SRE · Lesson 1

Observability for Backend Systems Explained

Learn how logs, metrics, traces, and events work together to diagnose backend failures, protect telemetry quality, and verify recovery.

Quick answer

Observability is the ability to explain a system’s internal behavior from the evidence it emits. Monitoring asks known questions such as “is checkout latency above the SLO?” Observability also supports investigation when the exact failure was not predicted in advance. Telemetry is the raw evidence—logs, metrics, traces, profiles, and events—not the outcome itself. A service can emit terabytes of telemetry and remain difficult to understand if identity, semantics, or ownership are inconsistent.

A useful design starts with decisions. Define the user journey, its service level objective (SLO), the components that can break it, and the evidence needed to distinguish those failures. Metrics reveal scope and direction. Traces connect work across service boundaries. Structured logs preserve detailed facts about selected events. Deployment and configuration events explain changes. None is a universal replacement for the others.

Use a stable evidence contract across the system: service.name, deployment.environment.name, trace_id, span_id, request_id, and message_id. Keep metric dimensions such as route, status, and operation low-cardinality. Do not use user IDs, order IDs, raw URLs, exception messages, or trace IDs as metric labels. Put high-cardinality identity in appropriately protected logs or traces where retention, access, and sampling are explicit.

Learning objectives

  • Separate monitoring, telemetry, observability, business evidence, and verified recovery in one Spring order service journey.
  • Map user impact to trustworthy metrics, traces, logs, profiles, and change evidence without treating any single signal as complete truth.

Prerequisites

Know HTTP request flows, Spring services, basic metrics and logs, and the production boundaries introduced in Production Spring Boot Backend Systems.

Production failure scenario

The shared incident begins when a slow query in the inventory service exhausts its database connection pool.

The cluster follows one incident. A deployment changes an inventory query. The query becomes slow for a subset of products and holds database connections longer. The inventory service connection pool saturates. The order API waits, times out, and retries. Retries amplify traffic. An asynchronous reservation consumer also slows, so the queue backlog grows. Most requests still succeed, but end-to-end latency burns the checkout SLO and notifications arrive late.

This sequence is intentionally ambiguous at first. An alert shows fast error-budget consumption, not “the inventory query is wrong.” A rate dashboard may show stable traffic and rising duration. Resource metrics show pool utilization and saturation. A trace shows time concentrated in the inventory database span. A structured log supplies the normalized query operation and pool wait duration. A deployment event narrows the change window. The operator mitigates by rolling back the query change, then verifies that latency, pool wait, retry volume, queue age, and SLO burn rate recover.

The shared fields make correlation possible. The order API creates or accepts a trace_id and assigns a request_id for the request. When it publishes reservation work, it records a stable message_id and propagates trace context according to the messaging instrumentation contract. Each component identifies itself with service.name and deployment.environment.name. A span has a span_id; logs written during that span include both trace and span identity. These identifiers are evidence links, not authorization credentials.

An evidence map records the question each signal can answer:

QuestionPrimary evidenceSupporting evidence
Are users affected?SLI and SLO metricssynthetic checks
Which routes and services changed?RED metricsdeployment events
Which dependency owns the delay?distributed traceresource metrics
What happened in one execution?structured logtrace attributes
Is the system recovering?burn rate and queue agefresh traces and logs

Evidence and system boundary

OpenTelemetry defines vendor-neutral APIs, SDK concepts, semantic conventions, context propagation, and the OTLP protocol. The OpenTelemetry Collector is a programmable telemetry pipeline. It does not define a universal storage or query product. Prometheus defines a metrics data model and query language, while Grafana, Loki, Tempo, and commercial services are replaceable visualization or storage choices. Keeping those boundaries explicit prevents a deployment choice from becoming a fake standard.

Semantic conventions improve correlation by giving common meaning to attributes, span names, instruments, and resources. Check the stability level of a convention before treating it as an organization-wide interface. Stable identifiers such as service.name can be governed centrally. Experimental database or messaging attributes may require a migration plan when their names change. Record the OpenTelemetry semantic-convention version tested by instrumentation and dashboards.

W3C Trace Context defines traceparent and tracestate for interoperable HTTP propagation. It does not make incoming context trustworthy. Validate syntax, define trust boundaries, and avoid placing personal data in tracestate or baggage. Baggage is propagated application context; it is not automatically a span attribute and has no built-in integrity guarantee.

Telemetry has a measurement boundary. A counter reports recorded events, not events that instrumentation missed. A sampled trace set is not a complete or unbiased history unless the sampling design and analysis justify that claim. A log pipeline can drop data during overload. Collector queues and retries reduce transient loss; they do not guarantee no telemetry loss across process crashes, exhausted storage, invalid data, or backend rejection.

Minimal implementation

Start with an instrumentation contract rather than a dashboard inventory:

resource:
  service.name: inventory-service
  deployment.environment.name: production
request_fields:
  - request_id
  - trace_id
  - span_id
message_fields:
  - message_id
metric_dimensions:
  - route
  - status
  - operation
forbidden_metric_dimensions:
  - user_id
  - order_id
  - raw_url
  - exception_message
  - trace_id

For the order path, define a small set of decision-oriented metrics: request count, error count, latency histogram, active requests, pool utilization, pool wait duration, retry attempts, queue depth, and oldest-message age. Add deployment events with version and environment. Instrument HTTP, database, and messaging boundaries with spans. Emit structured logs only where they add facts that cannot be represented safely and economically in metrics or span attributes.

Build one investigation view around the user journey. Start with successful checkout ratio and latency. Link to service RED metrics, inventory pool signals, queue age, and recent deploys. If the backend supports exemplars, connect a latency histogram observation to a representative trace without storing every trace ID as a metric label. From the trace, pivot to correlated logs using indexed trace_id according to the log backend’s cost model.

Ownership is part of the implementation. Each SLI, alert, dashboard, instrumentation library, Collector pipeline, and storage destination needs an owner. Record expected freshness and retention. A dashboard that silently stops receiving data must be distinguishable from a healthy service with zero traffic, for example through scrape health, Collector export failure metrics, and synthetic requests.

This evidence design helps answer known questions, but observability also matters for unknown unknowns: failure modes the team did not predict or encode in a dedicated dashboard. High-dimensional traces and structured events can expose an unexpected interaction, yet they remain incomplete when sampling, redaction, or pipeline loss removes evidence. Treat a novel correlation as a hypothesis to test against independent user-impact and resource signals, not as certainty created by a flexible query tool.

Design the telemetry path as a chain of custody. The application creates an observation, an SDK or agent transforms it, a Collector receives and processes it, an exporter transfers it, and a backend stores and indexes it. At every boundary, document what can be filtered, sampled, rejected, delayed, or renamed. This makes “the dashboard has no errors” a testable statement rather than an assumption. If the application counter rises but the backend series does not, the investigation can compare each handoff instead of increasing logging blindly.

Use change evidence as a first-class signal. Deployments, feature-flag changes, schema migrations, autoscaling events, and Collector configuration updates should have timestamps, environment, version, owner, and outcome. They need not be high-cardinality metric labels; annotations or structured events are usually safer. Correlation with a change narrows the hypothesis space, but temporal proximity is not proof of causation. Compare unaffected versions, routes, or regions before committing to rollback.

Finally, define observability quality objectives. Examples include maximum telemetry delay, minimum successful scrape ratio, maximum Collector queue utilization, and the percentage of services using the approved resource attributes. These are not substitutes for product SLOs. They describe whether operators can trust the evidence needed to defend those SLOs. A platform team can improve these objectives without claiming that application reliability improved automatically.

Failure modes and trade-offs

The first failure mode is signal duplication without semantics. Three teams may emit request duration in milliseconds, seconds, and mixed units under similar names. A dashboard can combine them and display a convincing lie. Use base units, explicit descriptions, and reviewed semantic conventions.

The second is cardinality explosion. A metric label for order_id creates a series per order; raw URL paths can create one per resource. The cost appears in memory, storage, query latency, and delayed alerts. Use route templates such as /orders/{id} and stable status classes. Preserve individual identity in protected logs and traces.

The third is retry amplification inside telemetry itself. An overloaded Collector retries an unavailable backend while applications keep sending. Memory rises, queues fill, and telemetry may be dropped. Bound queues, use backoff, monitor refusal and drop counters, and prioritize signals needed for incident response.

The fourth is treating absence as success. Missing error logs can mean the log exporter failed. A missing time series can mean instrumentation was never initialized. Use freshness, export success, and expected-traffic checks. Prefer an explicit zero for known metric series where appropriate, while recognizing that dynamic dimensions may not exist before the first event.

The fifth is alerting on implementation noise. CPU at 80 percent can be healthy; a low CPU system can still violate checkout latency. Page on user-impacting symptoms and rapid SLO burn, then use component metrics for diagnosis. Capacity and trend alerts can create tickets rather than waking an operator.

Common misconceptions

  • Telemetry volume is not the same as observability.
  • A green dashboard can coexist with delayed or missing evidence.
  • Sampling does not preserve a complete request population.
  • A cleared alert or successful rollback command does not prove user or durable-order recovery.

Security, privacy, and cost

Telemetry often contains more sensitive context than application teams expect. URLs may contain tokens. SQL statements may contain values. Headers can contain credentials. Exception messages may include personal data. Apply allowlists, redaction, and length limits before export. Protect telemetry stores with least privilege, encryption, retention limits, and audited access. Do not copy secrets into resource attributes, baggage, span events, or Collector configuration committed to source control.

Correlation identifiers should be random, bounded, and treated as untrusted input when received. They are useful lookup keys, not proof of identity. Prevent log injection by using structured encoders rather than concatenated text. Separate operational logs from audit and security records: those records may require immutability, stricter access, different retention, and evidence of who queried them.

Control cost at collection time. Keep metrics aggregated and low-cardinality. Sample traces deliberately while retaining error and high-latency evidence through well-governed policies. Reduce repetitive debug logs and avoid indexing every field. Use telemetry budgets per service and environment, but never optimize by deleting the only signal that proves the user-facing SLI.

Testing and validation

Test instrumentation like any public interface. A contract test can start a request, propagate it to a fake downstream service, publish a fake message, and assert that required resource and correlation fields exist. It should reject forbidden metric labels. Validate units and histogram boundaries. Test malformed or external trace context and verify that trust policy is enforced.

For metrics, generate known traffic and compare counters, errors, and latency observations with the workload. Confirm that the no-traffic case is distinguishable from a failed scrape. For traces, verify parent-child relationships across HTTP and messaging. For logs, send secret-shaped fixtures and confirm redaction before data leaves the process or Collector.

Run failure drills. Make the backend unavailable and observe Collector queue growth, retries, refusal, and eventual dropping. Saturate the inventory pool and verify that the SLO alert fires before a resource-only alert becomes the primary signal. Roll back the query change and confirm recovery across user SLI, RED metrics, pool wait, queue age, traces, and logs.

Review the evidence map after every drill. Remove panels that never influenced a decision, repair pivots that were slow or permission-blocked, and add only the missing evidence that changed diagnosis. This keeps the system understandable as services and ownership evolve.

A mature review also asks whether each signal shortens a decision. Evidence that is never queried, cannot be trusted, or has no owner should be repaired or retired.

Use that evidence to choose controls through Production Resilience for Backend Systems, then rehearse saturation diagnosis, mitigation, and exit criteria with Production Overload Troubleshooting.

Decision checklist

  • Define the user journey and SLO before choosing dashboards.
  • Assign an owner to every alert and telemetry pipeline.
  • Use stable resource identity and correlation fields consistently.
  • Keep metric dimensions bounded and low-cardinality.
  • Treat traces and logs as sampled or lossy evidence unless proven otherwise.
  • Redact credentials and personal data before export.
  • Monitor the Collector and storage pipeline as production dependencies.
  • Link alerts to a runbook and evidence map.
  • Verify recovery with user-impact and component signals.
  • Review conventions, costs, retention, and access at regular intervals.

Official sources

Official sources accessed August 19, 2026. OpenTelemetry convention stability can change; verify the current stable tables before adopting an attribute as a long-lived contract.

For a Spring order service, Spring Boot Actuator, Health, and Metrics Explained turns this evidence map into minimally exposed probes and bounded Micrometer dimensions. When customer impact is active, Production Spring Boot Incident Troubleshooting uses the same signal boundaries to choose reversible mitigation and verify user, correctness, and resource recovery.

This is the first lesson in Production Observability & SRE; continue through the Observability and SRE topic and Telemetry Quality, Semantic Conventions, and Cardinality.

Continue with Structured Logging and Correlation IDs, then use RED, USE, and Golden Signals to turn the evidence map into operational metrics. The full sequence is available in System Design and Topics.

For database-bound journeys, Database Query Performance for Backend Systems separates request, pool, session, statement, wait, and retry clocks; Production Slow Query Troubleshooting applies those signals without treating sampled traces or one query plan as the complete workload.

Knowledge check

Check your understanding

Answer both questions correctly to mark this lesson as mastered. You can retry without penalty.

1. Checkout latency burns its SLO while errors remain low; which investigation uses the telemetry signals according to their evidence boundaries?

2. A dashboard shows no new inventory errors, but Collector export failures are rising; what can the operator conclude?