logr
A minimal, backend-agnostic structured logging API for Go, letting libraries log without coupling to any specific logging implementation.
Repository Health
Technical Analysis
logr defines a small, stable logging interface that Go libraries and applications can depend on without committing to a concrete logging implementation. Rather than shipping its own logging engine, logr splits the problem into two APIs: the Logger type, a value-passed struct that application and library authors call directly (Info, Error, WithValues, WithName, V), and the LogSink interface, which backend authors implement to route those calls to an actual logging framework such as zap, klog, logrus, or the standard library’s slog.
This decoupling means a library can accept and use a logr.Logger internally with almost no dependency fan-out, while the application assembling that library chooses (and can later swap) which concrete logger backs it, near main(). The package is best known as the logging abstraction underpinning Kubernetes and its controller-runtime ecosystem, where dozens of controllers and operators log through logr.Logger while cluster operators plug in whichever backend fits their observability stack.
Beyond the core interface, the module ships funcr (a formatter that turns key/value pairs into text or JSON via an arbitrary write function) and testr (a sink that routes log output through testing.T for use inside Go tests), plus first-class two-way conversion helpers (FromSlogHandler, ToSlogHandler) for interoperating with Go’s standard-library slog package.
What You Get
- A concrete, pass-by-value
Loggertype withInfo,Error,V(verbosity),WithValues, andWithNamemethods for structured key/value logging - The
LogSinkinterface contract that backend implementers fulfill, plus optional extension interfaces (CallDepthLogSink,CallStackHelperLogSink) for accurate call-site attribution - Bundled
funcrpackage for building text or JSON-formatted sinks from any write function, with support forlogr.Marshaler,fmt.Stringer, anderror - Bundled
testrpackage for routing log output throughtesting.T/testing.B, ideal for asserting on logs in unit tests - Bidirectional slog interoperability via
FromSlogHandler/ToSlogHandlerand context helpers (NewContextWithSlogLogger/FromContextAsSlogLogger) - Context propagation helpers (
NewContext/FromContext) for carrying aLoggerthroughcontext.Context - A documented, stable public API protected by CI-enforced
apidiffchecks against breaking changes
Common Use Cases
- Library authors who want to emit logs without forcing every consumer onto a specific logging framework
- Kubernetes controllers and operators built on controller-runtime, which accept
logr.Loggerthroughout their reconciliation code - Applications that want to swap logging backends (zap, klog, logrus, zerolog, slog) without touching call sites scattered across the codebase
- Projects migrating toward Go’s standard
log/slogpackage that need a bridge for code still written againstlogr.Logger - Test suites that want log output captured and asserted against
testing.Tviatestr
Under The Hood
Architecture
logr.go defines two cooperating layers: Logger, a small pass-by-value struct wrapping a LogSink and a verbosity level, and LogSink, the interface a backend must implement (Init, Enabled, Info, Error, WithValues, WithName). Every Logger method (Info, Error, V, WithValues, WithName, WithCallDepth) is a thin, nil-safe forwarder onto the sink, with optional capability interfaces (CallDepthLogSink, CallStackHelperLogSink, SlogSink) detected via type assertion so backends can opt into richer behavior (accurate call-site depth, slog compatibility) without the core interface growing. funcr.go and testr.go are self-contained LogSink implementations layered on top of this contract, demonstrating the intended extension pattern for real backends (zapr, klogr, stdr, etc., which live in sibling go-logr repos). Because Logger is a value type passed by copy, the design deliberately keeps state minimal (a sink pointer/interface plus an int) so it can be threaded through call graphs and structs cheaply.
Tech Stack
The module targets Go 1.18+ with zero non-stdlib runtime dependencies in the core package (go.mod lists only the module path and Go version). funcr and the slog bridge (sloghandler.go, context_slog.go) use only encoding/json, log/slog, reflect, and other standard-library packages. Sibling implementations (zapr, klogr, stdr, zerologr) live in separate go-logr repositories and are not dependencies of this module — logr itself stays deliberately dependency-free so it can be imported by anything without dragging in a concrete logging stack.
Code Quality
The repo has extensive test coverage: logr_test.go, context_test.go, context_slog_test.go, slogr_test.go, plus per-package tests for funcr, testr (including a fuzz test, testr_fuzz_test.go), and testing. CI (.github/workflows/tests.yaml, lint.yaml) runs the test suite and a strict golangci-lint configuration (errcheck, govet, staticcheck, revive, gocritic, dupl, and more, zero-tolerance issue limits) on every change. An apidiff.yaml workflow guards the public API against accidental breaking changes across releases, and an OpenSSF Scorecard workflow tracks supply-chain security posture. Error handling is explicit throughout — sink methods and helpers check nil sinks defensively rather than panicking.
What Makes It Unique
logr’s distinguishing choice is scope: it is intentionally just an interface, not a logging implementation, with an unusually small and stable surface area enforced by automated API-diff checks. Its two-tier Logger/LogSink split lets it stay decoupled from any backend while still supporting advanced needs (call-stack skipping for helper functions, per-callsite verbosity, marshaler-based lazy value formatting) through optional capability interfaces rather than a bloated core API. The package’s own documentation explicitly maps its design decisions against Go’s standard-library slog (adopted years later and partly inspired by logr), and ships first-class two-way conversion so codebases can migrate incrementally rather than in one break.
Used by 12 apps in this directory
agentgateway
AI Development · Developer Tools
An open source AI-native proxy that secures, observes, and governs agent-to-LLM, agent-to-tool, and agent-to-agent communication through MCP, A2A, and unified LLM routing.
Argo Workflows
Devops · Data Engineering
The most popular Kubernetes-native workflow engine for orchestrating containerized DAGs, ML pipelines, CI/CD, and parallel batch jobs at scale.
Coder
Devops · Developer Tools · Code Editors
Self-hosted cloud development environments and AI coding agents — defined in Terraform, connected via WireGuard, automatically shut down when idle.
Cozystack
Devops · Hosting Control Panel
Turn bare metal servers into a fully managed cloud platform with a single Kubernetes-native REST API.
CubeSandbox
Developer Tools · Security · AI Agents
Instant, concurrent, hardware-isolated MicroVM sandboxes for AI agents — E2B-API compatible, sub-60ms cold starts, and a built-in zero-trust egress proxy, all self-hostable at scale.
Glasskube
Developer Tools · Devops
A next-generation Kubernetes package manager with a GUI, CLI, and native GitOps integration that makes deploying cluster workloads 20x faster than Helm.
Harness Open Source
Developer Tools · Devops · Code Editors
A unified open source DevOps platform combining Git hosting, CI/CD pipelines, cloud development environments, and artifact registries in a single self-hosted system.
OpenMeter
Invoicing Finance · Developer Tools
Open-source metering and billing engine for AI, agentic, and DevTool monetization — ingest usage events in real time and turn them into accurate invoices automatically.
OpenSandbox
Developer Tools · Security
Secure, fast, and extensible sandbox runtime for AI agents with multi-language SDKs and Docker/Kubernetes runtimes.