go17/book/config/log.go
2024-11-23 18:12:22 +08:00

145 lines
3.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package config
import (
"fmt"
"io"
"strconv"
"strings"
"sync"
"time"
"github.com/rs/zerolog"
"github.com/rs/zerolog/pkgerrors"
"gopkg.in/natefinch/lumberjack.v2"
)
// 怎么配置
// 是否要打印到控制台
// 是否要打印到文件里,是否要轮转 100M 5
type Log struct {
// 0 为打印日志全路径, 默认打印3层路径
CallerDeep int `toml:"caller_deep" json:"caller_deep" yaml:"caller_deep" env:"CALLER_DEEP"`
// 日志的级别, 默认Debug
Level zerolog.Level `toml:"level" json:"level" yaml:"level" env:"LEVEL"`
// 控制台日志配置
Console Console `toml:"console" json:"console" yaml:"console" envPrefix:"CONSOLE_"`
// 日志文件配置
File File `toml:"file" json:"file" yaml:"file" envPrefix:"FILE_"`
root *zerolog.Logger
lock sync.Mutex
}
type Console struct {
Enable bool `toml:"enable" json:"enable" yaml:"enable" env:"ENABLE"`
NoColor bool `toml:"no_color" json:"no_color" yaml:"no_color" env:"NO_COLOR"`
}
func (c *Console) ConsoleWriter() io.Writer {
output := zerolog.NewConsoleWriter(func(w *zerolog.ConsoleWriter) {
w.NoColor = c.NoColor
w.TimeFormat = time.RFC3339
})
output.FormatLevel = func(i interface{}) string {
return strings.ToUpper(fmt.Sprintf("%-6s", i))
}
output.FormatMessage = func(i interface{}) string {
return fmt.Sprintf("%s", i)
}
output.FormatFieldName = func(i interface{}) string {
return fmt.Sprintf("%s:", i)
}
output.FormatFieldValue = func(i interface{}) string {
return strings.ToUpper(fmt.Sprintf("%s", i))
}
return output
}
type File struct {
// 是否开启文件记录
Enable bool `toml:"enable" json:"enable" yaml:"enable" env:"ENABLE"`
// 文件的路径
FilePath string `toml:"file_path" json:"file_path" yaml:"file_path" env:"PATH"`
// 单位M, 默认100M
MaxSize int `toml:"max_size" json:"max_size" yaml:"max_size" env:"MAX_SIZE"`
// 默认保存 6个文件
MaxBackups int `toml:"max_backups" json:"max_backups" yaml:"max_backups" env:"MAX_BACKUPS"`
// 保存多久
MaxAge int `toml:"max_age" json:"max_age" yaml:"max_age" env:"MAX_AGE"`
// 是否压缩
Compress bool `toml:"compress" json:"compress" yaml:"compress" env:"COMPRESS"`
}
func (f *File) FileWriter() io.Writer {
return &lumberjack.Logger{
Filename: f.FilePath,
MaxSize: f.MaxSize,
MaxAge: f.MaxAge,
MaxBackups: f.MaxBackups,
Compress: f.Compress,
}
}
func (l *Log) Logger() *zerolog.Logger {
l.lock.Lock()
defer l.lock.Unlock()
if l.root == nil {
var writers []io.Writer
if l.Console.Enable {
writers = append(writers, l.Console.ConsoleWriter())
}
if l.File.Enable {
if l.File.FilePath == "" {
l.File.FilePath = "logs/app.log"
}
writers = append(writers, l.File.FileWriter())
}
zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack
// logger对象配置一些上下文信息: 2024-11-23T15:11:42+08:00
// 带上中间信息Any
// book/controller/book.go:60
root := zerolog.New(io.MultiWriter(writers...)).With().Timestamp().Any("服务", "book-api")
if l.CallerDeep > 0 {
// 启用caller
root = root.Caller()
// 配置自定义caller
zerolog.CallerMarshalFunc = l.CallerMarshalFunc
}
// 带有这些上下文信息的Logger对象 提前出来作为全局Logger对象供全局使用
l.SetRoot(root.Logger().Level(l.Level))
}
return l.root
}
func (m *Log) SetRoot(v zerolog.Logger) {
m.root = &v
}
// /go/src/your_project/some_file:21
func (m *Log) CallerMarshalFunc(pc uintptr, file string, line int) string {
if m.CallerDeep == 0 {
return file
}
short := file
count := 0
for i := len(file) - 1; i > 0; i-- {
if file[i] == '/' {
short = file[i+1:]
count++
}
if count >= m.CallerDeep {
break
}
}
file = short
return file + ":" + strconv.Itoa(line)
}