Observability Rules (OpenTelemetry)
1. Core Concepts
OpenTelemetry provides a unified standard for collecting telemetry data.
Three Pillars + Context
| Signal |
Purpose |
Role in Debugging |
| Traces |
Request flow across services |
Where it went wrong (which service/span) |
| Metrics |
Aggregated measurements over time |
Something is wrong (alert trigger) |
| Logs |
Discrete event records |
What went wrong (error details) |
| Context |
Correlates all signals via trace ID, span ID |
Connect all three for correlated debugging |
Architecture
[Application + OTel SDK]
|-- API (instrumentation interface)
|-- SDK (implementation: sampling, batching, export)
|-- Auto-instrumentation (zero-code)
|
[OTel Collector] (optional but recommended)
|-- Receivers → Processors → Exporters
|
[Backends: Jaeger, Tempo, Prometheus, Loki]
OTLP Protocol
| Transport |
Port |
Use Case |
| gRPC |
4317 |
Default, binary protobuf |
| HTTP |
4318 |
Firewalls, load balancers |
Endpoints: /v1/traces, /v1/metrics, /v1/logs
2. Distributed Tracing
Span Structure
A span represents a unit of work with:
- Span Context: trace ID, span ID, trace flags (immutable)
- Attributes: key-value metadata (
http.request.method, db.system)
- Events: timestamped annotations within the span
- Links: causal relationships to other spans (async flows)
- Status: Unset (default), Error, Ok
SpanKind
| Kind |
Direction |
Example |
| Client |
Outbound sync |
HTTP client, DB client |
| Server |
Inbound sync |
HTTP server handler |
| Internal |
In-process |
Business logic |
| Producer |
Outbound async |
Queue publish |
| Consumer |
Inbound async |
Queue consume |
W3C Trace Context Propagation
traceparent: 00-<trace-id>-<span-id>-<trace-flags>
tracestate: vendor-specific data
- Default propagator in OTel
- Inject on outgoing requests, extract on incoming
- Never propagate internal trace data to untrusted external services
- Never put sensitive data in Baggage
Instrumentation Approaches
| Approach |
Effort |
Coverage |
| Auto (zero-code) |
None |
Frameworks, HTTP, DB, messaging |
| Manual (code-based) |
Medium |
Custom business logic spans |
| Library instrumentation |
Low |
Third-party library support |
Rule: Start with auto-instrumentation, add manual spans only for
business-critical operations that auto-instrumentation doesn't cover.
3. Metrics
Instrument Types
| Type |
Monotonic |
Sync |
Use Case |
| Counter |
Yes |
Sync |
Request count, bytes sent |
| UpDownCounter |
No |
Sync |
Queue size, active connections |
| Histogram |
N/A |
Sync |
Request duration, response size |
| Gauge |
N/A |
Sync |
CPU temperature, memory usage |
| Observable* |
Varies |
Async |
Collected once per export cycle |
Timer note: Some frameworks (e.g., Micrometer) provide a Timer type
that combines duration measurement with count. In OTel, use a Histogram
instrument for the same purpose (e.g., http.server.request.duration).
Exemplars
Link metrics to traces for drill-down from aggregated data to individual requests.
- Attach trace ID / span ID to metric measurements
- Configure with
TraceBased exemplar filter
- Visualized as diamond markers in Grafana
- Enables: "This p99 latency spike → show me the exact trace"
Views
Customize metric processing per instrument:
- Select which instruments to process
- Override aggregation strategy (e.g., explicit bucket histogram)
- Filter or rename attributes
- Set aggregation temporality
Metric Naming Convention
# OTel standard: dot-separated, lowercase, include unit
http.server.request.duration
db.client.operation.duration
# Domain-specific pattern: <domain>.<entity>.<action>
orders.created.total
payments.processing.duration
users.active.count
cache.hits.total
Use standard units: s (seconds), By (bytes), {request} (count).
Key Metrics to Monitor
Application Metrics
| Metric |
Alert Threshold |
Severity |
| HTTP error rate (5xx) |
> 1% of requests |
Critical |
| HTTP P99 latency |
> 3x baseline |
Warning |
| Heap/memory usage |
> 85% |
Warning |
| GC pause time |
> 500ms |
Warning |
| Thread pool active threads |
> 90% capacity |
Warning |
| DB connection pool exhaustion |
> 90% used |
Critical |
Business Metrics
| Metric |
Purpose |
| Orders per minute |
Business throughput |
| Payment success rate |
Revenue impact |
| User login rate |
Traffic pattern |
| API call count by endpoint |
Usage analytics |
Infrastructure Metrics
| Metric |
Alert Threshold |
| CPU usage |
> 80% sustained |
| Memory usage |
> 85% |
| Disk I/O |
> 80% utilization |
| Pod restart count |
> 0 unexpected |
4. Logs
OTel does not replace existing logging frameworks. It bridges them.
Integration Pattern
[Application Code]
→ [Logging Framework (Logback, Log4j, winston)]
→ [OTel Log Appender/Bridge]
→ [OTel SDK LogRecordProcessor]
→ [OTel Collector or Backend]
Log-Trace Correlation
When OTel SDK is active, trace ID and span ID are automatically injected
into log records. No code changes required.
{
"timestamp": "2026-03-24T10:30:00Z",
"severity": "ERROR",
"body": "Payment processing failed",
"traceId": "abc123...",
"spanId": "def456...",
"attributes": {
"user.id": "42",
"order.id": "ORD-789"
}
}
Log Rules
- Use structured logging (JSON) for machine readability
- Let OTel SDK inject trace context automatically
- Do not call the Logs Bridge API directly from application code
- Configure log appenders for your framework (Logback, Log4j2, Python logging)
5. OTel Collector
The Collector is a vendor-agnostic proxy that receives, processes, and exports
telemetry data. For detailed pipeline configuration, see
references/otel-collector.md.
Deployment Patterns
| Pattern |
Description |
When to Use |
| No Collector |
App exports directly to backend |
Dev/test only |
| Agent (sidecar) |
Collector beside each service |
Fast offloading, local processing |
| Gateway |
Centralized Collector cluster |
Multi-source collection, routing |
Recommendation: Use Agent mode in production for reliability. Gateway mode
for cross-cluster aggregation and routing.
Essential Processors
| Processor |
Purpose |
batch |
Buffer and send in batches (reduces network overhead) |
memory_limiter |
Prevent OOM (always configure — set limit_mib to ~80% of container memory) |
attributes |
Add, update, delete, hash attributes |
filter |
Drop unwanted telemetry |
tail_sampling |
Sample based on complete trace (Collector only) |
resource |
Add resource attributes |
6. Semantic Conventions
Use standard attribute names for interoperability across tools and dashboards.
For the full convention list, see
references/semantic-conventions.md.
Key Conventions (Summary)
| Domain |
Key Attributes |
| HTTP |
http.request.method, http.response.status_code, url.path, http.route |
| Database |
db.system, db.operation.name, db.collection.name |
| Messaging |
messaging.system, messaging.operation.type, messaging.destination.name |
| RPC |
rpc.system, rpc.service, rpc.method |
7. SDK Patterns
For detailed setup examples by language (Java, Node.js, Python), see
references/otel-sdk-patterns.md.
Quick Reference
| Language |
Zero-Code |
Manual |
| Java |
-javaagent:opentelemetry-javaagent.jar |
GlobalOpenTelemetry.getTracer() |
| Java (Spring Boot 4.0+) |
spring-boot-starter-opentelemetry |
Spring-integrated config |
| Node.js |
@opentelemetry/auto-instrumentations-node |
trace.getTracer() |
| Python |
opentelemetry-instrument CLI |
trace.get_tracer() |
8. Backend Integration
Recommended Stack (Grafana)
Traces → Grafana Tempo (OTLP native)
Metrics → Prometheus (OTLP receiver or remote write)
Logs → Grafana Loki (OTLP native, Loki 3.0+)
UI → Grafana (unified query across all signals)
Jaeger
- Jaeger v2 uses OTel Collector as its core pipeline
- OTLP endpoints: gRPC
4317, HTTP 4318
jaegertracing/all-in-one Docker image for dev
Prometheus OTLP
# Enable OTLP receiver
prometheus --web.enable-otlp-receiver
# OTel SDK environment variables
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://localhost:9090/api/v1/otlp/v1/metrics
9. Alerting
Design alerts around symptoms, not causes. For detailed alerting rules,
severity levels, and templates, see
references/alerting-rules.md.
Key Principles
- Alert on symptoms (error rate, latency), not causes (CPU, memory)
- Every alert must have a runbook or action item
- Avoid alert fatigue — only alert on actionable conditions
- Use multi-window or burn-rate alerts over simple thresholds
- Include context in alert messages (service, environment, metric value)
Alert Severity Summary
| Level |
Response Time |
Example |
| Critical |
Immediate |
Service down, data loss risk |
| Warning |
Within 1 hour |
Degraded performance |
| Info |
Next business day |
Approaching threshold |
10. Health Checks
Health checks enable orchestrators (Kubernetes, load balancers) to manage
application lifecycle. For detailed probe configuration and rules, see
references/health-checks.md.
Probe Types
| Probe |
Check |
External Dependencies |
| Liveness |
App is running |
No |
| Readiness |
App can serve traffic |
Yes (DB, cache) |
| Startup |
App initialization done |
Yes |
Key Rules
- Liveness probes must be lightweight — no external dependency checks
- Readiness probes should verify critical dependencies
- Never put slow checks in liveness probes (causes unnecessary restarts)
- Health checks must not cause side effects (writes, external calls)
11. Common Anti-Patterns
| Anti-Pattern |
Problem |
Fix |
| No sampling in production |
Storage explosion |
Use head or tail sampling |
| High-cardinality attributes in metrics |
Metric/index explosion |
Limit metric attribute values, use Views to filter |
| Sensitive data in spans |
Security/compliance risk |
Redact PII with attribute processor |
| Skipping Collector |
No buffering, sampling, or routing |
Deploy Collector in Agent mode |
| Ignoring Semantic Conventions |
Inconsistent dashboards/alerts |
Follow OTel standard names |
No memory_limiter processor |
Collector OOM |
Always configure memory limits |
| Manual trace propagation |
Broken traces, missing context |
Use SDK auto-propagation |
| Logging trace ID manually |
Duplicate/inconsistent IDs |
Let OTel SDK inject automatically |
| Alerting on every error |
Alert fatigue |
Alert on error rate instead |
| Missing traceId in logs |
Breaks correlation |
Enable OTel log bridge |
| Dashboard with 50+ panels |
Information overload |
Focus on key signals per dashboard |
| No baseline metrics |
Cannot detect regressions |
Establish baselines before alerting |
| Monitoring only infra, not business |
Miss revenue-impacting issues |
Add business metrics |
12. SLO/SLI Design
Service Level Objectives (SLOs) and Indicators (SLIs) translate reliability into measurable targets.
For detailed design patterns, see references/slo-sli-design.md.
SLI Selection Framework
| Request Type |
Recommended SLIs |
| User-facing APIs |
Availability, Latency (p99), Error rate |
| Background jobs |
Freshness, Throughput, Error rate |
| Data pipelines |
Completeness, Freshness, Accuracy |
| Storage systems |
Durability, Availability, Latency |
SLO Design Rules
- Set SLO targets based on user pain thresholds, not current performance — aspire and improve
- Define error budget =
(1 - SLO) × time window; consume it deliberately on features, not incidents
- Use multi-window multi-burn-rate alerts (5m + 1h short window, 30m + 6h long window)
- Review and adjust SLOs quarterly — SLOs should reflect current user expectations
- Start conservative (e.g., 99.0%) and tighten as reliability improves
Error Budget Policy
| Budget Remaining |
Action |
| > 50% |
Ship features freely |
| 25–50% |
Review risky changes |
| 10–25% |
Freeze non-critical deploys |
| < 10% |
Incident review required before any deploy |
| 0% |
Reliability work only until budget restored |
13. Related Skills
logging: Structured logging and monitoring integration
incident-response: Alert-driven incident response processes
troubleshooting: Monitoring data-driven problem diagnosis
spring-framework: Spring Boot Actuator and Micrometer metrics
Additional References
- For PromQL examples, recording rules, and common query patterns, see references/prometheus-queries.md
- For SLO/SLI design, error budget management, and multi-window burn rate alerting, see references/slo-sli-design.md
- OpenTelemetry Documentation - Official OpenTelemetry documentation
- Prometheus Documentation - Official Prometheus documentation
- Google SRE Book - Monitoring - Monitoring distributed systems
- For Spring Boot implementation patterns (Actuator, Micrometer, distributed tracing), see
spring-framework skill — references/monitoring.md
1---2name: observability3description: Modern observability and monitoring patterns centered on OpenTelemetry (OTel). Covers the three pillars (traces, metrics, logs) with context propagation, OTel SDK architecture, OTLP protocol, distributed tracing with W3C Trace Context, metric instrument types (Counter, Histogram, Gauge, Timer, Exemplars), key metrics to monitor (application, business, infrastructure), metric naming conventions, log correlation, OTel Collector pipelines, Semantic Conventions, backend integration (Jaeger, Grafana Tempo, Loki, Prometheus), alerting rules, health check patterns (liveness, readiness, startup), SLO/SLI design, error budget management, and business metrics modeling. Use when implementing distributed tracing, setting up OTel instrumentation, configuring Collector pipelines, designing alerting strategies, implementing health checks, defining SLO/SLI targets, or integrating observability backends.4license: MIT5---67# Observability Rules (OpenTelemetry)89## 1. Core Concepts1011OpenTelemetry provides a unified standard for collecting telemetry data.1213### Three Pillars + Context1415| Signal | Purpose | Role in Debugging |16| --- | --- | --- |17| **Traces** | Request flow across services | Where it went wrong (which service/span) |18| **Metrics** | Aggregated measurements over time | Something is wrong (alert trigger) |19| **Logs** | Discrete event records | What went wrong (error details) |20| **Context** | Correlates all signals via trace ID, span ID | Connect all three for correlated debugging |2122### Architecture2324```text25[Application + OTel SDK]26 |-- API (instrumentation interface)27 |-- SDK (implementation: sampling, batching, export)28 |-- Auto-instrumentation (zero-code)29 |30 [OTel Collector] (optional but recommended)31 |-- Receivers → Processors → Exporters32 |33 [Backends: Jaeger, Tempo, Prometheus, Loki]34```3536### OTLP Protocol3738| Transport | Port | Use Case |39| --- | --- | --- |40| gRPC | 4317 | Default, binary protobuf |41| HTTP | 4318 | Firewalls, load balancers |4243Endpoints: `/v1/traces`, `/v1/metrics`, `/v1/logs`4445## 2. Distributed Tracing4647### Span Structure4849A span represents a unit of work with:5051- **Span Context**: trace ID, span ID, trace flags (immutable)52- **Attributes**: key-value metadata (`http.request.method`, `db.system`)53- **Events**: timestamped annotations within the span54- **Links**: causal relationships to other spans (async flows)55- **Status**: Unset (default), Error, Ok5657### SpanKind5859| Kind | Direction | Example |60| --- | --- | --- |61| Client | Outbound sync | HTTP client, DB client |62| Server | Inbound sync | HTTP server handler |63| Internal | In-process | Business logic |64| Producer | Outbound async | Queue publish |65| Consumer | Inbound async | Queue consume |6667### W3C Trace Context Propagation6869```text70traceparent: 00-<trace-id>-<span-id>-<trace-flags>71tracestate: vendor-specific data72```7374- Default propagator in OTel75- Inject on outgoing requests, extract on incoming76- Never propagate internal trace data to untrusted external services77- Never put sensitive data in Baggage7879### Instrumentation Approaches8081| Approach | Effort | Coverage |82| --- | --- | --- |83| Auto (zero-code) | None | Frameworks, HTTP, DB, messaging |84| Manual (code-based) | Medium | Custom business logic spans |85| Library instrumentation | Low | Third-party library support |8687**Rule**: Start with auto-instrumentation, add manual spans only for88business-critical operations that auto-instrumentation doesn't cover.8990## 3. Metrics9192### Instrument Types9394| Type | Monotonic | Sync | Use Case |95| --- | --- | --- | --- |96| Counter | Yes | Sync | Request count, bytes sent |97| UpDownCounter | No | Sync | Queue size, active connections |98| Histogram | N/A | Sync | Request duration, response size |99| Gauge | N/A | Sync | CPU temperature, memory usage |100| Observable* | Varies | Async | Collected once per export cycle |101102> **Timer note**: Some frameworks (e.g., Micrometer) provide a Timer type103> that combines duration measurement with count. In OTel, use a Histogram104> instrument for the same purpose (e.g., `http.server.request.duration`).105106### Exemplars107108Link metrics to traces for drill-down from aggregated data to individual requests.109110- Attach trace ID / span ID to metric measurements111- Configure with `TraceBased` exemplar filter112- Visualized as diamond markers in Grafana113- Enables: "This p99 latency spike → show me the exact trace"114115### Views116117Customize metric processing per instrument:118119- Select which instruments to process120- Override aggregation strategy (e.g., explicit bucket histogram)121- Filter or rename attributes122- Set aggregation temporality123124### Metric Naming Convention125126```text127# OTel standard: dot-separated, lowercase, include unit128http.server.request.duration129db.client.operation.duration130131# Domain-specific pattern: <domain>.<entity>.<action>132orders.created.total133payments.processing.duration134users.active.count135cache.hits.total136```137138Use standard units: `s` (seconds), `By` (bytes), `{request}` (count).139140### Key Metrics to Monitor141142#### Application Metrics143144| Metric | Alert Threshold | Severity |145| --- | --- | --- |146| HTTP error rate (5xx) | > 1% of requests | Critical |147| HTTP P99 latency | > 3x baseline | Warning |148| Heap/memory usage | > 85% | Warning |149| GC pause time | > 500ms | Warning |150| Thread pool active threads | > 90% capacity | Warning |151| DB connection pool exhaustion | > 90% used | Critical |152153#### Business Metrics154155| Metric | Purpose |156| --- | --- |157| Orders per minute | Business throughput |158| Payment success rate | Revenue impact |159| User login rate | Traffic pattern |160| API call count by endpoint | Usage analytics |161162#### Infrastructure Metrics163164| Metric | Alert Threshold |165| --- | --- |166| CPU usage | > 80% sustained |167| Memory usage | > 85% |168| Disk I/O | > 80% utilization |169| Pod restart count | > 0 unexpected |170171## 4. Logs172173OTel does not replace existing logging frameworks. It bridges them.174175### Integration Pattern176177```text178[Application Code]179 → [Logging Framework (Logback, Log4j, winston)]180 → [OTel Log Appender/Bridge]181 → [OTel SDK LogRecordProcessor]182 → [OTel Collector or Backend]183```184185### Log-Trace Correlation186187When OTel SDK is active, trace ID and span ID are automatically injected188into log records. No code changes required.189190```json191{192 "timestamp": "2026-03-24T10:30:00Z",193 "severity": "ERROR",194 "body": "Payment processing failed",195 "traceId": "abc123...",196 "spanId": "def456...",197 "attributes": {198 "user.id": "42",199 "order.id": "ORD-789"200 }201}202```203204### Log Rules205206- Use structured logging (JSON) for machine readability207- Let OTel SDK inject trace context automatically208- Do not call the Logs Bridge API directly from application code209- Configure log appenders for your framework (Logback, Log4j2, Python logging)210211## 5. OTel Collector212213The Collector is a vendor-agnostic proxy that receives, processes, and exports214telemetry data. For detailed pipeline configuration, see215[references/otel-collector.md](references/otel-collector.md).216217### Deployment Patterns218219| Pattern | Description | When to Use |220| --- | --- | --- |221| No Collector | App exports directly to backend | Dev/test only |222| Agent (sidecar) | Collector beside each service | Fast offloading, local processing |223| Gateway | Centralized Collector cluster | Multi-source collection, routing |224225**Recommendation**: Use Agent mode in production for reliability. Gateway mode226for cross-cluster aggregation and routing.227228### Essential Processors229230| Processor | Purpose |231| --- | --- |232| `batch` | Buffer and send in batches (reduces network overhead) |233| `memory_limiter` | Prevent OOM (always configure — set `limit_mib` to ~80% of container memory) |234| `attributes` | Add, update, delete, hash attributes |235| `filter` | Drop unwanted telemetry |236| `tail_sampling` | Sample based on complete trace (Collector only) |237| `resource` | Add resource attributes |238239## 6. Semantic Conventions240241Use standard attribute names for interoperability across tools and dashboards.242For the full convention list, see243[references/semantic-conventions.md](references/semantic-conventions.md).244245### Key Conventions (Summary)246247| Domain | Key Attributes |248| --- | --- |249| HTTP | `http.request.method`, `http.response.status_code`, `url.path`, `http.route` |250| Database | `db.system`, `db.operation.name`, `db.collection.name` |251| Messaging | `messaging.system`, `messaging.operation.type`, `messaging.destination.name` |252| RPC | `rpc.system`, `rpc.service`, `rpc.method` |253254## 7. SDK Patterns255256For detailed setup examples by language (Java, Node.js, Python), see257[references/otel-sdk-patterns.md](references/otel-sdk-patterns.md).258259### Quick Reference260261| Language | Zero-Code | Manual |262| --- | --- | --- |263| Java | `-javaagent:opentelemetry-javaagent.jar` | `GlobalOpenTelemetry.getTracer()` |264| Java (Spring Boot 4.0+) | `spring-boot-starter-opentelemetry` | Spring-integrated config |265| Node.js | `@opentelemetry/auto-instrumentations-node` | `trace.getTracer()` |266| Python | `opentelemetry-instrument` CLI | `trace.get_tracer()` |267268## 8. Backend Integration269270### Recommended Stack (Grafana)271272```text273Traces → Grafana Tempo (OTLP native)274Metrics → Prometheus (OTLP receiver or remote write)275Logs → Grafana Loki (OTLP native, Loki 3.0+)276UI → Grafana (unified query across all signals)277```278279### Jaeger280281- Jaeger v2 uses OTel Collector as its core pipeline282- OTLP endpoints: gRPC `4317`, HTTP `4318`283- `jaegertracing/all-in-one` Docker image for dev284285### Prometheus OTLP286287```bash288# Enable OTLP receiver289prometheus --web.enable-otlp-receiver290```291292```bash293# OTel SDK environment variables294OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf295OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://localhost:9090/api/v1/otlp/v1/metrics296```297298## 9. Alerting299300Design alerts around symptoms, not causes. For detailed alerting rules,301severity levels, and templates, see302[references/alerting-rules.md](references/alerting-rules.md).303304### Key Principles305306- Alert on symptoms (error rate, latency), not causes (CPU, memory)307- Every alert must have a runbook or action item308- Avoid alert fatigue — only alert on actionable conditions309- Use multi-window or burn-rate alerts over simple thresholds310- Include context in alert messages (service, environment, metric value)311312### Alert Severity Summary313314| Level | Response Time | Example |315| --- | --- | --- |316| Critical | Immediate | Service down, data loss risk |317| Warning | Within 1 hour | Degraded performance |318| Info | Next business day | Approaching threshold |319320## 10. Health Checks321322Health checks enable orchestrators (Kubernetes, load balancers) to manage323application lifecycle. For detailed probe configuration and rules, see324[references/health-checks.md](references/health-checks.md).325326### Probe Types327328| Probe | Check | External Dependencies |329| --- | --- | --- |330| Liveness | App is running | No |331| Readiness | App can serve traffic | Yes (DB, cache) |332| Startup | App initialization done | Yes |333334### Key Rules335336- Liveness probes must be lightweight — no external dependency checks337- Readiness probes should verify critical dependencies338- Never put slow checks in liveness probes (causes unnecessary restarts)339- Health checks must not cause side effects (writes, external calls)340341## 11. Common Anti-Patterns342343| Anti-Pattern | Problem | Fix |344| --- | --- | --- |345| No sampling in production | Storage explosion | Use head or tail sampling |346| High-cardinality attributes in metrics | Metric/index explosion | Limit metric attribute values, use Views to filter |347| Sensitive data in spans | Security/compliance risk | Redact PII with attribute processor |348| Skipping Collector | No buffering, sampling, or routing | Deploy Collector in Agent mode |349| Ignoring Semantic Conventions | Inconsistent dashboards/alerts | Follow OTel standard names |350| No `memory_limiter` processor | Collector OOM | Always configure memory limits |351| Manual trace propagation | Broken traces, missing context | Use SDK auto-propagation |352| Logging trace ID manually | Duplicate/inconsistent IDs | Let OTel SDK inject automatically |353| Alerting on every error | Alert fatigue | Alert on error rate instead |354| Missing traceId in logs | Breaks correlation | Enable OTel log bridge |355| Dashboard with 50+ panels | Information overload | Focus on key signals per dashboard |356| No baseline metrics | Cannot detect regressions | Establish baselines before alerting |357| Monitoring only infra, not business | Miss revenue-impacting issues | Add business metrics |358359## 12. SLO/SLI Design360361Service Level Objectives (SLOs) and Indicators (SLIs) translate reliability into measurable targets.362For detailed design patterns, see [references/slo-sli-design.md](references/slo-sli-design.md).363364### SLI Selection Framework365366| Request Type | Recommended SLIs |367| ------------ | ---------------- |368| User-facing APIs | Availability, Latency (p99), Error rate |369| Background jobs | Freshness, Throughput, Error rate |370| Data pipelines | Completeness, Freshness, Accuracy |371| Storage systems | Durability, Availability, Latency |372373### SLO Design Rules374375- Set SLO targets based on user pain thresholds, not current performance — aspire and improve376- Define error budget = `(1 - SLO) × time window`; consume it deliberately on features, not incidents377- Use multi-window multi-burn-rate alerts (5m + 1h short window, 30m + 6h long window)378- Review and adjust SLOs quarterly — SLOs should reflect current user expectations379- Start conservative (e.g., 99.0%) and tighten as reliability improves380381### Error Budget Policy382383| Budget Remaining | Action |384| ---------------- | ------ |385| > 50% | Ship features freely |386| 25–50% | Review risky changes |387| 10–25% | Freeze non-critical deploys |388| < 10% | Incident review required before any deploy |389| 0% | Reliability work only until budget restored |390391---392393## 13. Related Skills394395- `logging`: Structured logging and monitoring integration396- `incident-response`: Alert-driven incident response processes397- `troubleshooting`: Monitoring data-driven problem diagnosis398- `spring-framework`: Spring Boot Actuator and Micrometer metrics399400## Additional References401402- For PromQL examples, recording rules, and common query patterns, see [references/prometheus-queries.md](references/prometheus-queries.md)403- For SLO/SLI design, error budget management, and multi-window burn rate alerting, see [references/slo-sli-design.md](references/slo-sli-design.md)404- [OpenTelemetry Documentation](https://opentelemetry.io/docs/) - Official OpenTelemetry documentation405- [Prometheus Documentation](https://prometheus.io/docs/) - Official Prometheus documentation406- [Google SRE Book - Monitoring](https://sre.google/sre-book/monitoring-distributed-systems/) - Monitoring distributed systems407- For Spring Boot implementation patterns (Actuator, Micrometer, distributed tracing), see `spring-framework` skill — [references/monitoring.md](../spring-framework/references/monitoring.md)