agentleFS
suhailkakarsuhailkakar/the-skills/observability/SKILL.md

observability

Skill26 starsChanged 6 months agoMITView on GitHub

Use when the user is shipping anything to production, adding console.log for debugging, asking "why is this slow/broken?", wiring logging/tracing/metrics, or setting up alerts. Catches console.log in prod, missing trace IDs, alerting on symptoms instead of SLOs, and "we have no idea what happened" incidents.

87 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use gitops, background-jobs and 10 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • kcns008Skill

    gitops

    GitOps Agent (Flow) — manages ArgoCD applications, Helm charts, Kustomize overlays, deployment strategies (canary, blue-green, rolling), multi-cluster GitOps, and drift detection for Kubernetes and OpenShift clusters.

    Also in 4 projects that use this

  • YepAPISkill

    background-jobs

    Queue workers with BullMQ/Inngest/Trigger.dev, job retries, dead letter queues, concurrency.

    Also in 4 projects that use this

  • Mushfiqur-Rahman-RobinSkill

    rag-systems

    Best practices for building Retrieval-Augmented Generation systems — chunking, embedding, hybrid retrieval, reranking, indexing, caching, evaluation, observability — plus a catalog of RAG patterns and when each applies.

    Also in 3 projects that use this

  • YepAPISkill

    data-pipelines

    ETL patterns, cron scheduling, queue-based processing, and batch jobs with Inngest/BullMQ.

    Also in 4 projects that use this

  • wpankSkill

    caching

    Caching strategies, invalidation, eviction policies, HTTP caching, distributed caching, and anti-patterns. Use when designing cache layers, choosing eviction policies, debugging stale data, or optimizing read-heavy workloads.

    Also in 5 projects that use this

  • JohnJBorenSkill

    ci-cd

    CI/CD pipeline design, GitHub Actions, testing automation, and deployment strategies

    Also in 13 projects that use this

The file

We split this skill into the rules it gives an agent

4 rules. 0 are common, 3 are distinctive, and 1 is very specific to this project.

  • 0

    Common

    Most of the 70 edited versions we read keep these.

  • 3

    Distinctive

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Default: structured logs first, traces for any request that crosses services, metrics for SLOs.

    line 29
  2. Very specific:

    Don't error-level things that are normal (a 404 from a missing-user lookup is info).

    line 67
  3. Distinctive:

    When you call another service, propagate the trace context:

    line 91
  4. Distinctive:

    Put high-cardinality fields in logs and traces (where they belong), not in metric labels.

    line 139

“Common” is measured: kept by at least 6 in 10 of the 70 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Observability

If a user reports a bug at 3am, can you tell — within 5 minutes — exactly what request they made, what code path it took, and why it failed? If not, you don't have observability, you have logs.

When to use

  • About to ship anything to production
  • Setting up logging, tracing, or metrics
  • Adding console.log (replace with structured log immediately)
  • Wiring an alert
  • Diagnosing a slow or flaky path
  • Reviewing what happens when an incident hits

When to skip

  • Throwaway scripts and one-off tooling

The three pillars (and which to reach for first)

WhatWhen to reach for it
Logsstructured records of events"what happened on this request?"
Metricsnumbers over time"how often, how slow, how many errors?"
Tracesrequest → spans across services"where did the time go in this slow request?"

Default: structured logs first, traces for any request that crosses services, metrics for SLOs. Don't skip straight to a fancy dashboard before you can answer "what happened in this request" from logs.

The rules

1. No console.log in production code paths.

// BAD — unstructured, ungreppable, no level, no context
console.log('user signed up', user)

// GOOD — structured, queryable, leveled
import { logger } from '@/lib/logger'
logger.info({ userId: user.id, plan: user.plan, requestId }, 'user.signed_up')

Picks: Pino (Node), Logtape (cross-runtime, edge-friendly), @vercel/otel for built-in. Whatever you pick, structured JSON is non-negotiable.

2. Every log line gets a request ID.

// In a middleware or at the top of every handler
const requestId = req.headers.get('x-request-id') ?? crypto.randomUUID()
const log = logger.child({ requestId })
// pass `log` down, or attach to async-local-storage

The requestId is also returned in the response (x-request-id header). When a user pastes it in a bug report, you grep that ID and see every log line for the request — across web, API, jobs, and downstream services.

3. Use levels with intent.

LevelUse for
trace / debugLocal development; stripped in prod by config
infoNormal events: request received, job completed, user action
warnRecoverable issues: retry, fallback engaged, deprecated path used
errorUnexpected failure that affected this request
fatalProcess going down

