# logrotatex
**Repository Path**: MM-Q/logrotatex
## Basic Information
- **Project Name**: logrotatex
- **Description**: LogRotateX 是一个专为 Go 语言设计的高性能日志轮转库,基于 natefinch/lumberjack 进行深度优化和功能扩展。它可以与任何支持 io.Writer 接口的日志库无缝集成,自动管理日志文件的大小、数量和保留时间,为您的应用提供可靠的日志管理解决方案。
- **Primary Language**: Go
- **License**: MIT
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2025-04-29
- **Last Updated**: 2026-04-08
## Categories & Tags
**Categories**: Uncategorized
**Tags**: Go语言
## README
# 🔄 LogRotateX - Go 日志轮转工具
[](https://golang.org)
[](LICENSE)
[](https://gitee.com/MM-Q/logrotatex/releases)
[](https://goreportcard.com/report/gitee.com/MM-Q/logrotatex)
[](APIDOC.md)
**高性能、线程安全的 Go 日志轮转库,提供完整的日志文件管理功能**
[🚀 快速开始](#-快速开始) • [📖 文档](APIDOC.md) • [💡 示例](#-使用示例) • [🤝 贡献](#-贡献指南) • [📄 许可证](#-许可证)
---
## 📋 项目简介
LogRotateX 是一个专为 Go 语言设计的高性能日志轮转库,基于 [natefinch/lumberjack](https://github.com/natefinch/lumberjack) 进行深度优化和功能扩展。它可以与任何支持 `io.Writer` 接口的日志库无缝集成,自动管理日志文件的大小、数量和保留时间,为您的应用提供可靠的日志管理解决方案。
## ✨ 核心特性
|
### 🔄 智能轮转管理
- 📁 **自动日志轮转** - 基于文件大小智能轮转
- � **按天轮转** - 支持每天自动轮转,跨天时触发
- �️ **多重清理策略** - 按数量和时间双重管理
- 🗜️ **多格式压缩支持** - 支持8种压缩格式(zip、tar、tgz、tar.gz、gz、bz2、bzip2、zlib)节省存储空间
- ⏱️ **灵活时间格式** - 支持本地时间/UTC时间
|
### 🛡️ 安全与性能
- 🔒 **路径安全验证** - 防止路径遍历攻击
- 🚀 **高并发支持** - 线程安全的并发写入
- 📊 **性能优化** - O(n)文件扫描算法
- 🎯 **简化初始化** - 便捷的构造函数
|
|
### 🚀 缓冲写入器 (BufferedWriter)
- 📦 **批量写入** - 双重触发条件智能刷新(缓冲区大小、刷新间隔)
- ⚡ **性能提升** - 减少系统调用开销,提升写入性能
- 🔧 **通用设计** - 支持 io.WriteCloser,且提供 WrapWriter 适配 io.Writer;提供 NewStdoutBW 便捷函数
- ⏱️ **定时刷新器** - 内置定时器协程,确保数据及时写入,防止缓冲区长时间未刷新
- 🛡️ **错误恢复** - 定时器协程内置 panic 恢复机制,保障服务稳定运行
- 🎯 **智能控制** - 原子变量状态管理,支持运行时动态关闭检测
|
### 🌟 主要优势
| 特性 | 描述 | 优势 |
|------|------|------|
| 🔌 **无缝集成** | 实现 `io.Writer` 接口 | 兼容所有主流日志库 |
| ⚡ **高性能** | 优化的文件操作算法 | 支持高频日志写入场景 |
| 🚀 **缓冲写入** | 带缓冲批量写入器 + 定时刷新器 | 显著提升写入性能,减少系统调用,确保数据及时写入 |
| 📅 **按天轮转** | 支持每天自动轮转 | 满足日志按天归档需求 |
| �️ **多格式压缩** | 支持8种压缩格式(zip、tar、tgz、tar.gz、gz、bz2、bzip2、zlib) | 灵活选择压缩方式,平衡压缩率和性能 |
| �️ **企业级安全** | 多层安全防护机制 | 防止安全漏洞和攻击 |
| 🔧 **灵活配置** | 丰富的配置选项 | 适应各种使用场景 |
| 📈 **生产就绪** | 经过充分测试验证 | 可直接用于生产环境 |
## 📦 安装指南
### 🚀 从仓库安装
```bash
# 安装最新版本
go get gitee.com/MM-Q/logrotatex
# 安装指定版本
go get gitee.com/MM-Q/logrotatex@v1.0.0
# 更新到最新版本
go get -u gitee.com/MM-Q/logrotatex
```
### 📋 系统要求
| 项目 | 要求 |
|------|------|
| **Go 版本** | 1.25.0+ |
| **操作系统** | Linux, macOS, Windows |
| **架构** | amd64, arm64 |
| **依赖** | 无外部依赖 |
### ✅ 安装验证
```bash
# 创建测试文件
cat > test_install.go << 'EOF'
package main
import (
"fmt"
"gitee.com/MM-Q/logrotatex"
)
func main() {
logger := logrotatex.NewLogRotateX("test.log")
defer logger.Close()
logger.Write([]byte("安装成功!\n"))
fmt.Println("LogRotateX 安装验证成功!")
}
EOF
# 运行测试
go run test_install.go
```
## 🚀 快速开始
### 🎯 30秒快速体验
```go
package main
import (
"log"
"gitee.com/MM-Q/logrotatex"
)
func main() {
// 一行代码创建日志轮转器
logger := logrotatex.NewLogRotateX("logs/app.log")
defer logger.Close()
// 开始使用
logger.Write([]byte("Hello LogRotateX! 🎉\n"))
}
```
### 🚀 最简配置
```go
package main
import (
"log"
"gitee.com/MM-Q/logrotatex"
)
func main() {
// 使用默认配置,一行代码搞定
logger := logrotatex.Default()
defer logger.Close()
// 设置为标准日志输出
log.SetOutput(logger)
// 直接使用
log.Println("使用默认配置的日志消息")
}
```
**默认配置特性**:
- 日志文件路径:`logs/app.log`
- 按天轮转:每天自动轮转一次
- 日期目录:轮转后的日志存放在 `YYYY-MM-DD/` 目录下
- 文件大小:10MB 达到限制时也会轮转
- 本地时间:使用本地时间记录轮转时间
- 同步清理:清理操作同步执行(可改为异步)
## 💡 使用示例
### 📝 基础用法
🔧 推荐配置(点击展开)
```go
package main
import (
"log"
"gitee.com/MM-Q/logrotatex"
)
func main() {
// 使用构造函数创建(推荐方式)
logger := logrotatex.NewLogRotateX("logs/app.log")
defer logger.Close()
// 生产环境推荐配置
logger.MaxSize = 100 // 100MB - 避免单文件过大
logger.MaxFiles = 10 // 保留10个历史文件 - 控制磁盘使用
logger.MaxAge = 30 // 保留30天 - 满足审计要求
logger.Compress = true // 启用压缩 - 节省存储空间
// 设置为标准日志输出
log.SetOutput(logger)
// 直接使用Write接口写入日志
logger.Write([]byte("应用启动成功
"))
// 或者通过标准log包写入(内部调用Write方法)
log.SetOutput(logger)
log.Println("这条日志会通过Write方法写入")
}
```
⚙️ 默认配置使用(点击展开)
```go
package main
import (
"log"
"gitee.com/MM-Q/logrotatex"
)
func main() {
// 使用默认配置,适合快速开发和小型应用
logger := logrotatex.Default()
defer logger.Close()
// 默认配置已经包含按天轮转和日期目录功能
// 如需调整,可以修改特定配置
logger.MaxSize = 50 // 调整为50MB
logger.Compress = true // 启用压缩节省空间
// 设置为标准日志输出
log.SetOutput(logger)
log.Println("使用默认配置的日志消息")
}
```
**默认配置说明**:
- **Async**: false - 清理操作同步执行
- **MaxSize**: 10MB - 文件大小限制
- **MaxAge**: 0 - 不按时间清理
- **MaxFiles**: 0 - 不按数量清理
- **LocalTime**: true - 使用本地时间
- **Compress**: false - 不压缩
- **DateDirLayout**: true - 按日期目录存放
- **RotateByDay**: true - 按天轮转
- **CompressType**: zip - 默认压缩格式
📅 按天轮转配置(点击展开)
```go
package main
import (
"log"
"gitee.com/MM-Q/logrotatex"
)
func main() {
// 使用构造函数创建
logger := logrotatex.NewLogRotateX("logs/app.log")
defer logger.Close()
// 启用按天轮转
logger.RotateByDay = true // 每天自动轮转一次
// 可以同时设置按大小轮转
logger.MaxSize = 100 // 100MB - 文件大小达到限制时也会轮转
logger.MaxFiles = 10 // 保留10个历史文件
logger.MaxAge = 30 // 保留30天
// 设置为标准日志输出
log.SetOutput(logger)
// 日志会每天自动轮转,跨天时触发
log.Println("这条日志会在跨天时自动轮转")
}
```
**按天轮转特性:**
- **自动轮转**:每天自动轮转一次,跨天时触发
- **双重触发**:可以同时设置按大小轮转,满足任一条件即轮转
- **时间控制**:支持 `LocalTime` 配置,使用本地时间或 UTC 时间
- **灵活组合**:可与 `DateDirLayout` 组合使用,按日期目录存放备份文件
⚙️ 手动配置方式(点击展开)
```go
package main
import "gitee.com/MM-Q/logrotatex"
func main() {
// 完全自定义配置
logger := &logrotatex.LogRotateX{
LogFilePath: "logs/custom.log",
MaxSize: 50, // 50MB
MaxFiles: 5, // 保留5个历史文件
MaxAge: 14, // 保留14天
LocalTime: true, // 使用本地时间
Compress: true, // 启用压缩
CompressType: comprx.CompressTypeZip, // 压缩类型,默认为zip格式
FilePerm: 0644, // 自定义文件权限
}
defer logger.Close()
// 直接写入
logger.Write([]byte("自定义配置的日志消息\n"))
}
```
### 🚀 高性能缓冲写入
⚡ 缓冲写入器基础用法(点击展开)
```go
package main
import (
"log"
"gitee.com/MM-Q/logrotatex"
)
func main() {
// 创建日志轮转器
logger := logrotatex.NewLogRotateX("logs/app.log")
// 创建缓冲写入器,显著提升性能
buffered := logrotatex.NewBufferedWriter(logger, logrotatex.DefBufCfg()) // 使用默认配置
defer buffered.Close()
// 高性能批量写入
for i := 0; i < 1000; i++ {
buffered.Write([]byte("高性能日志消息
"))
}
// 自动批量刷新,减少系统调用
}
```
🔧 自定义缓冲配置(点击展开)
```go
package main
import (
"gitee.com/MM-Q/logrotatex"
"time"
)
func main() {
// 创建日志轮转器
logger := logrotatex.NewLogRotateX("logs/app.log")
// 自定义缓冲配置
config := &logrotatex.BufCfg{
MaxBufferSize: 128 * 1024, // 128KB 缓冲区
FlushInterval: 500 * time.Millisecond, // 500ms 刷新间隔(最小间隔)
}
// 创建缓冲写入器
buffered := logrotatex.NewBufferedWriter(logger, config)
defer buffered.Close()
// 高频写入场景
for i := 0; i < 10000; i++ {
buffered.Write([]byte("大量日志数据写入测试
"))
}
// 手动刷新缓冲区
buffered.Flush()
}
```
⚙️ 默认缓冲配置(点击展开)
```go
package main
import (
"log"
"gitee.com/MM-Q/logrotatex"
)
func main() {
// 方式1:使用 DefaultBufferedWriter,需要传入一个 io.WriteCloser
logger := logrotatex.NewLogRotateX("logs/app.log")
defer logger.Close()
buffered := logrotatex.DefaultBufferedWriter(logger)
defer buffered.Close()
log.SetOutput(buffered)
log.Println("使用 DefaultBufferedWriter 的日志消息")
// 方式2:使用 DefaultBuffered,内部自动创建 LogRotateX
buffered2 := logrotatex.DefaultBuffered()
defer buffered2.Close()
// 可以直接使用,无需创建 LogRotateX
buffered2.Write([]byte("使用 DefaultBuffered 的日志消息\n"))
}
```
**两种默认方式的区别**:
- **DefaultBufferedWriter**:需要传入一个 `io.WriteCloser`,适用于已有日志写入器的场景
- **DefaultBuffered**:内部自动创建默认配置的 `LogRotateX`,适用于快速开始场景
**BufferedWriter 默认配置**:
- **缓冲区大小**:256KB - 平衡内存使用和刷新频率
- **刷新间隔**:1秒 - 内置定时刷新器,确保数据及时写入,最小间隔500ms
📊 性能监控示例(点击展开)
```go
package main
import (
"fmt"
"time"
"gitee.com/MM-Q/logrotatex"
)
func main() {
logger := logrotatex.NewLogRotateX("logs/app.log")
buffered := logrotatex.NewBufferedWriter(logger, nil)
defer buffered.Close()
// 性能测试
start := time.Now()
for i := 0; i < 50000; i++ {
buffered.Write([]byte("性能测试日志消息
"))
// 每10000条检查状态
if (i+1)%10000 == 0 {
fmt.Printf("已写入 %d 条,缓冲区大小: %d 字节\n",
i+1, buffered.BufferSize())
}
}
elapsed := time.Since(start)
fmt.Printf("写入50000条日志耗时: %v
", elapsed)
}
```
⏱️ 定时刷新器特性(点击展开)
```go
package main
import (
"log"
"time"
"gitee.com/MM-Q/logrotatex"
)
func main() {
// 创建日志轮转器
logger := logrotatex.NewLogRotateX("logs/app.log")
// 创建缓冲写入器,使用定时刷新器确保数据及时写入
// 定时器会在后台定期检查并刷新缓冲区,防止数据长时间滞留
buffered := logrotatex.NewBufferedWriter(logger, logrotatex.DefBufCfg())
defer buffered.Close()
// 设置标准日志输出到缓冲写入器
log.SetOutput(buffered)
// 模拟长时间运行的服务
for i := 0; i < 10; i++ {
log.Printf("服务运行中 - 第 %d 次心跳\n", i+1)
// 模拟低频率写入场景
// 定时刷新器会确保这些数据及时写入磁盘,即使未达到缓冲区触发条件
time.Sleep(2 * time.Second)
}
// 程序结束时,Close() 会确保所有数据被刷新
log.Println("服务正常退出")
}
```
**定时刷新器优势:**
- **数据安全性**:防止缓冲区数据长时间未刷新,确保重要日志及时落盘
- **低延迟保证**:即使写入频率很低,也能通过定时器保证数据及时性
- **后台自动运行**:无需手动干预,定时器协程在后台自动管理刷新逻辑
- **错误恢复机制**:内置 panic 恢复,保障定时器协程稳定运行
- **优雅关闭**:支持运行时状态检测,关闭时立即停止定时器并刷新剩余数据
🖥️ 终端输出缓冲(stdout)(点击展开)
```go
package main
import (
"os"
"time"
"gitee.com/MM-Q/logrotatex"
)
func main() {
// 终端输出缓冲:减少频繁写入 stdout
cfg := &logrotatex.BufCfg{
MaxBufferSize: 32 * 1024, // 32KB 缓冲区
FlushInterval: 500 * time.Millisecond, // 500ms 刷新间隔(最小间隔)
}
bw := logrotatex.NewStdoutBW(cfg)
defer bw.Close() // 安全关闭缓冲器,不会关闭 stdout
_, _ = bw.Write([]byte("hello stdout buffered
"))
// 也可结合 WrapWriter 适配任意 io.Writer
// wc := logrotatex.WrapWriter(os.Stdout)
// bw := logrotatex.NewBufferedWriter(wc, cfg)
}
```
### 🔌 与主流项目结合
📊 Logrus 集成示例(点击展开)
```go
package main
import (
"fmt"
"github.com/sirupsen/logrus"
"gitee.com/MM-Q/logrotatex"
)
func main() {
// 创建轮转器
rotator := logrotatex.NewLogRotateX("logs/app.log")
rotator.MaxFiles = 5
rotator.Compress = true
defer rotator.Close()
// 配置 logrus
logrus.SetOutput(rotator)
logrus.SetFormatter(&logrus.JSONFormatter{
TimestampFormat: "2006-01-02 15:04:05",
})
logrus.SetLevel(logrus.InfoLevel)
// 使用结构化日志
logrus.WithFields(logrus.Fields{
"service": "user-api",
"version": "v1.2.3",
}).Info("服务启动成功")
logrus.WithError(fmt.Errorf("示例错误")).Error("错误日志示例")
}
```
⚡ Zap 集成示例(点击展开)
```go
package main
import (
"fmt"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gitee.com/MM-Q/logrotatex"
)
func setupZapLogger() *zap.Logger {
// 创建轮转器
rotator := logrotatex.NewLogRotateX("logs/app.log")
rotator.MaxSize = 10
rotator.MaxAge = 30
rotator.Compress = true
// 配置编码器
encoderConfig := zap.NewProductionEncoderConfig()
encoderConfig.TimeKey = "timestamp"
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
// 创建核心
core := zapcore.NewCore(
zapcore.NewJSONEncoder(encoderConfig),
zapcore.AddSync(rotator),
zapcore.InfoLevel,
)
return zap.New(core, zap.AddCaller(), zap.AddStacktrace(zapcore.ErrorLevel))
}
func main() {
logger := setupZapLogger()
defer logger.Sync()
// 使用结构化日志
logger.Info("应用启动",
zap.String("service", "user-api"),
zap.String("version", "v1.2.3"),
zap.Int("port", 8080),
)
logger.Error("数据库连接失败",
zap.String("database", "mysql"),
zap.String("host", "localhost:3306"),
zap.Error(fmt.Errorf("connection timeout")),
)
}
```
🌐 Gin 集成示例(点击展开)
```go
package main
import (
"github.com/gin-gonic/gin"
"gitee.com/MM-Q/logrotatex"
)
func main() {
// 创建日志轮转器
logger := logrotatex.Default()
defer logger.Close()
// 设置Gin的默认写入器
gin.DefaultWriter = logger
// 创建Gin引擎
r := gin.Default()
// 使用默认的中间件,日志会自动写入到LogRotateX
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
// 启动服务器
r.Run(":8080")
}
```
**Gin集成优势:**
- **无缝集成**:通过设置`gin.DefaultWriter`,所有Gin的日志输出都会自动写入LogRotateX
- **自动轮转**:日志文件会根据配置自动轮转,无需手动管理
- **性能优化**:可以结合BufferedWriter进一步提升性能
- **生产就绪**:适合生产环境使用,自动管理日志文件大小和数量
**高级用法(结合BufferedWriter):**
```go
package main
import (
"github.com/gin-gonic/gin"
"gitee.com/MM-Q/logrotatex"
)
func main() {
// 使用 DefaultBuffered 创建缓冲写入器,内部自动创建 LogRotateX
buffered := logrotatex.DefaultBuffered()
defer buffered.Close()
// 设置Gin的默认写入器为缓冲写入器
gin.DefaultWriter = buffered
// 创建Gin引擎
r := gin.Default()
// 所有Gin日志会先写入缓冲区,然后批量写入文件
r.GET("/api/users", func(c *gin.Context) {
c.JSON(200, gin.H{"users": []string{"user1", "user2"}})
})
r.Run(":8080")
}
```
### 🔧 高级用法示例
🗜️ 压缩类型配置(点击展开)
```go
package main
import (
"log"
"gitee.com/MM-Q/logrotatex"
"gitee.com/MM-Q/comprx"
)
func main() {
// 创建日志轮转器
logger := logrotatex.NewLogRotateX("logs/app.log")
defer logger.Close()
// 启用压缩
logger.Compress = true
// 设置压缩类型(默认为 zip)
logger.CompressType = comprx.CompressTypeZip
// 支持的压缩格式:
// - comprx.CompressTypeZip: zip 压缩格式(默认)
// - comprx.CompressTypeTar: tar 压缩格式
// - comprx.CompressTypeTgz: tgz 压缩格式
// - comprx.CompressTypeTarGz: tar.gz 压缩格式
// - comprx.CompressTypeGz: gz 压缩格式
// - comprx.CompressTypeBz2: bz2 压缩格式
// - comprx.CompressTypeBzip2: bzip2 压缩格式
// - comprx.CompressTypeZlib: zlib 压缩格式
// 设置为标准日志输出
log.SetOutput(logger)
// 写入日志,轮转后会使用指定的压缩格式
log.Println("这条日志会在轮转后使用zip格式压缩")
}
```
**压缩类型说明:**
- **zip格式**:兼容性好,支持多文件,适合大多数场景
- **tar格式**:不压缩,仅打包,适合需要快速访问的场景
- **tgz/tar.gz格式**:压缩率高,适合长期存储
- **gz格式**:单文件压缩,简单高效
- **bz2/bzip2格式**:压缩率更高,但速度较慢
- **zlib格式**:内存友好,适合流式处理
🎛️ 运行时控制(点击展开)
```go
package main
import (
"fmt"
"log"
"time"
"gitee.com/MM-Q/logrotatex"
)
func main() {
logger := logrotatex.NewLogRotateX("logs/app.log")
logger.MaxSize = 1 // 1MB,便于测试
defer logger.Close()
log.SetOutput(logger)
// 获取状态信息
fmt.Printf("当前文件: %s\n", logger.CurrentFile())
fmt.Printf("当前大小: %d 字节\n", logger.GetCurrentSize())
fmt.Printf("最大大小: %d 字节\n", logger.GetMaxSize())
// 写入大量日志触发轮转
for i := 0; i < 1000; i++ {
log.Printf("这是第 %d 条日志消息,时间: %s", i+1, time.Now().Format("2006-01-02 15:04:05"))
// 每100条检查一次状态
if (i+1)%100 == 0 {
fmt.Printf("已写入 %d 条,当前文件大小: %d 字节\n", i+1, logger.GetCurrentSize())
}
}
// 强制同步到磁盘
if err := logger.Sync(); err != nil {
log.Printf("同步失败: %v", err)
}
}
```
## 📖 文档
- 详细 API、功能/格式与配置项请参见 [APIDOC.md](APIDOC.md)
### 🎯 推荐配置场景
| 场景 | 配置 | 说明 |
|------|------|------|
| 🏢 **企业生产环境** | `logger := logrotatex.NewLogRotateX("logs/production.log")`
`logger.MaxSize = 100`
`logger.MaxFiles = 30`
`logger.MaxAge = 90`
`logger.Compress = true` | 100MB - 平衡性能和管理
30个历史文件 - 满足审计要求
90天 - 符合合规要求
启用压缩 - 节省存储 |
| 🔬 **开发测试环境** | `logger := logrotatex.NewLogRotateX("logs/dev.log")`
`logger.MaxSize = 10`
`logger.MaxFiles = 3`
`logger.MaxAge = 7`
`logger.Compress = false` | 10MB - 快速轮转便于测试
3个历史文件 - 节省空间
7天 - 短期保留
不压缩 - 便于查看 |
| ☁️ **云原生环境** | `logger := logrotatex.NewLogRotateX("logs/cloud.log")`
`logger.MaxSize = 50`
`logger.MaxFiles = 5`
`logger.MaxAge = 14`
`logger.Compress = true` | 50MB - 适合容器环境
5个历史文件 - 控制存储使用
14天 - 配合日志收集系统
启用压缩 - 减少网络传输 |
| 📅 **按天归档环境** | `logger := logrotatex.NewLogRotateX("logs/daily.log")`
`logger.RotateByDay = true`
`logger.MaxSize = 100`
`logger.MaxFiles = 30`
`logger.MaxAge = 90`
`logger.Compress = true`
`logger.DateDirLayout = true` | 启用按天轮转 - 每天自动归档
100MB - 文件大小达到限制时也会轮转
30个历史文件 - 保留30天的日志
90天 - 长期保留
启用压缩 - 节省存储空间
启用日期目录 - 按日期目录存放备份文件 |
## 🧪 测试说明
### 🚀 运行测试
```bash
# 运行所有测试
go test -v ./...
# 运行单元测试
go test -v ./tests -run TestUnit
# 运行集成测试
go test -v ./tests -run TestIntegration
# 运行性能测试
go test -bench=. -benchmem ./tests
# 生成测试覆盖率报告
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html
```
### 📊 测试覆盖范围
| 测试类型 | 覆盖范围 | 测试文件 |
|----------|----------|----------|
| **单元测试** | 核心功能逻辑 | `*_test.go` |
| **集成测试** | 端到端场景 | `integration_test.go` |
| **性能测试** | 性能基准 | `benchmark_test.go` |
| **并发测试** | 线程安全性 | `concurrent_test.go` |
### ✅ 测试场景
🔧 功能测试场景
- ✅ 基本写入操作
- ✅ 文件轮转触发
- ✅ 备份文件管理
- ✅ 压缩功能验证
- ✅ 权限设置检查
- ✅ 错误处理验证
- ✅ 边界条件测试
🚀 性能测试场景
- ✅ 高频写入性能
- ✅ 大文件处理能力
- ✅ 内存使用效率
- ✅ 并发写入性能
- ✅ 轮转操作耗时
- ✅ 压缩操作性能
🛡️ 安全测试场景
- ✅ 路径遍历攻击防护
- ✅ 文件权限验证
- ✅ 符号链接检查
- ✅ 恶意文件名过滤
- ✅ 资源泄漏检测
## 🏆 最佳实践
### 1. 🏢 生产环境配置
```go
logger := logrotatex.NewLogRotateX("logs/app.log")
logger.MaxSize = 100 // 100MB,避免单文件过大
logger.MaxFiles = 10 // 保留10个历史文件,控制磁盘使用
logger.MaxAge = 30 // 保留30天,满足审计要求
logger.Compress = true // 启用压缩,节省存储空间
```
### 2. 🚀 高并发场景
```go
// 创建全局日志实例
var globalLogger *logrotatex.LogRotateX
func init() {
globalLogger = logrotatex.NewLogRotateX("logs/app.log")
globalLogger.MaxSize = 50
globalLogger.MaxFiles = 5
globalLogger.Compress = true
// 设置为标准日志输出
log.SetOutput(globalLogger)
}
// 在程序退出时清理
func cleanup() {
if globalLogger != nil {
globalLogger.Close()
}
}
```
### 3. 🛡️ 错误处理
```go
logger := logrotatex.NewLogRotateX("logs/app.log")
defer func() {
if err := logger.Close(); err != nil {
log.Printf("关闭日志文件失败: %v", err)
}
}()
// 写入时检查错误
if _, err := logger.Write([]byte("日志消息\n")); err != nil {
log.Printf("写入日志失败: %v", err)
}
```
### 4. 📊 监控和告警
```go
// 定期检查日志文件状态
func monitorLogFile(logger *logrotatex.LogRotateX) {
ticker := time.NewTicker(5 * time.Minute)
defer ticker.Stop()
for range ticker.C {
currentSize := logger.GetCurrentSize()
maxSize := logger.GetMaxSize()
// 当文件大小接近限制时发出告警
if float64(currentSize)/float64(maxSize) > 0.8 {
log.Printf("警告: 日志文件大小接近限制 (%d/%d)", currentSize, maxSize)
}
}
}
```
## 🐛 故障排除
### ❓ 常见问题
Q: 日志文件没有按预期轮转?
**A: 检查以下几点:**
- ✅ 文件权限是否正确
- ✅ 磁盘空间是否充足
- ✅ MaxSize 设置是否合理
- ✅ 是否有其他进程占用文件
```bash
# 检查文件权限
ls -la logs/
# 检查磁盘空间
df -h
# 检查进程占用
lsof logs/app.log
```
Q: 压缩功能不工作?
**A: 确认以下设置:**
- ✅ `Compress` 字段设置为 `true`
- ✅ 有足够的磁盘空间进行压缩操作
- ✅ 检查系统日志中的错误信息
```go
// 启用详细错误日志
logger.Compress = true
logger.CompressType = comprx.CompressTypeZip // 设置压缩类型
if err := logger.Rotate(); err != nil {
log.Printf("轮转失败: %v", err)
}
```
Q: 如何选择合适的压缩类型?
**A: 根据场景选择压缩类型:**
- **zip格式**:兼容性好,支持多文件,适合大多数场景
- **tar格式**:不压缩,仅打包,适合需要快速访问的场景
- **tgz/tar.gz格式**:压缩率高,适合长期存储
- **gz格式**:单文件压缩,简单高效
- **bz2/bzip2格式**:压缩率更高,但速度较慢
- **zlib格式**:内存友好,适合流式处理
```go
// 高性能场景:使用gz格式
logger.Compress = true
logger.CompressType = comprx.CompressTypeGz
// 高压缩率场景:使用bz2格式
logger.Compress = true
logger.CompressType = comprx.CompressTypeBz2
// 兼容性优先:使用zip格式(默认)
logger.Compress = true
logger.CompressType = comprx.CompressTypeZip // 可省略,默认值
```
Q: 备份文件没有被清理?
**A: 检查配置:**
- ✅ `MaxSize` 和 `MaxAge` 的设置
- ✅ 文件名格式是否符合预期
- ✅ 目录权限是否允许删除操作
```go
// 调试清理逻辑
logger.MaxFiles = 5 // 明确设置历史文件数量
logger.MaxAge = 7 // 明确设置保留天数
```
### 🔧 调试技巧
1. **启用详细日志**:在测试环境中使用详细输出
2. **检查文件权限**:确保程序有足够权限
3. **监控文件句柄**:使用系统工具监控资源使用
4. **测试轮转逻辑**:使用小的 `MaxSize` 值快速测试
## 🤝 贡献指南
我们欢迎社区贡献!参与项目开发请遵循以下流程:
### 🚀 开发环境设置
```bash
# 1. Fork 并克隆仓库
git clone https://gitee.com/MM-Q/logrotatex.git
cd logrotatex
# 2. 创建开发分支
git checkout -b feature/your-feature-name
# 3. 安装开发依赖
go mod tidy
# 4. 运行测试确保环境正常
go test -v ./...
```
### 📋 提交要求
| 要求 | 说明 |
|------|------|
| ✅ **代码质量** | 通过 `gofmt`、`golint` 检查 |
| ✅ **测试覆盖** | 新功能必须包含测试用例 |
| ✅ **文档更新** | 更新相关文档和示例 |
| ✅ **提交信息** | 使用清晰的提交信息格式 |
### 🔄 提交流程
```bash
# 1. 提交代码
git add .
git commit -m "feat: 添加新功能描述"
# 2. 推送到远程分支
git push origin feature/your-feature-name
# 3. 创建 Pull Request
# 在 Gitee 上创建 PR,详细描述变更内容
```
### 📊 代码规范
- 遵循 Go 官方代码规范
- 使用有意义的变量和函数名
- 添加必要的注释和文档
- 保持代码简洁和可读性
## 📄 许可证
本项目采用 **MIT 许可证** - 详见 [LICENSE](LICENSE) 文件
## 🙏 致谢
本项目基于 [natefinch/lumberjack](https://github.com/natefinch/lumberjack) 库的 v2 分支进行开发和扩展。我们对原作者 **Nate Finch** 及其团队的杰出工作表示诚挚的感谢!
### 🌟 主要改进
- 🔧 **构造函数支持** - 添加了 `NewLogRotateX()` 构造函数
- 🛡️ **增强安全特性** - 内置路径安全验证机制
- 📊 **性能优化** - 优化文件扫描算法和内存使用
- 🗜️ **多格式压缩** - 支持8种压缩格式(zip、tar、tgz、tar.gz、gz、bz2、bzip2、zlib),提供灵活的压缩选择
- 🔒 **权限控制** - 增加文件权限配置选项
- 🚀 **缓冲写入器** - 新增高性能批量写入功能,三重触发条件智能刷新
- 🌐 **本地化支持** - 提供中文文档和本地化体验
### 📚 原始项目信息
| 项目信息 | 详情 |
|----------|------|
| **原项目地址** | https://github.com/natefinch/lumberjack |
| **原作者** | Nate Finch |
| **基于分支** | v2 |
| **原项目许可** | MIT License |
## 🔗 相关链接
### 📚 文档与资源
[](APIDOC.md)
[](docs/design.md)
[](docs/performance.md)
### 🌐 项目链接
[](https://gitee.com/MM-Q/logrotatex)
[](https://gitee.com/MM-Q/logrotatex/issues)
[](https://gitee.com/MM-Q/logrotatex/issues/new)
### 🤝 社区支持
[](https://gitee.com/MM-Q/logrotatex/discussions)
[](#-贡献指南)
[](CODE_OF_CONDUCT.md)
---
**🔄 LogRotateX** - 让日志管理变得简单高效! 🚀
*如果这个项目对您有帮助,请给我们一个 ⭐ Star!*
[](https://gitee.com/MM-Q/logrotatex)