> ## Content Index
> Fetch the complete content index at: https://huizhou92.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# An Analysis of Mainstream Go Logging Libraries：Learning How to Integrate Log Rotation and Segmentation Functionality from a Design Perspective
- URL: https://huizhou92.com/an-analysis-of-mainstream-go-logging-libraries-learning-how-to-integrate-log-rotation-and-segmentation-functionality-from-a-design-perspective/
- Published: 2024-06-28T10:21:48.000Z
- Updated: 2026-09-06T11:38:58.000Z
- Author: huizhou92
- Tags: tech, golang, #lang-en

In existing logging libraries, including the `slog` logging library introduced in `go` 1.21.0, typically support log file rotation and segmentation. However, these functionalities are not built-in directly but require manual configuration to enable.

> This article was first published in the Medium MPP plan. If you are a Medium user, please follow me on [Medium](https://medium.huizhou92.com/?ref=huizhou92.com). Thank you very much.

This article will explore several popular logging libraries, such as `Logrus`, `zap`, and the official `Slog`. I will analyze the key design elements of these libraries and discuss how they support the configuration of log rotation and segmentation functionalities.

Are you ready? Grab a cup of your favorite coffee or tea, and let's dive into the exploration.

## Analysis of logrus, zap, and slog Designs

When comparing and analyzing the designs of the `logrus`, `zap`, and `slog` logging libraries, a notable commonality is that they all include the crucial attribute `io.Writer`. This attribute plays a central role in the design of logging frameworks as it determines the destination of log output.

## logrus Logging Library

`logrus` is a feature-rich Go logging library that provides structured logging and log level control.

When using `logrus`, you can create a `Logger` instance by calling the `logrus.New()` function. Through this instance, you can perform various operations such as customizing the log output location and printing logs. Take a look at the following code:

```go
logger := logrus.New()
logger.Out = os.Stdout // stdout
// or redirects to file
//out, err := os.OpenFile("file.log", os.O_CREATE|os.O_WRONLY, 0666)
//if err != nil {
// panic(err)
//}
//logger.Out = out

```

The definition of the `Logger` struct is as follows:

```go
type Logger struct {
    Out       io.Writer
    Hooks     LevelHooks
    Formatter Formatter
    // other fields...
}

```

The key attribute `Out`, of type `io.Writer`, is used to specify the output destination of the logs, whether it's standard output, a file, or any other custom output medium.

## zap Logging Library

`zap` is a high-performance logging library that provides structured logging, multi-level log control, and flexible configuration options.

Similar to `logrus`, `zap` also allows configuring the log output location through settings. However, the implementation approach is slightly different. In `zap`, log output is achieved through the configuration of `zapcore.Core`. When creating an instance of `zapcore.Core`, you need to specify a `zapcore.WriteSyncer` interface implementation as a parameter, which directly determines the log's output destination. To create a `zapcore.WriteSyncer` instance, the `zapcore.AddSync()` function is commonly used, which takes a parameter of type `io.Writer`.

Here's a basic example of creating a log instance using `zap`:

```go
writer := zapcore.AddSync(os.Stdout) // use stdout
core := zapcore.NewCore(
    zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()),
    writer,
    zap.InfoLevel,
)
logger := zap.New(core)
defer logger.Sync() // Flush any buffered log entries

// use logger

```

The key lies in the `zapcore.AddSync()` function, which takes a parameter of type `io.Writer`. This parameter is used to specify the log's output destination, whether it's standard output, a file, or any other custom output medium.

## slog Logging Library

`slog` is an official logging library introduced in `go 1.21.0`, providing structured logging. If you want to learn more about the `slog` logging library,

Similar to `logrus` and `zap`, `slog` also allows users to set the log output destination by specifying an `io.Writer` parameter when creating an implementation of `slog.Handler`.

```go
textLogger := slog.New(slog.NewTextHandler(os.Stdout, nil))
jsonLogger := slog.New(slog.NewJSONHandler(os.Stdout, nil))

```

In both of these functions, the first parameter of `slog.NewTextHandler` and `slog.NewJSONHandler` is of type `io.Writer`.

## Summary of the Analysis

In the analysis of the three mainstream logging libraries, `logrus`, `zap`, and `slog`, we can identify a crucial commonality: they all rely on the `io.Writer` interface when handling log output. These logging libraries use the `io.Writer` interface as a key parameter type to set the log's output destination.

![Pasted image 20240212220811](https://images.yixiao9206.cn/blog-images/2024/02/f3e3b50c2247e4d57f5b0946497fbba8.png)

# Mechanism and Practice of Log Rotation and Segmentation Functionality

## Mechanism of Implementation

After analyzing the designs of the `logrus`, `zap`, and `slog` logging libraries, we have discovered their commonalities. Now, let's delve into the mechanism of log rotation and segmentation functionality.

To implement log file rotation and segmentation, we typically rely on third-party libraries such as `lumberjack`. There are other similar libraries available, but we won't list them all here.

`lumberjack` is a library specifically designed for log rotation and segmentation. Its role can be likened to a pluggable component. By configuring this component and integrating it into the chosen logging library, we can achieve log file rotation and segmentation functionality.

The code for initializing the `lumberjack` component is as follows:

```go
log := &lumberjack.Logger{
    Filename:   "/path/file.log", // location of the log file
    MaxSize:    10,               // Maximum file size (in MB)
    MaxBackups: 3,                // Maximum number of old files to keep
    MaxAge:     28,               // Maximum number of days to retain old files
    Compress:   true,             // whether to compress/archive old files
    LocalTime:  true,             // create timestamps using local time
}

```

In this example, we create a `lumberjack.Logger` instance and set the following parameters:

- `Filename`: Specifies the storage path of the log file.
- `MaxSize`: Triggers log rotation when the log file reaches a certain size in MB.
- `MaxBackups`: Specifies the maximum number of old log files to keep.
- `MaxAge`: Sets the maximum number of days to retain old log files.
- `Compress`: Determines whether to compress/archive old log files (e.g., convert them to `.gz`).
- `LocalTime`: Creates timestamps using local time.

It's important to note that the `Logger` struct of `lumberjack` implements the `io.Writer` interface. This means that all the core logic related to log file rotation and segmentation is encapsulated in the `Write` method. This implementation also allows the `Logger` struct to be integrated into any logging library that supports the `io.Writer` parameter.

Now that we understand these details, you should have a good understanding of how to implement log rotation and segmentation functionality. Since the `Logger` struct of `lumberjack` implements the `io.Writer` interface, you can pass it to third-party libraries for seamless integration and configuration.

## Practice

### Implementation with logrus Logging Library

```go
log := &lumberjack.Logger{
    Filename:   "/path/file.log", // location of log file
    MaxSize:    10,               // Maximum file size in MB
    MaxBackups: 3,                // Maximum number of old files to keep
    MaxAge:     28,               // Maximum number of days to retain old files
    Compress:   true,             // whether to compress/archive old files
    LocalTime:  true,             // create timestamps using local time
}
logger := logrus.New()
logger.Out = log

```

### Implementation with zap Logging Library

```go
log := &lumberjack.Logger{
    Filename:   "/path/file.log", // location of log file
    MaxSize:    10,               // Maximum file size in MB
    MaxBackups: 3,                // Maximum number of old files to keep
    MaxAge:     28,               // Maximum number of days to retain old files
    Compress:   true,             // whether to compress/archive old files
    LocalTime:  true,             // create timestamps using local time
}
writer := zapcore.AddSync(log)
core := zapcore.NewCore(
    zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()),
    writer,
    zap.InfoLevel,
)
logger := zap.New(core)
defer logger.Sync() // Flush any buffered log entries

```

### Implementation with slog Logging Library

```go
log := &lumberjack.Logger{
    Filename:   "/path/file.log", // location of log file
    MaxSize:    10,               // Maximum file size (in MB)
    MaxBackups: 3,                // Maximum number of old files retained
    MaxAge:     28,               // Maximum number of days to keep old files
    Compress:   true,             // Whether to compress/archive old files
    LocalTime:  true,             // Create a timestamp with local time
}
textLogger := slog.New(slog.NewTextHandler(log, nil))
jsonLogger := slog.New(slog.NewJSONHandler(log, nil))

```

In this article, we have analyzed the design elements of the three popular logging libraries, `logrus`, `zap`, and `slog`. Although they have differences in the details of creating log instances, they all rely on the `io.Writer` interface parameter to handle log output. By mastering how to configure the `io.Writer` parameter and combining it with the use of the `lumberjack` library, we can achieve log file rotation and segmentation functionality.

Even if new logging libraries are introduced in the future, we can quickly integrate log file rotation and segmentation functionality using similar methods.