Don't error-level things that are normal (a 404 from a missing-user lookup is info). Alert thresholds depend on level being meaningful.

4. Log the entire Error object, not its message.

// BAD — loses stack trace, loses cause chain
logger.error('failed: ' + err.message)

// GOOD — modern loggers serialize Error properly via `err.cause`
logger.error({ err, requestId, userId }, 'job.failed')

5. Distributed traces with OpenTelemetry. Not provider-locked SDKs.

// instrumentation.ts
import { registerOTel } from '@vercel/otel'
registerOTel({ serviceName: 'web' })

OTel emits a vendor-neutral format. Honeycomb, Datadog, Grafana Tempo, AWS X-Ray, Jaeger — all consume it. Don't hand-write spans for everything; instrument the framework + your DB + outbound HTTP, and let auto-instrumentation cover the rest.

6. Trace propagation across boundaries.

When you call another service, propagate the trace context:

// fetch automatically forwards `traceparent` if OTel is wired correctly
const res = await fetch('https://internal.api/x', { headers: { ... } })

For background jobs, include the trace context in the job payload; resume it in the worker. Otherwise the trace is broken at every async boundary and you can't see the whole request.

7. Metrics: RED for services, USE for resources.

RED (per service/endpoint):

  • Rate (requests per second)
  • Errors (errors per second)
  • Duration (latency, p50/p95/p99)

USE (per resource: CPU, DB connections, queue):

  • Utilization
  • Saturation
  • Errors

Build a dashboard with these for every service before you build anything fancier.

8. Alert on SLOs, not symptoms.

BAD:  alert if error_rate > 0% for 1 minute    →   pages you for every blip
BAD:  alert if cpu > 80%                       →   not a user-facing problem yet
GOOD: alert if (success_rate over 5 min) < 99.9% AND lasts > 5 min
GOOD: alert if p95_latency over 10 min > 500ms AND lasts > 10 min

An SLO-based alert pages you when users are affected at a meaningful level, not when a metric twitches. Consider error-budget burn rate (Google SRE handbook) for the right shape.

9. Cardinality discipline.

// BAD — every requestId becomes a metric label, blows up cardinality and your bill
metrics.increment('http.requests', { requestId, userId, url })

// GOOD — bounded label sets
metrics.increment('http.requests', {
  route: '/api/posts',     // bounded
  status: '200',           // bounded
  region: 'iad1',          // bounded
})

Put high-cardinality fields in logs and traces (where they belong), not in metric labels. A cardinality blowup can $$$ you instantly.

10. The dashboard you'd want at 3am, before 3am.

For each service: requests/sec, errors/sec, p95 latency, queue depth, DB connection pool, recent deploys overlaid. Recent deploys overlaid is the cheap superpower — most prod incidents are "what just changed."

11. Don't log sensitive data. Or log a redacted version.

// BAD
logger.info({ user, password: req.body.password }, 'login')

// GOOD — explicit allowlist of fields, or use a redactor
logger.info({ userId, email: redactEmail(email), ip }, 'login')

Most loggers (Pino) support redact paths. Configure once at the logger level so a junior dev's new log line can't leak. See data-privacy.

What "good" looks like (minimum bar)

For every service before launch:

  • Structured logs with requestId, userId, route, level, msg
  • One trace per request (auto-instrumented for HTTP + DB + outbound)
  • RED metrics dashboard + recent-deploy overlay
  • One SLO-based alert ("availability < 99.5% for 5min" or similar)
  • Logs and traces correlated via requestId and traceparent

War story

A "background sync" job started failing silently after a deploy. Errors went to console.log. The platform's stdout retention was 24 hours and ungreppable. Three days later, customer reports come in: "data hasn't synced since Friday." The team spent six hours reconstructing the failure window from raw logs and DB state. Adding Pino + a job.failed alert took 30 minutes the next day and would have caught it within the hour.

Quick checklist

  • No console.log in prod code; use a structured logger
  • requestId in every log line and echoed in the response header
  • Log levels used with intent; expected events not at error
  • Errors logged with { err } (full Error object), not err.message
  • OpenTelemetry instrumentation enabled; traces flow across services and jobs
  • RED dashboard per service with deploy markers
  • SLO-based alerts (sustained, multi-window), not symptom-twitch alerts
  • Metric labels are low-cardinality
  • Sensitive fields redacted at the logger level

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.