write-logs

Writes Go log/slog logging emitted once at outermost boundaries with fixed vocabulary and redaction.

Updated Sep 14, 2026
One-click install
npx skills add https://github.com/nakamori-naoya/go-convention-plugins --skill write-logs-nakamori-naoya
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: write-logs
Source: https://github.com/nakamori-naoya/go-convention-plugins/tree/main/plugins/go-convention/skills/write-logs
Command: npx skills add https://github.com/nakamori-naoya/go-convention-plugins --skill write-logs-nakamori-naoya

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill includes references (resource) components.

What problem does it solve? Go services often scatter log calls across layers, producing duplicate lines for the same failure, leaking sensitive values, and mixing business rejections with real errors. This Skill enforces a convention where only the outermost boundary (Connect interceptor, worker supervisor, external intake) logs each event exactly once, with a fixed attribute vocabulary and secret redaction. ## Core Features & Use Cases - Boundary-only logging: Defines which layers log (interceptors, supervisors) and which never do (domain, repository), with the rule "if you return it, don't log it; if you swallow it, log it." - Middleware patterns: Provides a Connect logging interceptor that recovers panics, translates errors to connect.Code, derives log level from the code, and a ctx-aware slog.Handler wrapper that adds request_id and caller attributes. - Severity and redaction rules: Supplies a level table (business rejections are Info, only unexpected failures are Error), a snake_case attribute vocabulary, and a four-point redaction strategy using primitives only, JSON handler, and ReplaceAttr. - Use Case: When asked to add logging to a Go worker that expires holds one by one, the Skill places per-item failure/success logs in the worker's Run loop while cycle-level errors return to the supervisor, verified with go vet and grep checks. ## Quick Start Apply the write-logs convention to add slog logging to my Connect interceptor and worker so each RPC is logged exactly once.

Frequently Asked Questions about write-logs

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I structure logging in a Go Connect service?▼

Place a single outermost Connect interceptor that logs each RPC once, translating returned errors to connect.Code and deriving the level from the code. Inner interceptors and server implementations only return errors and never call slog themselves.

How to avoid duplicate log lines for the same error in Go?▼

Follow the rule: if you return the error, do not log it; if you swallow it, log it. Errors returned up the stack are recorded once by the boundary interceptor, while only information that never reaches the boundary gets mid-process logs.

Should Go domain packages import log/slog?▼

No. Domain packages such as value objects, aggregates, and events must not import log/slog. They communicate outward through sentinels and transition result types, keeping logging vocabulary and redaction changes from rippling into the domain.

What log level should business rejections use in Go?▼

Business rejections like NotFound or permission denials use Info, since the system worked correctly. Only unexpected failures such as Internal codes or worker panics use Error, keeping actionable lines distinguishable from normal client failures.

How do I prevent secrets from leaking into slog output?▼

Pass only primitive values via typed helpers, never write String() on value objects, use slog.NewJSONHandler, and add a ReplaceAttr function that rewrites keys in a secretKeys set to [REDACTED] as a safety net.

When is mid-process logging allowed in a Go worker?▼

Mid-process logs are allowed only for information that never reaches the boundary: partial failures skipped with continue, individual retry attempts, per-item successful audit events, and cycle completion summaries. Cycle-wide failures return to the supervisor instead.