Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
cxuu avatar

Go Logging

  • 677 installs
  • 137 repo stars
  • Updated June 20, 2026
  • cxuu/golang-skills

go-logging is a Claude Code skill that adds structured, leveled logging to Go services and CLIs with consistent fields, context propagation, and production-ready observability hooks for developers who need uniform log ou

About

go-logging is a Go instrumentation skill from cxuu/golang-skills that guides adding structured, leveled logging to services and command-line tools. The skill emphasizes consistent field keys, context propagation through request handlers, and hooks compatible with production observability pipelines so logs remain parseable in aggregation systems. Developers reach for it when standing up a new Go microservice, CLI, or refactoring printf-style debugging into leveled structured output. Outputs include logger initialization patterns, context-aware child loggers, and field conventions that survive multi-package codebases. Use it during backend build when traceability and operability must be designed in, not bolted on after deploy.

  • Structured slog patterns
  • Log levels and fields
  • Context-aware loggers
  • Production defaults
  • CLI and HTTP instrumentation

Go Logging by the numbers

  • 677 all-time installs (skills.sh)
  • Ranked #22 of 98 Go skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/cxuu/golang-skills --skill go-logging

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs677
repo stars137
Last updatedJune 20, 2026
Repositorycxuu/golang-skills

How do you add structured logging to Go services?

Add structured, leveled logging to Go services and CLIs with consistent fields, context propagation, and production-ready observability hooks.

Who is it for?

Go developers building APIs or CLIs who need production-grade structured logging with context fields from the start.

Skip if: Teams already standardized on a complete observability stack with tracing and metrics and only need duplicate logger setup docs.

When should I use this skill?

A developer asks to add structured logging, log levels, context fields, or observability hooks to Go code.

What you get

Leveled structured logger setup, consistent field schema, and context-propagated log calls across Go packages.

  • Logger initialization
  • Context-aware log helpers
  • Field naming conventions

Files

SKILL.mdMarkdownGitHub ↗

Go Logging

Compatibility: log/slog requires Go 1.21+; testing/slogtest requires Go 1.22+.

Resource Routing

  • references/LEVELS-AND-CONTEXT.md - Read when choosing log levels, deciding logger-in-context versus explicit parameters, or excluding sensitive fields.
  • references/LOGGING-PATTERNS.md - Read when configuring slog handlers, logging HTTP requests, testing handlers, or migrating from log.Printf.

Core Principle

Logs are for operators, not developers. Every log line should help someone diagnose a production issue. If it doesn't serve that purpose, it's noise.

---

Choosing a Logger

Normative: Use log/slog for new Go code.

slog is structured, leveled, and in the standard library (Go 1.21+). It covers the vast majority of production logging needs.

Which logger?
├─ New production code      → log/slog
├─ Trivial CLI / one-off    → log (standard)
└─ Measured perf bottleneck → zerolog or zap (benchmark first)

Do not introduce a third-party logging library unless profiling shows slog is a bottleneck in your hot path. When you do, keep the same structured key-value style.

---

Structured Logging

Normative: Always use key-value pairs. Never interpolate values into the message string.

The message is a static description of what happened. Dynamic data goes in key-value attributes:

// Good: static message, structured fields
slog.Info("order placed", "order_id", orderID, "total", total)

// Bad: dynamic data baked into the message string
slog.Info(fmt.Sprintf("order %d placed for $%.2f", orderID, total))

Key Naming

Advisory: Use snake_case for log attribute keys.

Keys should be lowercase, underscore-separated, and consistent across the codebase: user_id, request_id, elapsed_ms.

Typed Attributes

For performance-critical paths, use typed constructors to avoid allocations:

slog.LogAttrs(ctx, slog.LevelInfo, "request handled",
    slog.String("method", r.Method),
    slog.Int("status", code),
    slog.Duration("elapsed", elapsed),
)

---

Log Levels

Advisory: Follow these level semantics consistently.
LevelWhen to useProduction default
DebugDeveloper-only diagnostics, tracing internal stateDisabled
InfoNotable lifecycle events: startup, shutdown, config loadedEnabled
WarnUnexpected but recoverable: deprecated feature used, retry succeededEnabled
ErrorOperation failed, requires operator attentionEnabled

Rules of thumb:

  • If nobody should act on it, it's not Error — use Warn or Info
  • If it's only useful with a debugger attached, it's Debug
  • slog.Error should always include an "err" attribute
slog.Error("payment failed", "err", err, "order_id", id)
slog.Warn("retry succeeded", "attempt", n, "endpoint", url)
slog.Info("server started", "addr", addr)
slog.Debug("cache lookup", "key", key, "hit", hit)

---

Request-Scoped Logging

Advisory: Derive loggers from context to carry request-scoped fields.

Use middleware to enrich a logger with request ID, user ID, or trace ID, then pass the enriched logger downstream via context or as an explicit parameter. Keep the full context-key and middleware implementation in the logging patterns reference so request-scoped logging has one owner.

---

Log or Return, Not Both

The handle-once rule belongs to go-error-handling. In logging work, apply it by choosing either a local log-and-recover path or a return path with context, not both for the same error.

Exception: HTTP handlers and other top-of-stack boundaries may log detailed errors server-side while returning a sanitized message to the client:

if err != nil {
    slog.Error("checkout failed", "err", err, "user_id", uid)
    http.Error(w, "internal error", http.StatusInternalServerError)
    return
}

See go-error-handling for the full handle-once pattern and error wrapping guidance.

---

What NOT to Log

Normative: Never log secrets, credentials, PII, or high-cardinality unbounded data.
  • Passwords, API keys, tokens, session IDs
  • Full credit card numbers, SSNs
  • Request/response bodies that may contain user data
  • Entire slices or maps of unbounded size

---

Quick Reference

DoDon't
slog.Info("msg", "key", val)log.Printf("msg %v", val)
Static message + structured fieldsfmt.Sprintf in message
snake_case keyscamelCase or inconsistent keys
Log OR return errorsLog AND return the same error
Derive logger from contextCreate a new logger per call
Use slog.Error with "err" attrslog.Info for errors
Pre-check Enabled() on hot pathsAlways allocate log args

---

Related Skills

  • Error handling: See go-error-handling when deciding whether to log or return an error, or for the handle-once pattern
  • Context propagation: See go-context when passing request-scoped values (including loggers) through context
  • Performance: See go-performance when optimizing hot-path logging or reducing allocations in log calls
  • Code review: See go-code-review when reviewing logging practices in Go PRs

Related skills

FAQ

What does go-logging standardize in Go projects?

go-logging standardizes leveled structured log output, consistent field names across packages, and context propagation so request-scoped metadata flows to child loggers in Go services and CLIs.

When should developers invoke go-logging?

Developers should invoke go-logging when adding or refactoring logging in Go services and CLIs, especially when replacing ad-hoc fmt.Printf calls with production-parseable structured logs and observability hooks.

Gobackendintegrations

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.