Go primitives that make observability work.
What observability is
The ability to understand what a system is doing from outside it. Four signals:
- Logs, timestamped event records (what happened, where, at what level)
- Metrics, aggregate measurements over time (rate, errors, duration)
- Traces, per-request execution paths (where time went, where it failed)
- Alerts, when a signal crosses a threshold (wake someone up)
If you only have one, it's logs. If you have two, add metrics.
Go's logging surface
logstdlib is fine for CLI, lacks structure and level controllog/slog(Go 1.21+) is the default for services- JSON handler in prod
- text/tint handler in dev
slog.New(slog.NewMultiHandler(handlers...))to run both at once
- Log to
os.Stderr, neveros.Stdout(mixing logs into stdout breaks pipelines)
Multi-handler
One logger, multiple destinations. Debug tint to stderr for humans, JSON to a rotated file for aggregation.
In linko: internal/logging/logger.go:32-75.
TS equivalent: Effect Logger Multi-Writer. Logger.zip ≈ MultiHandler, Logger.layer([...]) is the array form, Effect.acquireRelease in a Layer is the close-function pattern.
Lifecycle logs
- Info log at boot
- Info log at shutdown
In linko: server.go:62, server.go:70.
Close function
If you buffer, write to a file, or send to a network, you have a resource to flush before exit.
Pattern:
Initializereturns(logger, closeFunc, err)closeFuncisdefer'd immediately on successful initcloseFuncreturns anerror: closing can fail in ways you need to know about (full disk, closed socket, truncated file). Silent failure loses the tail of your logs at exactly the moment you need them mostcloseFunccollects errors from every sub-closer witherrors.Joinand returns the joined result, so the caller sees every failure, not just the first
In linko: internal/logging/logger.go:66-72, errors.Join over all closers. Wired in main.go:57-61.
Build info
git_sha,build_time,env,hostnameon the root logger vialogger.With(...)- Binds once, every subsequent log carries them
GitSHAandBuildTimefrominternal/build/build.go(set via-ldflags)
In linko: main.go:63-68.