diff --git a/book/config/config.go b/book/config/config.go index 7a59656..3549a28 100644 --- a/book/config/config.go +++ b/book/config/config.go @@ -3,15 +3,8 @@ package config import ( "encoding/json" "fmt" - "io" - "strconv" - "strings" "sync" - "time" - "github.com/rs/zerolog" - "github.com/rs/zerolog/pkgerrors" - "gopkg.in/natefinch/lumberjack.v2" "gorm.io/driver/mysql" "gorm.io/gorm" ) @@ -97,132 +90,3 @@ func (c *MySQL) DB() *gorm.DB { return c.db } - -// 怎么配置 -// 是否要打印到控制台 -// 是否要打印到文件里,是否要轮转 100M 5 -type Log struct { - // 0 为打印日志全路径, 默认打印2层路径 - 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 -} - -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) -} diff --git a/book/config/log.go b/book/config/log.go new file mode 100644 index 0000000..3eef793 --- /dev/null +++ b/book/config/log.go @@ -0,0 +1,144 @@ +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) +} diff --git a/homework/README.md b/homework/README.md index 3ad7ad9..27470db 100644 --- a/homework/README.md +++ b/homework/README.md @@ -19,4 +19,5 @@ Web全栈开发(Book Api): 必须完成 - GO17042-志勇 [vblog](https://gitlab.com/laizhiyo/vblog.git) - GO17024-mushroom [vblog](https://gitlab.com/go3751246/book-api) -day01: book restful api + config 包 的版本, 跑起来能验证成功 \ No newline at end of file +day01: book restful api + config 包 的版本, 跑起来能验证成功 +day02: book mvc 版本是必须要写出来(log 包允许你copy), mcube的版本是体验, mcube版本不做要求 \ No newline at end of file