Adds one top-level telemetry skill covering the observability stack that deploys as one unit: Prometheus (scrape config, recording/alerting rules, relabeling, retention, HA), the OpenTelemetry Collector (pipelines, receivers/processors/exporters, sampling, trace/span correlation), and Loki (ingest, LogQL, retention, labels). Ships the read-only telemetry-check script (stdlib-only, --json): Prometheus rule sanity mirroring promtool check rules plus scrape-target reachability probes, fixture-tested with 16 unittest/pytest cases. Includes five dated references, a human-facing README, and six eval cases covering rule authoring, pipeline design, and retention. Routes up to platform-engineering and grafana without duplicating their content. Regenerates the llms.txt / marketplace / plugin catalogs and adds the README index entry. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
4.1 KiB
OpenTelemetry Collector Operations
Last Updated: 2026-08-03
Operational patterns for the OpenTelemetry Collector in the telemetry stack: pipeline design, receivers/processors/exporters, sampling, and trace/span correlation. Sources: OpenTelemetry Collector documentation (opentelemetry.io/docs/collector, accessed 2026-08-03).
Pipeline design
A pipeline is a named, directed acyclic chain per signal type (metrics, logs,
traces): one or more receivers, zero or more processors, one or more
exporters. Signals flow through every processor in order, so pipeline length
is a cost and a debugging surface.
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, batch, tail_sampling]
exporters: [otlp/backend]
metrics:
receivers: [otlp, prometheus]
processors: [memory_limiter, batch]
exporters: [prometheusremotewrite]
logs:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [loki]
Design rules:
- keep pipelines per signal — a pipeline that mixes traces and logs becomes un-debuggable and couples sampling decisions;
- run one
memory_limiterprocessor before every exporter to bound memory (ballast_size_mibis deprecated; sizecheck_interval/limit_mibagainst the container limit); batchafter sampling and before exporting amortizes exporter cost;- an unused receiver or exporter is dead configuration — remove it.
Receivers, processors, exporters
| Role | Examples | Notes |
|---|---|---|
| Receiver | otlp (default port 4317 gRPC / 4318 HTTP), prometheus, filelog, hostmetrics |
Receivers own the ingest surface; auth and TLS live here |
| Processor | memory_limiter, batch, tail_sampling, probabilistic_sampler, resource, attributes, filter, transform, spanmetrics |
Order matters: sampling before batch changes semantics; resource should run early |
| Exporter | otlp, prometheusremotewrite, loki, logging/debug, kafka |
Exporters own delivery and retry; failing exporters backpressure the pipeline |
The logging/debug exporter is the troubleshooting tool: attach it to a
pipeline temporarily to see what actually leaves the collector, then remove
it. Never ship a debug exporter in production config.
Sampling
Two trace samplers ship with the collector:
probabilistic_sampler— stateless, per-span hash of the trace ID, cheap, no cross-span state. Good for high-volume, low-value traffic.tail_sampling— buffers spans per trace and decides at the batch level, so policies can depend on span attributes (status, error, duration). Stateful and memory-hungry; belongs on a trace pipeline afterbatch.
Sample with the alerting and debugging goal in mind: keep every error and slow
path (via tail_sampling policy on status.code, http.status_code,
duration), sample the long tail of success traffic, and record the sampling
decision (sampler.type/sampling.score) as a span attribute so downstream
queries can scale results. Metrics and logs are not sampled by these processors
— do not apply trace samplers to other signal pipelines.
Trace/span correlation
Correlation is the payoff of the stack: a trace ID in a log line or an exemplar lets any query pivot from "this happened" to "here is the full request". The collector supports this by:
- carrying
trace_id/span_idthrough OTLP log records — thelokiexporter maps them totrace_id/span_idstructured metadata for LogQL matching; - the
spanmetricsprocessor deriving RED (rate/errors/duration) metrics from spans, withtrace_idexemplars on the histogram so PromQL can jump to a trace; - resource attributes (
service.name,deployment.environment) flowing through to every signal so logs, metrics, and traces share the join keys.
Correlation is only as good as propagation: if the application does not propagate context, the collector cannot invent it. Missing trace context in logs usually means the SDK side is not wired — that is application-level work for backend-engineering; the collector side of the join is this skill.