个人博客网站: https://www.sakurasss.top ( 最近打算把个人博客里的那些文章也慢慢移过来吧 )
- Golang 里面的那些日志库,我个人喜欢还是喜欢用 zerolog,主要是喜欢 zerolog 的链式调用,还有它的性能,虽然 zap 也不错,但是 zap 配置起来我觉得有些麻烦。
- 本来是打算 slog 出来之后,就不用第三方日志的,然后发现 slog 连时间都不能格式化输出。也没法同时输出到文件和终端,想要实现的话,自己还要定义两个 slog ,然后还得自己封装一下
还是用 zerolog 得了,而且 zerolog 还有个全局变量调用的时候比较方便
github地址:https://github.com/rs/zerolog
一: 定义 log.yaml 配置文件
这是最简单的配置。根据自己需求添加字段,增加配置
# 日志配置
ZeroLogConfig:
Level: debug
# development or production
Pattern: development
OutPut: log
# 日志轮换(分割配置)
LogRotate:
Filename: service.log
MaxSize: 1
MaxBackups: 3
MaxAge: 7
Compress: true
二: 使用 viper 加载配置文件
import (
"fmt"
"github.com/spf13/viper"
)
func CreateConfig(file string) *viper.Viper {
config := viper.New()
configPath := "config/"
config.AddConfigPath(configPath) // 文件所在目录
config.SetConfigName(file) // 文件名
config.SetConfigType("yaml") // 文件类型
configFile := configPath + file + ".yaml"
if err := config.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
panic(fmt.Errorf("找不到配置文件:%s", configFile)) //系统初始化阶段发生任何错误,直接结束进程
} else {
panic(fmt.Errorf("解析配置文件%s出错:%s", configFile, err))
}
}
return config
}
二: 初始化 log 日志
import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"os"
"time"
)
type LogConfig struct {
Level string `yaml:"level"`
Pattern string `yaml:"pattern"`
OutPut string `yaml:"output"`
}
// LogInit 完成Zero 日志的初始化
package loadConfig
import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"gopkg.in/natefinch/lumberjack.v2"
"os"
"strings"
"time"
)
// LogConfig 日志配置
type LogConfig struct {
ZeroLogConfig ZeroLogConfig `yaml:"ZeroLogConfig"`
LogRotate LogRotate `yaml:"LogRotate"`
}
// ZeroLogConfig
type ZeroLogConfig struct {
Level string `yaml:"Level"`
Pattern string `yaml:"Pattern"`
OutPut string `yaml:"OutPut"`
}
// LogRotate 日志轮换(分割)配置
type LogRotate struct {
Filename string `yaml:"Filename"`
MaxSize int `yaml:"MaxSize"` // megabytes,M 为单位,达到这个设置数后就进行日志切割
MaxBackups int `yaml:"MaxBackups"` // 保留旧文件最大份数
MaxAge int `yaml:"MaxAge"` // days , 旧文件最大保存天数
Compress bool `yaml:"Compress"` // 是否开启压缩,默认关闭
}
// LogInit 完成Zero 日志的初始化
func LogInit() {
var logConfig LogConfig
config := CreateConfig("log")
// 反序列化到结构体
err := config.Unmarshal(&logConfig)
if err != nil {
panic(err)
}
// 验证是序列化成功
//fmt.Println(logConfig.ZeroLogConfig)
//fmt.Println(logConfig.LogRotate)
//fmt.Println(strings.Join([]string{logConfig.ZeroLogConfig.OutPut, logConfig.LogRotate.Filename}, "/"))
// 设置日志等级
switch logConfig.ZeroLogConfig.Level {
case "debug":
zerolog.SetGlobalLevel(zerolog.DebugLevel)
case "info":
zerolog.SetGlobalLevel(zerolog.InfoLevel)
case "warn":
zerolog.SetGlobalLevel(zerolog.WarnLevel)
case "error":
zerolog.SetGlobalLevel(zerolog.ErrorLevel)
case "panic":
zerolog.SetGlobalLevel(zerolog.PanicLevel)
}
// 日志切割
logRotate := &lumberjack.Logger{
Filename: strings.Join([]string{logConfig.ZeroLogConfig.OutPut, logConfig.LogRotate.Filename}, "/"), // 文件位置
MaxSize: 1, // megabytes,M 为单位,达到这个设置数后就进行日志切割
MaxBackups: 3, // 保留旧文件最大份数
MaxAge: 7, //days , 旧文件最大保存天数
Compress: true, // disabled by default,是否压缩日志归档,默认不压缩
}
// 调整日志时间格式
zerolog.TimeFieldFormat = time.StampMilli
// 开启调用位置打印
log.Logger = log.With().Caller().Logger()
if logConfig.ZeroLogConfig.Pattern == "development" {
// 控制台输出的输出器
consoleWriter := zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.StampMilli}
multi := zerolog.MultiLevelWriter(consoleWriter, logRotate)
log.Logger = log.Output(multi)
} else if logConfig.ZeroLogConfig.Pattern == "production" {
log.Logger = log.Output(logRotate)
} else {
panic("log pattern Error")
}
}
- 运行
import (
"Distributed/loadConfig"
"errors"
"github.com/rs/zerolog/log"
)
func main() {
// 初始化配置
loadConfig.LogInit()
// 四种日志级别
log.Debug().Str("name", "sakura").Msg("Debug Msg")
log.Info().Int("value", 114514).Msg("Info Msg")
log.Error().Err(errors.New("This is Error")).Msg("Errotr Msg")
log.Warn().Msg("Warn Msg")
}
运行之后开始看到日志同时在终端,文件输出
development : 开发模式,开启终端彩输出和文件输出
pordectiuon:生产模式,关闭终端彩色输出,只留一个文件输出(毕竟终端这个彩色打印性能非常差)