structured-logginglisted
Install: claude install-skill Markuysa/agent-skills
# Structured logging
The test for a log line is simple: **when this fires at 3am, does it tell someone
what happened and what to do?** Lines that fail that test are cost — in storage,
in scroll, and in the attention they take from the line that mattered.
## Structured, always
Log key-value events, never interpolated prose. Prose is unqueryable, and every
log pipeline ends up needing queries.
```go
// bad — cannot filter, aggregate, or alert on this
log.Printf("failed to process order %s for user %s: %v", orderID, userID, err)
// good — every field is a filterable dimension
slog.ErrorContext(ctx, "process order failed",
"order_id", orderID,
"user_id", userID,
"err", err,
)
```
The message is a **stable, constant string** — it's the identity of the event, so
you can find every occurrence. Everything variable goes in fields. A message
built with `fmt.Sprintf` cannot be grouped, which defeats the purpose.
Keep field names consistent across the whole system (`user_id`, never `userId`
here and `uid` there). Inconsistent names are discovered during an incident, at
the worst possible moment.
## Levels
Pick by **who acts on it**, not by how you feel about the event:
| Level | Meaning | Who reads it |
| --- | --- | --- |
| `ERROR` | Something failed that shouldn't; needs a human eventually | On-call, dashboards |
| `WARN` | Degraded but handled — fallback used, retry succeeded | Reviewed in aggregate |
| `INFO` | A significant state change: started, stopped, deplo