Golang Logging Libraries in 2024
Logging in Golang is an essential aspect of software development, as it helps developers monitor, troubleshoot, and analyze the behavior of their applications.
Standard library log
Go's standard library includes a basic logging package called log
. It provides a simple way to log messages to the console:
package main
import (
"log"
)
func main() {
log.Println("This is a log message")
}
However, the standard log
package is minimalistic and may not be suitable for more complex logging requirements, such as log rotation, log levels, or log formatting.
Standard library slog
Recently, the Go standard library introduced a new logging package called slog
that brings structured logging to the standard library. Structured logs use key-value pairs so they can be parsed, filtered, searched, and analyzed quickly and reliably.
The slog
package provides a more advanced logging functionality than the log package, and it is recommended for use in production environments.
Here is an example of how to use the slog
package for logging in Go:
package main
import (
"os"
"log/slog"
)
func main() {
textHandler := slog.NewTextHandler(os.Stdout)
logger := slog.New(textHandler)
logger.Info("Usage Statistics",
slog.Int("current-memory", 50),
slog.Int("min-memory", 20),
slog.Int("max-memory", 80),
slog.Int("cpu", 10),
slog.String("app-version", "v0.0.1-beta"),
)
}
To log to a file using the slog
package in Go, you can use the slog.NewJSONHandler
function to create a new handler that writes logs to a file in JSON format. Here is an example:
package main
import (
"os"
"log/slog"
)
func main() {
file, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
panic(err)
}
defer file.Close()
jsonHandler := slog.NewJSONHandler(file)
logger := slog.New(jsonHandler)
logger.Info("Application started",
slog.String("app-version", "v0.0.1-beta"),
)
}
If you're using slog for logging in your Go application and you also want to leverage OpenTelemetry for distributed tracing, then OpenTelemetry slog is a valuable tool to consider.
Logrus
To handle more advanced logging needs, many developers turn to third-party logging libraries. One popular choice is "logrus," which provides a more feature-rich logging experience. You can install it using:
go get github.com/sirupsen/logrus
Here's an example of how to use the Logrus library:
package main
import (
"github.com/sirupsen/logrus"
)
func main() {
// Create a new logger instance
log := logrus.New()
// Set the log level (optional)
log.SetLevel(logrus.InfoLevel)
// Log messages
log.WithFields(logrus.Fields{
"animal": "walrus",
}).Info("A walrus appears")
}
Logrus offers features like structured logging, log levels, custom formatters, and more.
Logrus is a highly extensible logging library and can be integrated with various monitoring tools. For example, OpenTelemetry Logrus is a plugin that provides integration with OpenTelemetry.
Zap
Another popular logging library in the Go ecosystem is Zap. which is known for its high performance and structured logging capabilities. You can install it using:
go get go.uber.org/zap
Here's a basic example of how to use Zap:
package main
import (
"go.uber.org/zap"
)
func main() {
// Create a logger
logger, _ := zap.NewProduction()
// Log messages
logger.Info("This is an info message", zap.String("key", "value"))
}
Zap allows for efficient logging with minimal allocation and has a rich set of features.
You can integrate Zap with OpenTelemetry using the OpenTelemetry Zap plugin.
Zerolog
Zerolog is a fast and simple structured logger. It focuses on reducing allocations and providing a clean API for structured logging. It's suitable for both basic and advanced logging needs.
go get github.com/rs/zerolog
Here's a basic example of using Zerolog to log messages:
package main
import (
"os"
"github.com/rs/zerolog"
)
func main() {
// Create a new logger instance
logger := zerolog.New(os.Stdout).With().Timestamp().Logger()
// Log messages
logger.Info().Str("key", "value").Msg("This is an info message")
logger.Error().Err(fmt.Errorf("An error occurred")).Msg("This is an error message")
}
Best practices
Effective logging is a balance between providing enough information to troubleshoot issues and avoiding information overload. Adjust your logging practices based on the specific requirements and constraints of your application and organization.
Structured Logging. Adopt structured logging, which allows you to attach key-value pairs or structured data to log entries. This makes it easier to filter and analyze logs in a structured way.
Log Levels. Utilize log levels (e.g., INFO
, DEBUG
, WARN
, ERROR
) to categorize log messages. This allows you to control the verbosity of your logs and focus on relevant information during debugging or troubleshooting.
Contextual Information. Include relevant contextual information in your log messages. For example, include request IDs, user IDs, and timestamps. This helps when tracing issues across components.
Error Wrapping. When logging errors, use error wrapping to preserve the original error context. You can use packages like "github.com/pkg/errors" or the built-in "fmt.Errorf" for this purpose.
Monitoring and Alerting. Set up monitoring and alerting for your application's logs. Use tools like Uptrace or Grafana to create dashboards and set up alerts based on log patterns.
Logs monitoring
Uptrace is an open source APM for OpenTelemetry that supports distributed tracing, metrics, and logs. You can use it to monitor applications and troubleshoot issues.
Uptrace comes with an intuitive query builder, rich dashboards, alerting rules, notifications, and integrations for most languages and frameworks.
Uptrace can process billions of spans and metrics on a single server and allows you to monitor your applications at 10x lower cost.
In just a few minutes, you can try Uptrace by visiting the cloud demo (no login required) or running it locally with Docker. The source code is available on GitHub.
Conclusion
Choose a logging approach based on your application's requirements and complexity. Third-party libraries like Logrus and Zap are recommended for most projects, as they provide robust features and are well-maintained by the community.
Recently, the Go standard library introduced a new logging package called slog
that brings structured logging to the standard library and is recommended for use in production environments.
Keep in mind that the choice of a logging library may depend on the size and complexity of your project. For smaller projects, a simple and easy-to-use logger may be sufficient, while larger and more complex projects may benefit from a more feature-rich and performant logging library.