pattern-engineer-observability
Skill0 starsChanged 5 months agoMITView on GitHub
OpenTelemetry is the only instrumentation API in source; vendor SDKs only behind the Collector. Services emit traces + metrics + logs through OTel with shared resource attributes, W3C `tracecontext` propagation, auto-instrumentation for boilerplate, RED/USE metrics with bounded label cardinality, structured JSON logs gated at source. Activate when touching instrumentation or `OTEL_*` env vars.
- Reads credentials
In this repository74 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- create-bug-issueSkill
- create-enhancement-issueSkill
- create-feature-issuesSkill
- dream-summary-memorySkill
- memory-conventionSkill
- operation-gitSkill
- pattern-architect-api-endpointSkill
- pattern-architect-data-modelSkill
- pattern-architect-deep-moduleSkill
- pattern-e2e-coding-standardSkill
- pattern-engineer-apiSkill
- pattern-engineer-backend-standardSkill
- pattern-engineer-coding-standardSkill
- pattern-engineer-containerSkill
- pattern-engineer-databaseSkill
- pattern-engineer-fastapiSkill
- pattern-engineer-frontend-standardSkill
- pattern-engineer-goSkill
- pattern-engineer-javaSkill
- pattern-engineer-kotlinSkill
- pattern-engineer-nodeSkill
- pattern-engineer-non-functionalSkill
- pattern-engineer-pythonSkill
- pattern-engineer-rustSkill
- pattern-engineer-securitySkill
- pattern-engineer-ssrSkill
- pattern-engineer-swiftSkill
- pattern-engineer-typescriptSkill
- pattern-engineer-viteSkill
- pattern-exploratory-testingSkill
- pattern-reviewer-apiSkill
- pattern-reviewer-backend-standardSkill
- pattern-reviewer-coding-standardSkill
- pattern-reviewer-containerSkill
- pattern-reviewer-contractSkill
- pattern-reviewer-databaseSkill
- pattern-reviewer-fastapiSkill
- pattern-reviewer-frontend-standardSkill
- pattern-reviewer-goSkill
- pattern-reviewer-javaSkill
- pattern-reviewer-kotlinSkill
- pattern-reviewer-nodeSkill
- pattern-reviewer-non-functionalSkill
- pattern-reviewer-observabilitySkill
- pattern-reviewer-pythonSkill
- pattern-reviewer-rustSkill
- pattern-reviewer-securitySkill
- pattern-reviewer-ssrSkill
- pattern-reviewer-swiftSkill
- pattern-reviewer-test-coverageSkill
- pattern-reviewer-typescriptSkill
- pattern-reviewer-viteSkill
- pattern-test-coverageSkill
- principle-engineer-tddSkill
- scaffold-projectSkill
- workflow-architect-interviewSkill
- workflow-designer-sample-pagesSkill
- workflow-design-interviewSkill
- workflow-e2e-authorSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
5 rules. About 0 are common, 1 is distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 18
After loading this skill, also check $MAIN_ROOT/.claude/memory/patterns/pattern-engineer-observability.md in the consuming project (resolve …
- Very specific: line 42
Cardinality is a hard constraint: Never use user.id, email, session.id, request.id, raw URL with path params, or any unbounded value as a …
- Very specific: line 43
Bound enumerable labels: only (http.status_code, db.system, payment.method, tenant.tier).
- Distinctive: line 44
Histograms ship with explicit bucket boundaries: when the domain isn't HTTP-server-duration in seconds — otherwise every observation …
- Very specific: line 73
Don't mock the OTel API: Use the real SDK with an in-memory exporter — mocking tracer.startSpan tests the mock, not the behavior.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
pattern-engineer-observability
Terse rule list for writing observability code. OpenTelemetry is the only instrumentation API; vendor SDKs (Datadog, New Relic, Sentry, Honeycomb, Splunk, Elastic) appear only as OTLP backends behind the Collector — never as imports in src/.
When to activate
Activate whenever you add/edit/remove a log statement, span, metric, or trace-context propagation; scaffold observability for a service; touch OTEL_* env vars or the SDK bootstrap; wire (or remove) auto-instrumentation; or reach for print / console.log to "see what's happening" in a service path.
Skip for local one-off print debugging in throwaway scripts or pure log-aggregation tooling that doesn't touch the app code path.
Project memory overlay
After loading this skill, also check $MAIN_ROOT/.claude/memory/patterns/pattern-engineer-observability.md in the consuming project (resolve MAIN_ROOT="$(dirname "$(git rev-parse --path-format=absolute --git-common-dir)")"). If present, load it as an additive overlay to the rules below; if absent, skip silently. See memory-convention for the full contract (additivity, severity floor, conflict surfacing).
Rules
Instrumentation surface
- OpenTelemetry only. No
dd-trace,newrelic,@sentry/node,elastic-apm-node,splunk-otelas direct imports. - No
print/console.log/console.error/fmt.Println/System.out.printlnin committed code. Use the OTel-emitting structured logger. - One structured logger per language, bridged to OTel logs (
structlogfor Python,pinofor Node,slogfor Go,Logbackfor Java). No parallel logging stacks. - Auto-instrumentation for boilerplate (HTTP servers, DB drivers, queue clients, outbound HTTP). Hand-roll spans only for business operations the framework can't infer (3–10 per service is enough).
- Resource attributes set once at SDK init (
service.name,service.version,service.namespace,deployment.environment). Per-signalservice.nameis a bug. - W3C
traceparent/tracestatepropagation. Nox-datadog-trace-id/x-b3-traceidheaders in new code.
Traces
- Span name is the route template, never the resolved URL:
"GET /users/{user_id}", notf"GET /users/{user_id}". - Use OTel semantic-convention attribute names:
http.method,http.route,http.status_code,db.system,db.statement,messaging.system,exception.type,exception.message,exception.stacktrace. Don't inventhttpMethod/dbSystem/errorMsg. - Errors →
record_exception(exc)+set_status(Status(StatusCode.ERROR, ...))(Python) /recordException+setStatus({code: SpanStatusCode.ERROR, ...})(TS). Never shove the stack trace into a free-text attribute. - App-side sampling:
ParentBased(AlwaysOn)— emit 100%. The real sampling decision lives in the Collector'stail_samplingprocessor. Fixed-ratio app-level head sampling "to save cost" is wrong.
Metrics
- Pick the right instrument.
Counter(monotonic),UpDownCounter(up/down),Histogram(distribution),Observable Gauge(sampled). A "request latency counter" is a category error. - Semantic-convention names:
http.server.duration,http.server.requests,db.client.operation.duration. Business signals under your namespace:payments.charge.attempts. Lower-case dot-separated, never camelCase. - Cardinality is a hard constraint. Never use
user.id,email,session.id,request.id, raw URL with path params, or any unbounded value as a metric attribute. If you need the dimension, it belongs on a span or log, not a metric. - Bound enumerable labels only (
http.status_code,db.system,payment.method,tenant.tier). - Histograms ship with explicit bucket boundaries when the domain isn't HTTP-server-duration in seconds — otherwise every observation collapses into one bucket and p95 is meaningless.
- Default dashboard = RED + USE. RED (Rate / Errors / Duration) per HTTP route, gRPC method, queue consumer. USE (Utilization / Saturation / Errors) per resource dependency (CPU, memory, DB pool, queue depth, GC pause).
Logs
- Structured key-value records, never
printf-style.logger.info("user.charged", user_id=user_id, amount=amount, currency="USD"), notf"User {user_id} charged {amount}". - Production threshold =
INFO.DEBUGis for transient operator-driven boosts, never the default. Gate at source, not in the Collector — serialization cost is paid in the app before the Collector ever sees it. INFO= "events the operator would want a record of, even with no incident." If you can't name the event, it'sDEBUG.- Dynamic per-logger level override, auth-gated, time-boxed (auto-revert after 10–30 min), audit-logged at
WARN. So the on-call doesn't need a redeploy during an incident, and a forgotten boost doesn't triple the log bill overnight. - Never log secrets (passwords, tokens, API keys,
Authorizationheaders, full PAN/SSN, password-reset tokens, session/refresh cookies). Redact PII (email, full name, address) at the boundary; log the user id instead. The Collector's redaction is a backstop, not the rule. - One log line per business event, not one per code path. "12 log lines in one handler" is almost always wrong.
- Active span context attaches automatically via the logs bridge. Records without
trace_id/span_idwhen there's an active span mean the bridge is misconfigured — fix that before adding more logs.
SDK bootstrap
- Bootstrap in exactly one place per service (
observability.py/observability.ts/ equivalent), called once at process start before any framework wiring. - Read every endpoint and credential from
OTEL_*env vars (OTEL_EXPORTER_OTLP_ENDPOINT,OTEL_EXPORTER_OTLP_HEADERS,OTEL_SERVICE_NAME,OTEL_SERVICE_VERSION,OTEL_SERVICE_NAMESPACE,DEPLOYMENT_ENVIRONMENT). Never hard-code an endpoint or service name. Mirror the required vars in.env.example. - Use batch processors in production:
BatchSpanProcessor,BatchLogRecordProcessor,PeriodicExportingMetricReader. Never synchronous variants — they block on export network IO. - Bootstrap MUST NOT crash when
OTEL_EXPORTER_OTLP_ENDPOINTis unset. Dev/CI booting without a Collector is a supported mode.
Alerts and SLOs
- Page on metric thresholds, not log strings.
grep ERRORalerts are fragile. - Availability SLO =
successful / totalover a window; successful =http.status_code < 500(4xx is the caller's problem). - Latency SLO = p95 (or p99) of
http.server.duration. - Saturation alerts = connection-pool / queue-depth ratios over time. Logs back the alert; they don't trigger it.
Testing observability
- Don't mock the OTel API. Use the real SDK with an in-memory exporter — mocking
tracer.startSpantests the mock, not the behavior. - Pin attributes, not just existence. "A span was created" is not an assertion; "a span named X with attribute Y=Z was created" is.
- Clear the exporter between tests (
exporter.clear()/exporter.reset()inafterEach/ pytest fixture teardown).
TDD cadence
Observability is first-class behavior: in RED assert the span / metric / log emits with the right attributes; in GREEN add the OTel call. Not a separate phase after the feature ships.
Templates
| Asset | Purpose |
templates/observability/python-bootstrap.py | Python OTel SDK bootstrap (resource, exporters, propagator, logger bridge). |
templates/observability/typescript-bootstrap.ts | TypeScript / Node OTel SDK bootstrap. |
templates/observability/collector-config.yaml | Collector starter pipeline (receivers → processors → exporters). |
templates/observability/test-fixtures.md | In-memory exporter recipes for pytest / vitest assertions. |
Invariants (verify on every change)
- The service boots without errors when
OTEL_EXPORTER_OTLP_ENDPOINTis unset. OTEL_SERVICE_NAME,OTEL_SERVICE_VERSION,OTEL_SERVICE_NAMESPACE,DEPLOYMENT_ENVIRONMENTare present in.env.exampleand the deployed env manifest.- The Collector is reachable from the service network on
:4317(gRPC) — and:4318if any client uses OTLP HTTP.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

