- One telemetry pipeline for traces, metrics and logs instead of tool-by-tool agents
- SLOs defined for key customer journeys and reviewed with product owners
- Pages driven by error-budget burn rather than resource thresholds
- Incidents traced across service boundaries from a single trace view
Anonymised composite. Client names, identifying details and confidential figures are withheld; public facts are cited in the references.
The situation
A telecom operator ran customer-facing digital services (self-care apps, online ordering, payments and activation) on top of a mix of modern microservices and long-lived back-office systems. Monitoring had grown team by team. Each group had its own agents, dashboards and alert rules, and the same incident lit up several tools at once without any of them saying whether customers were affected.
The pattern on bad days was familiar: complaints arrived through support channels first, several teams investigated in parallel from their own dashboards, and the root cause sat at a boundary nobody's tool covered.
What had to be true
- One vendor-neutral telemetry pipeline, so instrumentation is done once and backends can change.
- Traces across boundaries, from the app request through the API layer to the back-office call.
- Objectives tied to customer journeys, agreed with the people who own those journeys.
- Alerts that mean action: page when users are being hurt, ticket when a budget is slowly eroding, and nothing else.
- Cost under control, with sampling and cardinality managed centrally rather than service by service.
Architecture
The core was an OpenTelemetry Collector gateway: services and node-level agents send OTLP to a central endpoint per cluster or region, where processing, sampling and export happen once1. Deployment patterns are compared in OpenTelemetry Collector deployment patterns.
For older services that could not be changed quickly, OpenTelemetry eBPF Instrumentation (OBI) captured spans and rate, error and duration metrics for HTTP and gRPC traffic without code changes2. It cannot see business context, so revenue-critical services also received SDK instrumentation for custom attributes. More in OpenTelemetry eBPF instrumentation.
The data flow, end to end
- InstrumentSDKs on new services, OBI on legacy ones, consistent resource attributes everywhere
- CollectNode agents add host and Kubernetes metadata and forward OTLP
- ProcessGateway filters noise, drops high-cardinality labels and applies sampling policy
- StoreMetrics to Prometheus, traces and logs to their backends, linked by trace ID
- EvaluateRecording rules compute SLIs and burn rates per journey
- RespondFast burn pages on-call; slow burn opens a ticket for the owning team
Prometheus held the SLI time series and evaluated recording and alerting rules, which suits numeric operational data well, though not anything that needs exact per-request accounting3.
The hard part: deciding what to promise
The pipeline was engineering. The objectives were negotiation. Each journey (sign in, view bill, pay, activate) needed an indicator measured close to the user, a target the business could defend, and an owner who accepted the consequences of the error budget5. In practice that meant:
- Choosing indicators at the edge of the journey, not on internal components that customers never see.
- Starting with targets the service already met most of the time, then tightening, rather than declaring aspirational numbers nobody could hold.
- Writing a short error budget policy per journey that said what happens when the budget runs low.
- Retiring old component alerts deliberately, with each team agreeing what replaced them.
Alerting followed the multiwindow, multi-burn-rate approach in the Google SRE Workbook, which pairs a long window for significance with a short window for fast reset4. The practical version for smaller teams is in SLOs and error budgets for small teams.
An SLO is a business decision expressed in numbers. If product owners have not agreed it, it is just another threshold.
How the engagement ran
- Run collectors and gateway
- Own sampling and cost policy
- Publish instrumentation defaults
- Adopt SDK or OBI
- Define SLIs with platform
- Own pages for their journeys
- Agree targets
- Approve error budget policy
- Review budget each cycle
- Tool and alert inventory
- Recent incident review
- Journey map
- Gateway and agents
- One journey traced end to end
- Attribute conventions
- SLIs and targets
- Burn-rate alerts
- Retire legacy alerts
- Remaining journeys
- On-call runbooks
- Budget reviews in planning
Key decisions and trade-offs
| Decision | Alternative | Why |
|---|---|---|
| OpenTelemetry and OTLP | Vendor agents per tool | Instrument once; backends become replaceable |
| Collector gateway | Services export directly | Central sampling, filtering and credentials |
| OBI for legacy services | Wait for code changes | Baseline traces now; SDKs where context matters |
| Journey-level SLOs | Per-component thresholds | Alerts reflect customer impact, not resource noise |
| Multiwindow burn-rate alerts | Static error-rate alerts | Better precision and faster reset |
What I'd do again, and differently
Again: trace one journey end to end before instrumenting everything, and make product owners co-own the targets. Differently: set attribute naming and cardinality rules before the first service onboards. Cleaning up inconsistent labels later cost more than agreeing them early.
If you're planning something similar, the fractional CTO page describes how I lead platform and reliability work, or analyse your challenge and bring the result to a call.
- 1Gateway deployment patternOpenTelemetry
- 2OpenTelemetry eBPF InstrumentationOpenTelemetry
- 3Prometheus overviewPrometheus
- 4
- 5