
Golang Samber Slog
Compose production-grade Go structured logging with correct handler order, PII scrubbing, sampling, and error routing to Sentry.
Overview
golang-samber-slog is an agent skill for the Build phase that composes samber slog-multi pipelines with sampling-first ordering, PII scrubbing, and Sentry routing for Go services.
Install
npx skills add https://github.com/samber/cc-skills-golang --skill golang-samber-slogWhat is this skill?
- Places slog-sampling first so dropped records do not waste CPU on formatters or routers
- Uses slog-formatter (PIIFormatter / FormatByKey) for email and other sensitive field masking
- Routes ERROR and above to Sentry via slogmulti.Router or Fanout
- Explains Router (all matching rules) vs FirstMatch (single destination per record)
- Eval-backed traps for pipeline ordering and router semantics without custom sampling code
- Eval scenarios assert sampling as outermost handler before formatting
Adoption & trust: 3.4k installs on skills.sh; 2k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your Go service logs too much, leaks PII, or burns CPU because sampling and multi-destination routing are wired in the wrong order or with the wrong Router semantics.
Who is it for?
Solo builders adding Sentry, sampling, and GDPR-style field masking to an existing samber/slog stack without rewriting logging from scratch.
Skip if: Teams that only need default slog.TextHandler to stdout with no routers, scrubbers, or external log sinks.
When should I use this skill?
You are composing or refactoring a Go slog handler chain with sampling, PII masking, or Sentry and need correct samber library order and Router behavior.
What do I get? / Deliverables
You get a documented handler chain with sampling outermost, formatter-based scrubbing, and correct Fanout or FirstMatch routing ready to paste into production init code.
- Complete handler composition code
- Short rationale for pipeline order and router mode
Recommended Skills
Journey fit
How it compares
Library-specific procedural knowledge for samber slog-multi—not a generic “use structured logging” chat tip or an MCP observability server.
Common Questions / FAQ
Who is golang-samber-slog for?
Go indie developers and small teams shipping APIs or workers who use samber’s slog extensions and want agents to assemble pipelines correctly on the first try.
When should I use golang-samber-slog?
During Build when you add logging middleware, before Ship when you tune sampling for production volume, or in Operate when duplicate ERROR routes to Slack and PagerDuty need a FirstMatch fix.
Is golang-samber-slog safe to install?
Review the Security Audits panel on this Prism page and inspect the skill package in your repo before granting network-related agent permissions for Sentry endpoints.
SKILL.md
READMESKILL.md - Golang Samber Slog
[ { "id": 1, "name": "pipeline-ordering", "description": "Tests whether the model places sampling first in the pipeline (before formatting)", "prompt": "Set up a slog pipeline in Go using samber/slog libraries with PII scrubbing (mask email fields), error routing to Sentry, and log sampling at 10%. Show the complete handler composition using slog-multi, slog-sampling, and slog-formatter.", "trap": "Without the skill, the model places sampling last (after formatting) or in the middle, wasting CPU on records that get dropped", "assertions": [ {"id": "1.1", "text": "Sampling is the outermost/first handler in the pipeline (applied before formatting)"}, {"id": "1.2", "text": "Uses slog-sampling library (slogsampling) for sampling, not custom code"}, {"id": "1.3", "text": "Uses slog-formatter for PII scrubbing (PIIFormatter or FormatByKey)"}, {"id": "1.4", "text": "Uses slogmulti.Router or Fanout for routing to Sentry"}, {"id": "1.5", "text": "Explains or demonstrates why sampling should be first (avoid wasted CPU on dropped records)"} ] }, { "id": 2, "name": "router-firstmatch-vs-router-all-matches", "description": "Tests whether the model distinguishes Router (all matching) from Router+FirstMatch (first match only)", "prompt": "I have a slog-multi Router with two rules: (1) ERROR and above → PagerDuty, (2) WARN and above → Slack. My problem: ERROR logs are going to BOTH PagerDuty AND Slack. I only want errors in PagerDuty, not duplicated in Slack. How do I fix this with slog-multi?", "trap": "Without the skill, the model adds a LevelIs(slog.LevelWarn) predicate to the Slack handler thinking that fixes it — but WARN and above includes ERROR, so errors still reach Slack. The correct fix is Router().Add(...).FirstMatch() so routing stops at the first matching handler.", "assertions": [ {"id": "2.1", "text": "Identifies that the default Router sends to ALL matching handlers (both Slack and PagerDuty match for ERROR)"}, {"id": "2.2", "text": "Recommends using .FirstMatch() on the Router to stop at the first matching handler"}, {"id": "2.3", "text": "Does NOT suggest just changing Slack's predicate to LevelIs(slog.LevelWarn) as the complete fix (errors still match WARN-and-above)"}, {"id": "2.4", "text": "Shows the correct Router().Add(pagerduty, LevelIs(ERROR)).Add(slack, LevelIs(WARN)).FirstMatch().Handler() pattern"}, {"id": "2.5", "text": "Explains the semantic difference: Router routes to ALL matches, FirstMatch routes to FIRST match only"} ] }, { "id": 3, "name": "missing-close-batch", "description": "Tests whether the model remembers to call Close() on batch handlers", "prompt": "Set up slog to send logs to Datadog using samber/slog-datadog in a Go HTTP server with graceful shutdown. Show the complete main() function.", "trap": "Without the skill, the model forgets to close the handler on shutdown, causing buffered logs to be lost", "assertions": [ {"id": "3.1", "text": "Calls handler.Stop(ctx) or defer handler.Stop(ctx) for the Datadog handler (not Close)"}, {"id": "3.2", "text": "Uses Option{}.NewDatadogHandler() constructor pattern"}, {"id": "3.3", "text": "Close happens during graceful shutdown (signal handling or defer in main)"}, {"id": "3.4", "text": "Mentions or demonstrates that Datadog handler batches logs (data loss risk without Close)"}, {"id": "3.5", "text": "Import path is github.com/samber/slog-datadog/v2 or later"} ] }, { "id": 4, "name": "sampling-matcher-grouping", "description": "Tests whether the model understands slog-sampling Matchers for deduplication grouping", "prompt": "I've set up ThresholdSamplingOption in my Go service: log the first 10 per 5s, then sample at 10%. It works, but I notice that 'user not found' (DEBUG) and 'cache miss' (DEBUG) are being counted together in the same bucket. After 10 total