Skip to content
Agentmart
Submit a tool

go-instrumentation

Observability principles for Go services: structured logging, distributed tracing, metrics, context propagation, and HTTP service bootstrap.

Skill by els0r

IndexedMIT★ 1
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/els0r-go-instrumentation

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Observability principles for Go services: structured logging, distributed tracing, metrics, context propagation, and HTTP service bootstrap. Library-agnostic — the code examples use github.com/els0r/telemetry as a concrete reference implementation, but the patterns apply equally to slog + OpenTelemetry, zap, zerolog, or any equivalent stack. Use this skill whenever writing or reviewing Go code that involves logging, tracing, metrics, observability, middleware, or service bootstrap — even if the user doesn't explicitly mention "instrumentation." Also trigger when the user discusses context propagation, span creation, request latency, or error tracking.

Use cases: writing

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/go-instrumentation

What's inside

Skill name
go-instrumentation
Description
Observability principles for Go services: structured logging, distributed tracing, metrics, context propagation, and HTTP service bootstrap. Library-agnostic — the code examples use github.com/els0r/telemetry as a concrete reference implementation, but the patterns apply equally to slog + OpenTelemetry, zap, zerolog, or any equivalent stack. Use this skill whenever writing or reviewing Go code that involves logging, tracing, metrics, observability, middleware, or service bootstrap — even if the user doesn't explicitly mention "instrumentation." Also trigger when the user discusses context propagation, span creation, request latency, or error tracking.
License
MIT
Instructions
136 lines in SKILL.md · view on GitHub

Files (1)

  • SKILL.md

SKILL.md (first lines)

# Go Instrumentation

Universal patterns for instrumenting Go services. The code examples
use `github.com/els0r/telemetry` as a concrete reference
implementation; substitute the equivalent calls in your chosen stack
(slog + OpenTelemetry, zap, zerolog, ...). Pick a library, then don't
reinvent it.

## What to wire up

| Concern | Pattern | Reference impl (`els0r/telemetry`) |
|---------|---------|------------------------------------|
| Context labels | Request-scoped metadata attached to ctx (user_id, request_id) | `telemetry.WithLabels(ctx, ...)` |
| Logging | Logger that pulls labels from context automatically | `logging.FromContext(ctx)` |
| Tracing | Span helper that also emits structured logs | `spanlogging.Start()` |
| HTTP middleware | One-call middleware registration for the router | `obsgin.RegisterObservability(router, ...)` |

**Labels vs span attributes:** Labels propagate through the entire request context (correlation). Span attributes are local to a single operation (e.g., `order_id` on a processing span).

## Structured Logging

Always use structured key-value logging. Never concatenate strings.

```go
logger := logging.FromContext(ctx)
logger.Infow("user created",
    "user_id", user.ID,
    "email", user.Email,
)

// ❌ logger.Info("User " + user.Email + " created with ID " + user.ID)
```

Use consistent, lowercase, snake_case keys:

| Key | Usage |
|-----|-------|
| `user_id` | User identifier |
| `request_id` | Request correlation ID |
| `company_id` | Tenant/company identifier |
| `duration_ms` | Operation duration in milliseconds |
| `error` | Error value |

### Log Levels

| Level | When |
|-------|------|
| `Debug` | Detailed flow for local dev — never in prod hot paths |
| `Info` | Normal operations worth recording (service started, job completed) |
| `Warn` | Degraded but recoverable (retry succeeded, fallback used) |
| `Error` | Failed operation that needs attention — always include the `error` key |

**Log or return, not both.** If you return an error to the caller, don't also log it — the caller decides. Log only at the point where the error is handled (not propagated).

## Tracing

Use `spanlogging.Start()` (or your library's equivalent span helper) for operations involving downstream systems or complex logic. Don't trace trivial functions.

```go
func ProcessOrder(ctx context.Context, orderID string) error {
    ctx, span := spanlogging.Start(ctx, "order.Process")
    defer span.End()

    span.SetAttributes(attribute.String("order_id", orderID))

    if err := validate(ctx, orderID); err != nil {
        span.RecordError(err)
        return fmt.Errorf("validate order %s: %w", orderID, err)
    }
    // ...
    return nil
}
```

- Keep span names consistent: `package.Function` or `service/operation`.
- Use `span.RecordError(err)` before returning errors — it attaches the error to the trace.

## HTTP Service Bootstrap

Every Go HTTP service should wire observability from the start. The example below uses `els0r/telemetry` + Gin; the structure (init observability, register middleware, start the server) is identical for any stack.

```go
func main() {
    ctx := context.Background()

    flags := pflag.NewFlagSet("service", pflag.ExitOnError)
    obs.RegisterFlags(flags)
    flags.Parse(os.Args[1:])

    shutdown, err := obs.InitFromFlags(ctx)
    if err != nil {
        panic(err)
    }
    defer shutdown()

    router := gin.New()
    obsgin.RegisterObservability(router,
        true,  // logging middleware
        true,  // tracing middleware
        true,  // metrics middleware
        true,  // recovery middleware
        false, // verbose request body logging (disable in prod)
    )

    router.GET("/health", func(c *gin.Context) {
        c.JSON(200, gin.H{"status": "healthy"})
    })

    router.Run(":8080")
}
```

## Profiling

For pprof endpoints and production profiling, see the `go-performance` skill.

## Rules

1. **Never build custom instrumentation** when your library provides it.

From els0r/skills, MIT.

More from els0r/skills

Signals

Stars
1
Forks
0
Open issues
0
Last commit (this folder)
May 20, 2026 (5 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from els0r

Cite this page

go-instrumentation skill. Agent Mart. https://agentmart.dev/skills/els0r-go-instrumentation (last updated 2026-10-24)