Logging for Go (Golang): Best Solutions
Logging is one of the key tasks when developing any serious application in Go. Properly configured logging allows you to quickly find errors, analyze performance, and track system behavior in production. In this article, we will review the most popular and modern libraries for logging in Go, their strengths and weaknesses, and provide practical code examples.
Why is logging needed in Go?
Unlike simple console output, industrial logging requires:
- Structured output — output in JSON format for easy integration with log collection systems (ELK, Grafana Loki, Datadog);
- Log levels — debug, info, warn, error, fatal;
- Performance — minimal impact on application speed;
- Context — adding metadata (request ID, username, function name).
The standard log library does not support structured output and levels, so Go developers actively use third-party solutions.
1. log/slog — Standard Package in Go 1.21
Starting with Go version 1.21, the log/slog package was added to the standard library. It provides structured logging out of the box and does not require installing additional dependencies.
Advantages:
- Official support from Go developers;
- Flexible configuration via
Handler(JSON, text, custom); - Built-in levels (
Debug,Info,Warn,Error); - Support for context and attribute groups.
Usage example:
package main
import ( "log/slog" "os")
func main() { // JSON logger logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) logger.Info("Server started", "port", 8080, "env", "production")
// Text logger with Debug level textLogger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{ Level: slog.LevelDebug, })) textLogger.Debug("Connection debugging", "ip", "192.168.1.1")}If you are starting a new project on Go 1.21+, slog is the best choice for most tasks.
2. zerolog — Maximum Performance
The zerolog library (github.com/rs/zerolog) is known for its exceptional speed. It uses zero-allocation for JSON formatting, making it one of the fastest in the Go ecosystem.
Features:
- Minimal memory allocation (zero allocation);
- Log levels: trace, debug, info, warn, error, fatal, panic;
- Method chaining for adding fields;
- Support for colored console output.
Example:
package main
import ( "github.com/rs/zerolog" "github.com/rs/zerolog/log")
func main() { zerolog.TimeFieldFormat = zerolog.TimeFormatUnix log.Info().Str("service", "api").Int("status", 200).Msg("Request processed")
// Error level with stack trace log.Error().Err(err).Str("method", "GET").Msg("Request error")}When to choose zerolog: if performance is critical (high-load microservices, APIs with millions of requests).
3. zap — Powerful and Fast from Uber
The zap library (go.uber.org/zap) is another performance leader. It was developed at Uber for internal needs but has become a de facto standard for many Go projects.
Key features:
- Two modes:
Logger(slower, more convenient
Also in library
JWT tokens in TypeScript: a complete guide to working with JSON Web Tokens
Geolocation and Maps in C# (.NET): Overview of Libraries and Tools
Working with CSV in Go (Golang): A Complete Guide to encoding/csv
JWT tokens in C# (.NET): working with System.IdentityModel.Tokens.Jwt
Axios for JavaScript (Node.js): Complete Guide with Examples