
本文介绍如何在go中使用logrus等主流日志库,将不同日志级别分别输出到控制台(如info)和文件(如debug),同时保留时间戳、格式化标签等关键特性,解决单实例多目标、多级别定向输出的常见需求。
本文介绍如何在go中使用logrus等主流日志库,将不同日志级别分别输出到控制台(如info)和文件(如debug),同时保留时间戳、格式化标签等关键特性,解决单实例多目标、多级别定向输出的常见需求。
在Go开发中,仅靠标准库log或简单使用io.MultiWriter(如io.MultiWriter(file, os.Stdout))虽能实现日志“复制”到多个输出,但无法按级别分流——它会把所有日志原样写入所有目标,违背“控制台只显示INFO及以上、文件记录DEBUG及以上”的核心诉求。
真正可行的方案是利用logrus的Hook机制(推荐)或zerolog/zap的多Writer+LevelFilter组合。以下以logrus为例,提供生产就绪的完整实现:
Go语言(Golang)1.26.0版本提供 Go 官方 Windows amd64 MSI 安装包下载入口,版本号 1.26.0,可用于旧项目维护、兼容性测试和指定版本开发环境配置。
✅ 正确做法:为不同输出注册带级别过滤的Hook
package main
import (
"os"
"time"
"github.com/sirupsen/logrus"
"gopkg.in/natefinch/lumberjack.v2"
)
func main() {
logger := logrus.New()
logger.SetFormatter(&logrus.TextFormatter{
FullTimestamp: true,
TimestampFormat: time.RFC3339,
})
// 控制台输出(仅INFO及以上)
consoleWriter := os.Stdout
logger.AddHook(&LevelHook{
Writer: consoleWriter,
Levels: []logrus.Level{logrus.InfoLevel, logrus.WarnLevel, logrus.ErrorLevel, logrus.FatalLevel, logrus.PanicLevel},
Formatter: &logrus.TextFormatter{
DisableColors: true,
FullTimestamp: true,
TimestampFormat: time.RFC3339,
},
})
// 文件输出(DEBUG及以上,自动轮转)
fileWriter := &lumberjack.Logger{
Filename: "app.log",
MaxSize: 50, // MB
MaxBackups: 5,
MaxAge: 28, // days
}
logger.AddHook(&LevelHook{
Writer: fileWriter,
Levels: []logrus.Level{
logrus.DebugLevel, logrus.InfoLevel, logrus.WarnLevel,
logrus.ErrorLevel, logrus.FatalLevel, logrus.PanicLevel,
},
Formatter: &logrus.TextFormatter{
FullTimestamp: true,
TimestampFormat: time.RFC3339,
DisableColors: true,
},
})
// 使用示例
logger.Debug("Entering some func") // → 仅写入文件
res := "Successful"
logger.Infof("Result was: %s", res) // → 控制台 + 文件均输出
}
? 自定义LevelHook(核心组件)
type LevelHook struct {
Writer io.Writer
Levels []logrus.Level
Formatter logrus.Formatter
}
func (h *LevelHook) Fire(entry *logrus.Entry) error {
for _, level := range h.Levels {
if entry.Level == level {
err := h.Formatter.Format(entry)
if err != nil {
return err
}
_, err = h.Writer.Write(entry.Buffer.Bytes())
return err
}
}
return nil
}
func (h *LevelHook) Levels() []logrus.Level {
return h.Levels
}
⚠️ 注意事项:
- io.MultiWriter仅适用于全量镜像输出,不满足分级需求;
- logrus默认不支持多级输出分流,必须通过Hook手动控制;
- 生产环境务必使用lumberjack等轮转写入器,避免日志文件无限增长;
- 若追求极致性能与结构化日志,可切换至zap(搭配zapcore.NewMultiCore与zapcore.LevelEnablerFunc)。
综上,Go中实现多目标、多级别日志输出的关键在于解耦输出目标与日志级别逻辑,而非简单合并Writer。借助logrus Hook或zap Core机制,即可优雅、可靠地达成控制台精简提示、文件完整审计的工程目标。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










