golang自动轮转日志文件多策略实现插件库rollingwriter的使用
Golang自动轮转日志文件多策略实现插件库rollingwriter的使用
RollingWriter是一个自动轮转的io.Writer
实现,可以与日志记录器良好配合使用。
主要特性
- 支持多种轮转策略的自动日志轮转
- 实现了go io.Writer接口,提供并行安全的写入器
- 自动清理保留最大数量的轮转文件
- 用户可以轻松实现自己的管理器
组件结构
RollingWriter包含两个独立部分:
-
Manager:决定何时根据策略轮转文件
- WithoutRolling:不进行轮转
- TimeRolling:按时间轮转
- VolumeRolling:按文件大小轮转
-
IOWriter:实现io.Writer并执行IO写入
- Writer:非并行安全的写入器
- LockedWriter:通过锁保证并行安全
- AsyncWriter:并行安全的异步写入器
- BufferWriter:将多次写入合并为一个
file.Write()
快速开始示例
package main
import (
"github.com/arthurkiller/rollingwriter"
)
func main() {
// 配置轮转策略
config := rollingwriter.Config{
LogPath: "./logs", // 日志目录
FileName: "app.log", // 日志文件名
MaxRemain: 7, // 保留的旧日志文件最大数量
RollingPolicy: rollingwriter.TimeRolling, // 按时间轮转
RollingTimePattern: "0 0 0 * * *", // 每天午夜轮转
}
// 创建写入器
writer, err := rollingwriter.NewWriterFromConfig(&config)
if err != nil {
panic(err)
}
// 写入日志
writer.Write([]byte("hello, world\n"))
// 确保在程序退出前关闭写入器
defer writer.Close()
}
完整示例Demo
package main
import (
"log"
"time"
"github.com/arthurkiller/rollingwriter"
)
func main() {
// 配置按大小轮转的写入器
sizeConfig := rollingwriter.Config{
LogPath: "./logs",
FileName: "size_rolling.log",
MaxRemain: 5, // 保留5个旧日志文件
RollingPolicy: rollingwriter.VolumeRolling, // 按大小轮转
RollingVolume: 10 * 1024 * 1024, // 每个日志文件最大10MB
}
sizeWriter, err := rollingwriter.NewWriterFromConfig(&sizeConfig)
if err != nil {
log.Fatal(err)
}
defer sizeWriter.Close()
// 配置按时间轮转的写入器
timeConfig := rollingwriter.Config{
LogPath: "./logs",
FileName: "time_rolling.log",
MaxRemain: 7, // 保留7个旧日志文件
RollingPolicy: rollingwriter.TimeRolling, // 按时间轮转
RollingTimePattern: "0 0 12 * * *", // 每天中午12点轮转
}
timeWriter, err := rollingwriter.NewWriterFromConfig(&timeConfig)
if err != nil {
log.Fatal(err)
}
defer timeWriter.Close()
// 模拟日志写入
for i := 0; i < 1000; i++ {
msg := time.Now().Format("2006-01-02 15:04:05") + " - Log message " + string(i) + "\n"
// 写入大小轮转日志
if _, err := sizeWriter.Write([]byte(msg)); err != nil {
log.Printf("Error writing to size rolling log: %v", err)
}
// 写入时间轮转日志
if _, err := timeWriter.Write([]byte(msg)); err != nil {
log.Printf("Error writing to time rolling log: %v", err)
}
time.Sleep(time.Second)
}
}
性能基准测试
goos: darwin
goarch: amd64
pkg: github.com/arthurkiller/rollingwriter
BenchmarkWrite-4 300000 5952 ns/op 0 B/op 0 allocs/op
BenchmarkParallelWrite-4 200000 7846 ns/op 0 B/op 0 allocs/op
BenchmarkAsynWrite-4 200000 7917 ns/op 16324 B/op 1 allocs/op
BenchmarkParallelAsynWrite-4 200000 8632 ns/op 12513 B/op 1 allocs/op
BenchmarkLockedWrite-4 200000 5829 ns/op 0 B/op 0 allocs/op
BenchmarkParallelLockedWrite-4 200000 7796 ns/op 0 B/op 0 allocs/op
BenchmarkBufferWrite-4 200000 6943 ns/op 1984 B/op 4 allocs/op
BenchmarkParallelBufferWrite-4 1000000 1026 ns/op 7129 B/op 1 allocs/op
PASS
ok github.com/arthurkiller/rollingWriter 14.867s
RollingWriter提供了灵活的日志轮转解决方案,可以根据项目需求选择不同的轮转策略和写入器类型。
更多关于golang自动轮转日志文件多策略实现插件库rollingwriter的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang自动轮转日志文件多策略实现插件库rollingwriter的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang自动轮转日志文件多策略实现:rollingwriter使用指南
什么是rollingwriter
rollingwriter是一个功能强大的Golang日志轮转库,它提供了多种日志轮转策略,包括按时间、按文件大小、按文件行数等,并且支持多种压缩和归档选项。
安装
go get github.com/arthurkiller/rollingwriter
基本使用
1. 简单示例
package main
import (
"log"
"os"
"time"
"github.com/arthurkiller/rollingwriter"
)
func main() {
// 配置rollingwriter
config := rollingwriter.Config{
LogPath: "./logs", // 日志目录
TimeTagFormat: "20060102", // 时间格式
FileName: "app.log", // 基础文件名
MaxRemain: 3, // 保留的旧日志文件数量
RollingPolicy: rollingwriter.TimeRolling, // 按时间轮转
RollingTimePattern: "* * * * * *", // 每分钟轮转一次
WriterMode: "none", // 不压缩
BufferWriterThershould: 8 * 1024, // 8KB缓冲区
}
// 创建writer
writer, err := rollingwriter.NewWriterFromConfig(&config)
if err != nil {
log.Fatal(err)
}
// 设置log输出
log.SetOutput(writer)
// 模拟日志输出
for i := 0; i < 100; i++ {
log.Printf("This is a test log message %d", i)
time.Sleep(time.Second)
}
}
多种轮转策略
1. 按时间轮转
config := rollingwriter.Config{
LogPath: "./logs",
TimeTagFormat: "20060102",
FileName: "time_rotate.log",
MaxRemain: 7, // 保留7天的日志
RollingPolicy: rollingwriter.TimeRolling,
RollingTimePattern: "0 0 0 * * *", // 每天午夜轮转
}
2. 按文件大小轮转
config := rollingwriter.Config{
LogPath: "./logs",
TimeTagFormat: "20060102",
FileName: "size_rotate.log",
MaxRemain: 10, // 保留10个旧日志文件
RollingPolicy: rollingwriter.VolumeRolling,
RollingVolumeSize: "100MB", // 每个日志文件最大100MB
}
3. 按文件行数轮转
config := rollingwriter.Config{
LogPath: "./logs",
TimeTagFormat: "20060102",
FileName: "line_rotate.log",
MaxRemain: 5, // 保留5个旧日志文件
RollingPolicy: rollingwriter.LineRolling,
RollingLine: 100000, // 每10万行轮转一次
}
高级配置
1. 压缩轮转后的日志
config := rollingwriter.Config{
LogPath: "./logs",
FileName: "compressed.log",
RollingPolicy: rollingwriter.VolumeRolling,
RollingVolumeSize: "50MB",
WriterMode: "lock", // 使用lock模式
Compress: true, // 启用压缩
CompressSuffix: ".gz", // 压缩后缀
}
2. 异步写入
config := rollingwriter.Config{
LogPath: "./logs",
FileName: "async.log",
RollingPolicy: rollingwriter.VolumeRolling,
RollingVolumeSize: "100MB",
Async: true, // 启用异步写入
BufferSize: 4096, // 缓冲区大小
}
3. 自定义文件名格式
config := rollingwriter.Config{
LogPath: "./logs",
FileName: "custom",
TimeTagFormat: "2006-01-02-15-04-05",
RollingPolicy: rollingwriter.TimeRolling,
RollingTimePattern: "* * * * * *", // 每分钟轮转
MaxRemain: 60, // 保留60个文件
}
最佳实践
1. 与标准log包集成
func setupLogger() {
config := rollingwriter.Config{
LogPath: "./logs",
FileName: "app.log",
RollingPolicy: rollingwriter.TimeRolling,
RollingTimePattern: "0 0 0 * * *", // 每天轮转
MaxRemain: 7,
Async: true,
}
writer, err := rollingwriter.NewWriterFromConfig(&config)
if err != nil {
panic(err)
}
log.SetOutput(writer)
log.SetFlags(log.LstdFlags | log.Lshortfile)
}
2. 与logrus集成
import (
"github.com/sirupsen/logrus"
"github.com/arthurkiller/rollingwriter"
)
func setupLogrus() *logrus.Logger {
config := rollingwriter.Config{
LogPath: "./logs",
FileName: "logrus.log",
RollingPolicy: rollingwriter.VolumeRolling,
RollingVolumeSize: "100MB",
MaxRemain: 10,
}
writer, err := rollingwriter.NewWriterFromConfig(&config)
if err != nil {
panic(err)
}
logger := logrus.New()
logger.SetOutput(writer)
logger.SetFormatter(&logrus.JSONFormatter{})
return logger
}
注意事项
- 确保日志目录有写入权限
- 合理设置MaxRemain参数,避免磁盘空间被占满
- 生产环境中建议启用异步写入以提高性能
- 对于高频日志,考虑使用缓冲区减少IO操作
rollingwriter提供了灵活且强大的日志轮转功能,可以根据实际需求组合不同的策略和选项,是Golang项目中管理日志文件的优秀选择。