Logini - 开箱即用的 Go 日志库

基于 logrus 封装的简单易用的日志库,只需一个配置文件即可使用,无需编写任何初始化代码。
📑 目录
✨ 特性
- 📝 配置文件驱动 - 开箱即用,一行代码完成初始化
- 🖥️ 双端输出 - 同时支持控制台和文件输出
- 🔄 自动轮转 - 日志文件按大小、时间、数量自动轮转
- 📊 多级别日志 - 支持 trace、debug、info、warn、error、fatal、panic
- ✅ Success 日志 - 内置绿色成功日志,便于标记成功操作
- 🎨 多种格式 - 支持 JSON 和 Text 格式输出
- 🏗️ 结构化日志 - 完整的结构化日志支持
- 🗜️ 自动压缩 - 旧日志文件自动 gzip 压缩
- 🔒 线程安全 - 并发环境下安全使用
- 🎨 彩色输出 - 支持终端彩色日志显示
📦 安装
方法 1: 直接安装(推荐)
go get gitee.com/yjx2320674897/logini
方法 2: 配置 GOPROXY(国内加速)
# 配置环境
go env -w GOPRIVATE=gitee.com
go env -w GOPROXY=https://goproxy.cn,direct
# 安装
go get gitee.com/yjx2320674897/logini
方法 3: 在 go.mod 中指定
require gitee.com/yjx2320674897/logini v1.0.2
⚠️ 注意:Gitee 需要配置 GOPRIVATE=gitee.com,详见 FIX_GITEE_GO_GET.md
🚀 快速开始
1️⃣ 创建配置文件
在项目根目录创建 config.yaml:
level: info
format: text
console: true
report_caller: false
force_colors: true
file:
enable: true
path: ./logs/app.log
max_size: 100
max_backups: 3
max_age: 7
compress: true
2️⃣ 在代码中使用
package main
import "gitee.com/yjx2320674897/logini"
func main() {
// 初始化(只需一行!)
mylogger.MustInit("config.yaml")
// 开始使用
mylogger.Info("应用程序启动")
mylogger.Success("初始化成功")
mylogger.Warn("这是一条警告")
mylogger.Error("这是一条错误")
}
3️⃣ 运行
go run main.go
输出(彩色显示):
time="2026-01-12 20:30:45" level=info msg="应用程序启动"
time="2026-01-12 20:30:45" level=info msg="初始化成功" status=success
time="2026-01-12 20:30:45" level=warning msg="这是一条警告"
time="2026-01-12 20:30:45" level=error msg="这是一条错误"
📖 详细使用说明
基本用法
1. 简单日志输出
mylogger.Trace("跟踪信息") // 跟踪级别(最详细)
mylogger.Debug("调试信息") // 调试级别
mylogger.Info("普通信息") // 信息级别
mylogger.Success("成功信息") // 成功级别(Info 级别,带 success 标记)
mylogger.Warn("警告信息") // 警告级别
mylogger.Error("错误信息") // 错误级别
2. 格式化输出
name := "张三"
age := 25
mylogger.Infof("用户 %s 的年龄是 %d", name, age)
mylogger.Successf("用户 %s 注册成功", name)
// 输出: 用户 张三 的年龄是 25
// 输出: level=info msg="用户 张三 注册成功" status=success
3. 结构化日志(⭐ 推荐)
import "github.com/sirupsen/logrus"
mylogger.WithFields(logrus.Fields{
"user_id": 12345,
"action": "login",
"ip": "192.168.1.1",
}).Info("用户登录成功")
// 输出: level=info msg="用户登录成功" action=login ip=192.168.1.1 user_id=12345
4. 错误处理
result, err := database.Query()
if err != nil {
mylogger.WithError(err).Error("数据库查询失败")
return
}
mylogger.Info("查询成功")
5. 链式调用
mylogger.WithField("request_id", "abc-123").
WithField("user_id", 456).
WithField("method", "GET").
Info("处理HTTP请求")
高级用法
1. 获取 Logger 实例
// 获取原始 logrus.Logger 实例
logger := mylogger.GetLogger()
// 使用 logrus 的所有高级功能
logger.WithFields(logrus.Fields{
"component": "database",
}).Info("执行查询")
2. 多环境配置
import "os"
func init() {
env := os.Getenv("APP_ENV")
if env == "" {
env = "dev"
}
configFile := fmt.Sprintf("config.%s.yaml", env)
mylogger.MustInit(configFile)
}
运行:
# 开发环境
go run main.go
# 生产环境
APP_ENV=prod go run main.go
3. 使用代码配置
config := mylogger.DefaultConfig()
config.Level = "debug"
config.Format = "json"
config.File.Path = "/var/log/myapp.log"
mylogger.InitWithConfig(config)
✅ 适用场景
1. Web 应用程序
适合:HTTP 服务器、RESTful API、Web 框架
func handleRequest(w http.ResponseWriter, r *http.Request) {
mylogger.WithFields(logrus.Fields{
"method": r.Method,
"path": r.URL.Path,
"ip": r.RemoteAddr,
}).Info("收到请求")
// 处理逻辑...
}
为什么适合:
- ✅ 自动记录请求信息
- ✅ 结构化日志便于分析
- ✅ 线程安全,支持高并发
2. 微服务
适合:服务间调用、API 网关、消息队列
func processMessage(msg Message) {
logger := mylogger.WithFields(logrus.Fields{
"service": "payment",
"trace_id": msg.TraceID,
})
logger.Info("开始处理消息")
// 处理逻辑...
logger.Info("消息处理完成")
}
为什么适合:
- ✅ 支持 trace_id 追踪
- ✅ JSON 格式便于日志收集
- ✅ 文件轮转防止磁盘满
3. 后台任务/定时任务
适合:Cron 任务、数据同步、批处理
func cronJob() {
mylogger.Info("定时任务开始")
// 执行任务...
mylogger.WithField("count", processedCount).Info("任务完成")
}
为什么适合:
- ✅ 自动记录执行时间
- ✅ 错误日志便于排查
- ✅ 历史日志自动归档
4. CLI 工具
适合:命令行工具、脚本程序
func main() {
mylogger.MustInit("config.yaml")
mylogger.Info("开始执行任务")
// 执行逻辑...
mylogger.Info("任务执行完成")
}
为什么适合:
- ✅ 配置简单,一行初始化
- ✅ 控制台输出带颜色
- ✅ 可选择性记录到文件
5. 数据处理程序
适合:ETL、数据分析、数据清洗
func processData(data []Record) {
mylogger.WithField("total", len(data)).Info("开始处理数据")
for i, record := range data {
if err := process(record); err != nil {
mylogger.WithFields(logrus.Fields{
"index": i,
"record_id": record.ID,
}).WithError(err).Error("处理失败")
}
}
mylogger.Info("数据处理完成")
}
为什么适合:
- ✅ 详细记录处理进度
- ✅ 错误日志便于重试
- ✅ 统计信息一目了然
6. 长运行服务
适合:守护进程、监控服务、消息消费者
func main() {
mylogger.MustInit("config.yaml")
mylogger.Info("服务启动")
for {
if err := doWork(); err != nil {
mylogger.WithError(err).Error("工作失败")
time.Sleep(5 * time.Second)
continue
}
}
}
为什么适合:
- ✅ 日志自动轮转,不会占满磁盘
- ✅ 压缩旧日志节省空间
- ✅ 线程安全,并发无忧
⚠️ 不适用场景
1. 超高性能要求场景
不适合:每秒百万级日志、超低延迟系统
原因:
- ❌ logrus 相比 zerolog/zap 性能较低
- ❌ 文件 I/O 会影响性能
- ❌ 结构化日志有序列化开销
替代方案:使用 zerolog 或 zap
2. 需要复杂日志路由
不适合:不同日志级别写入不同文件、动态日志路由
原因:
- ❌ 本库简化设计,只支持单一输出配置
- ❌ 不支持基于条件的日志分发
替代方案:直接使用 logrus + 自定义 Hook
3. 需要日志采样
不适合:需要对高频日志进行采样
原因:
替代方案:使用 zap 的采样功能
4. 嵌入式系统/IoT 设备
不适合:内存受限的设备、嵌入式 Linux
原因:
- ❌ 依赖较多(logrus + lumberjack + yaml)
- ❌ 内存占用相对较高
替代方案:使用轻量级日志库或标准库
5. 浏览器/前端应用
不适合:WebAssembly、前端 Go 应用
原因:
替代方案:使用浏览器 console API
6. 需要实时日志聚合
不适合:直接发送日志到 ELK、Kafka 等
原因:
- ❌ 默认只支持文件和控制台输出
- ❌ 需要自己实现 Hook
替代方案:
- 使用 filebeat 收集日志文件
- 或自定义 logrus Hook
⚙️ 配置说明
完整配置选项
# 日志级别
level: info # trace, debug, info, warn, error, fatal, panic
# 输出格式
format: text # text 或 json
# 控制台输出
console: true # true 或 false
# 调用者信息(文件名和行号)
report_caller: false # 建议关闭
# 强制显示颜色
force_colors: true # 仅 text 格式有效
# 文件输出
file:
enable: true # 是否启用
path: ./logs/app.log # 文件路径
max_size: 100 # 单文件最大 MB
max_backups: 3 # 保留文件数
max_age: 7 # 保留天数
compress: true # 是否压缩
日志级别说明
| 级别 |
颜色 |
说明 |
使用场景 |
输出内容 |
trace |
⚪ 灰色 |
最详细 |
追踪代码执行流程 |
trace + debug + info + warn + error + fatal + panic |
debug |
⚪ 灰色 |
调试信息 |
开发环境调试 |
debug + info + warn + error + fatal + panic |
info |
🟢 绿色 |
一般信息 |
正常业务流程 |
info + warn + error + fatal + panic |
success |
🟢 绿色✨ |
成功信息 |
标记成功操作 |
info 级别,带 status=success 标记 |
warn |
🟡 黄色 |
警告信息 |
需要注意但不影响运行 |
warn + error + fatal + panic |
error |
🔴 红色 |
错误信息 |
发生错误但程序继续 |
error + fatal + panic |
fatal |
🔴 红色 |
致命错误 |
程序无法继续,调用 os.Exit(1) |
fatal + panic |
panic |
🔴 红色 |
严重错误 |
触发 panic() |
panic |
💡 提示:Success 方法基于 Info 级别,额外添加 status=success 字段,便于日志分析和搜索。
输出格式对比
Text 格式
time="2026-01-12 20:30:45" level=info msg="用户登录" user_id=123
- ✅ 人类易读
- ✅ 开发环境友好
- ✅ 支持彩色输出
- ❌ 不便于程序解析
JSON 格式
{"level":"info","msg":"用户登录","time":"2026-01-12 20:30:45","user_id":123}
- ✅ 便于程序解析
- ✅ 适合日志收集系统
- ✅ 生产环境推荐
- ❌ 人类不易直接阅读
🎯 实际应用案例
案例 1: RESTful API 服务
package main
import (
"net/http"
"time"
"gitee.com/yjx2320674897/logini"
"github.com/sirupsen/logrus"
)
func main() {
mylogger.MustInit("config.yaml")
mylogger.Success("API 服务启动成功")
http.HandleFunc("/api/users", loggingMiddleware(handleUsers))
http.ListenAndServe(":8080", nil)
}
// 日志中间件
func loggingMiddleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
// 记录请求信息
logger := mylogger.WithFields(logrus.Fields{
"method": r.Method,
"path": r.URL.Path,
"ip": r.RemoteAddr,
})
logger.Info("收到请求")
// 处理请求
next(w, r)
// 记录响应时间
logger.WithField("duration_ms", time.Since(start).Milliseconds()).
Info("请求完成")
mylogger.Success("请求处理成功")
}
}
func handleUsers(w http.ResponseWriter, r *http.Request) {
// 业务逻辑...
}
案例 2: 数据库操作
package database
import (
"database/sql"
"gitee.com/yjx2320674897/logini"
"github.com/sirupsen/logrus"
)
type UserRepo struct {
db *sql.DB
}
func (r *UserRepo) GetUser(id int) (*User, error) {
logger := mylogger.WithFields(logrus.Fields{
"component": "database",
"operation": "GetUser",
"user_id": id,
})
logger.Debug("开始查询用户")
var user User
err := r.db.QueryRow("SELECT * FROM users WHERE id = ?", id).Scan(&user)
if err != nil {
logger.WithError(err).Error("查询用户失败")
return nil, err
}
logger.Info("查询用户成功")
mylogger.Successf("用户 %d 查询成功", id)
return &user, nil
}
案例 3: 后台任务处理
package worker
import (
"time"
"gitee.com/yjx2320674897/logini"
)
func StartWorker() {
mylogger.Info("后台任务启动")
ticker := time.NewTicker(5 * time.Minute)
defer ticker.Stop()
for range ticker.C {
processJob()
}
}
func processJob() {
mylogger.WithField("job", "cleanup").Info("开始执行任务")
start := time.Now()
count, err := cleanupOldData()
if err != nil {
mylogger.WithError(err).Error("任务执行失败")
return
}
mylogger.WithFields(logrus.Fields{
"deleted_count": count,
"duration_sec": time.Since(start).Seconds(),
}).Info("任务执行完成")
}
案例 4: 消息队列消费者
package consumer
import (
"encoding/json"
"gitee.com/yjx2320674897/logini"
"github.com/sirupsen/logrus"
)
type MessageConsumer struct {
queue Queue
}
func (c *MessageConsumer) Start() {
mylogger.Info("消息消费者启动")
for msg := range c.queue.Messages() {
c.processMessage(msg)
}
}
func (c *MessageConsumer) processMessage(msg Message) {
logger := mylogger.WithFields(logrus.Fields{
"message_id": msg.ID,
"topic": msg.Topic,
})
logger.Info("开始处理消息")
var data PaymentData
if err := json.Unmarshal(msg.Body, &data); err != nil {
logger.WithError(err).Error("消息解析失败")
return
}
if err := c.handlePayment(data); err != nil {
logger.WithError(err).Error("处理失败")
return
}
logger.Info("消息处理成功")
}
⚡ 性能考虑
性能影响因素
-
日志级别
debug/trace 级别会输出大量日志
- 生产环境建议使用
info 或 warn
-
输出目标
- 控制台输出:较慢
- 文件输出:中等
- 仅内存:最快(不支持)
-
格式化
- JSON 格式:序列化有开销
- Text 格式:稍快
- 结构化字段:增加序列化时间
-
ReportCaller
- 开启后会获取调用栈信息
- 性能影响约 20-40%
- 建议关闭
性能优化建议
1. 合理设置日志级别
# 开发环境
level: debug
# 生产环境
level: info # 或 warn
2. 关闭不必要的功能
report_caller: false # 关闭调用者信息
force_colors: false # 生产环境关闭颜色
3. 条件日志
// ❌ 不推荐:总是执行昂贵的操作
mylogger.Debugf("数据: %s", expensiveOperation())
// ✅ 推荐:先检查级别
if mylogger.GetLogger().IsLevelEnabled(logrus.DebugLevel) {
mylogger.Debugf("数据: %s", expensiveOperation())
}
4. 使用结构化日志而非格式化字符串
// ❌ 较慢
mylogger.Infof("用户 %d 执行了 %s 操作", userID, action)
// ✅ 更快
mylogger.WithFields(logrus.Fields{
"user_id": userID,
"action": action,
}).Info("用户操作")
性能基准
在普通服务器上(Intel i5,SSD):
| 场景 |
每秒日志量 |
CPU 占用 |
| 纯控制台输出 |
~50k |
低 |
| 文件输出 |
~20k |
中 |
| JSON + 文件 |
~15k |
中 |
| ReportCaller 开启 |
~8k |
高 |
⚠️ 实际性能取决于硬件、日志内容、并发量等因素
🎓 最佳实践
1. 初始化位置
✅ 推荐:在 main 函数或 init 函数中
func main() {
mylogger.MustInit("config.yaml")
// 之后的代码都可以使用
}
或
func init() {
mylogger.MustInit("config.yaml")
}
❌ 不推荐:在每个函数中初始化
func someFunc() {
mylogger.MustInit("config.yaml") // ❌ 重复初始化
mylogger.Info("test")
}
2. 日志级别选择
// ✅ 跟踪信息(最详细)
mylogger.Trace("进入函数 processOrder")
// ✅ 调试信息
mylogger.Debug("变量值:", value)
// ✅ 正常流程
mylogger.Info("用户登录")
// ✅ 成功操作(推荐用于标记成功)
mylogger.Success("用户登录成功")
// ✅ 警告信息
mylogger.Warn("连接池接近上限")
// ✅ 错误但可恢复
mylogger.Error("数据库连接失败,尝试重连")
// ✅ 致命错误,程序退出
mylogger.Fatal("配置文件不存在")
3. 结构化日志
✅ 使用结构化字段
mylogger.WithFields(logrus.Fields{
"user_id": 123,
"action": "login",
"ip": "192.168.1.1",
}).Info("用户操作")
❌ 不要把所有信息放在消息中
mylogger.Info("用户 123 从 192.168.1.1 登录") // ❌ 难以搜索和分析
4. 错误处理
✅ 使用 WithError
if err != nil {
mylogger.WithError(err).Error("操作失败")
return err
}
✅ 添加上下文信息
if err != nil {
mylogger.WithFields(logrus.Fields{
"user_id": userID,
"operation": "update_profile",
}).WithError(err).Error("更新失败")
return err
}
5. 使用 Logger 实例传递
✅ 在函数间传递 logger
func handleRequest(logger *logrus.Entry, req Request) {
logger.Info("开始处理")
// ...
}
// 调用
logger := mylogger.WithField("request_id", reqID)
handleRequest(logger, req)
6. 不同环境使用不同配置
开发环境 (config.dev.yaml):
level: debug
format: text
console: true
report_caller: false
force_colors: true
file:
enable: true
path: ./logs/dev.log
max_size: 10
max_backups: 3
max_age: 3
compress: false
生产环境 (config.prod.yaml):
level: info
format: json
console: false
report_caller: false
force_colors: false
file:
enable: true
path: /var/log/myapp/app.log
max_size: 500
max_backups: 10
max_age: 30
compress: true
7. 关键操作必须记录
// ✅ 记录重要操作
func createOrder(order Order) error {
mylogger.WithFields(logrus.Fields{
"order_id": order.ID,
"user_id": order.UserID,
"amount": order.Amount,
}).Info("创建订单")
// 业务逻辑...
mylogger.WithField("order_id", order.ID).Info("订单创建完成")
mylogger.Success("订单创建成功")
return nil
}
8. 避免敏感信息
❌ 不要记录密码、密钥等敏感信息
// ❌ 危险!
mylogger.WithFields(logrus.Fields{
"username": user.Name,
"password": user.Password, // ❌ 泄露密码
}).Info("用户登录")
// ✅ 安全
mylogger.WithField("username", user.Name).Info("用户登录")
❓ 常见问题
A: 不需要!这是错误用法。正确写法:
import "gitee.com/yjx2320674897/logini"
mylogger.MustInit("config.yaml") // 使用 mylogger
mylogger.Info("test")
详见:IMPORT_VS_PACKAGE_NAME.md
Q2: 为什么没有颜色输出?
A: 配置文件中添加 force_colors: true:
format: text
force_colors: true
详见:COLOR_AND_CALLER_GUIDE.md
Q3: 为什么显示 logger.go 而不是我的代码位置?
A: 因为使用了包装函数。两种解决方案:
方案 1:关闭 report_caller(推荐)
report_caller: false
方案 2:使用 Logger 实例
logger := mylogger.GetLogger()
logger.Info("test") // 会显示正确位置
Q4: go get 报错 "no matching versions"?
A: 配置 GOPRIVATE:
go env -w GOPRIVATE=gitee.com
go env -w GOPROXY=https://goproxy.cn,direct
go get gitee.com/yjx2320674897/logini
详见:FIX_GITEE_GO_GET.md
Q5: 如何在测试环境禁用文件输出?
A:
file:
enable: false
Q6: 日志文件太大怎么办?
A: 调整配置:
file:
max_size: 50 # 减小单文件大小
max_backups: 5 # 减少保留文件数
max_age: 7 # 减少保留天数
Q7: 可以同时使用多个 logger 实例吗?
A: 可以,但通常不需要:
// 全局实例
mylogger.MustInit("config.yaml")
// 创建额外的实例
logger2 := logrus.New()
logger2.SetLevel(logrus.DebugLevel)
Q8: 支持 JSON 配置文件吗?
A: 支持!同时支持 .yaml、.yml 和 .json:
mylogger.MustInit("config.json")
Q9: 如何集成到现有项目?
A: 三步搞定:
go get gitee.com/yjx2320674897/logini
- 复制
config.yaml 到项目根目录
- 在
main.go 添加 mylogger.MustInit("config.yaml")
Q10: 性能会不会影响程序?
A: 正常使用不会。优化建议:
- 生产环境使用
level: info
- 关闭
report_caller
- 考虑使用
format: json
Q11: Success 和 Info 有什么区别?
A:
Info: 普通信息级别日志
Success: 基于 Info 级别,额外添加 status=success 字段,便于筛选成功操作
mylogger.Info("用户登录")
// 输出: level=info msg="用户登录"
mylogger.Success("用户登录成功")
// 输出: level=info msg="用户登录成功" status=success
使用建议:用 Success 标记关键成功操作,便于监控和日志分析。
Q12: 为什么 Debug 日志没有输出?
A: 检查配置文件中的 level 设置:
# ❌ 错误 - Debug 不会输出
level: info
# ✅ 正确 - Debug 会输出
level: debug
日志级别过滤规则:trace < debug < info < warn < error
📊 与其他日志库对比
| 特性 |
Logini |
logrus |
zap |
zerolog |
| 易用性 |
⭐⭐⭐⭐⭐ |
⭐⭐⭐ |
⭐⭐ |
⭐⭐ |
| 性能 |
⭐⭐⭐ |
⭐⭐⭐ |
⭐⭐⭐⭐⭐ |
⭐⭐⭐⭐⭐ |
| 功能丰富度 |
⭐⭐⭐⭐ |
⭐⭐⭐⭐ |
⭐⭐⭐⭐⭐ |
⭐⭐⭐⭐ |
| 配置文件 |
✅ |
❌ |
❌ |
❌ |
| 日志轮转 |
✅ 内置 |
❌ |
❌ |
❌ |
| 学习成本 |
极低 |
低 |
中 |
中 |
| 适合场景 |
中小型项目 |
通用 |
高性能 |
高性能 |
🔗 相关资源
📜 License
MIT License - 详见 LICENSE 文件
🤝 贡献
欢迎提交 Issue 和 Pull Request!
🙏 致谢
感谢以下开源项目:
⭐ 如果这个项目对您有帮助,欢迎点个 Star!