golang标准库log+第三方zerolog
2023-03-08 21:14 dribs 阅读(484) 评论(0) 编辑 收藏 举报package main import ( "log" "os" ) func main() { log.Printf("%s\n", "Printf") //2023/03/08 21:05:08 Printf log.Println("Println") log.Print("print") //log.Fatal("fatal") //log.Panicln("panicln") //自定义logger infologger := log.New(os.Stdout, "<Info>", 3|64) //3 LstdFlags 64 Lmsgprefix infologger.Println("this is test") // 2023/03/08 21:05:08 <Info>this is test errlogger := log.New(os.Stderr, "<ERROR>", 3|64) errlogger.Println("this is err log test") //写日志文件 f, err := os.OpenFile("e:/test.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, os.ModePerm) if err != nil { log.Panicln(err) } defer f.Close() logger := log.New(f, "<info>", log.LstdFlags) logger.Println("wirte file log test") }
log包提供了一个缺省的Logger即std。std是小写的,包外不可见,所以提供了Default()方法返回std给 包外使用。
// 大约在源码log.go第90行 var std = New(os.Stderr, "", LstdFlags) func Default() *Logger { return std } const ( Ldate = 1 << iota // 1 当前时区日期: 2009/01/23 Ltime // 2 当前时区时间: 01:23:23 Lmicroseconds // 4 微秒: 01:23:23.123123. assumes Ltime. Llongfile // 8 绝对路径和行号: /a/b/c/d.go:23 Lshortfile // 16 文件名和行号: d.go:23. overrides Llongfile LUTC // 32 使用UTC(GMT),而不是本地时区 Lmsgprefix // 64 默认前缀放行首,这个标记把前缀prefix放到消息 message之前 LstdFlags = Ldate | Ltime // 3 initial values for the standard logger )
zerolog
log模块太简陋了,实际使用并不方便。
logrus有日志级别、Hook机制、日志格式输出,很好用
zap是Uber的开源高性能日志库
zerolog更注重开发体验,高性能、有日志级别、链式API,json格式日志记录,号称0内存分配
官网 https://zerolog.io/
安装 go get -u github.com/rs/zerolog/log
package main import ( "errors" "fmt" "github.com/rs/zerolog" "github.com/rs/zerolog/log" "os" ) func example1() { zerolog.SetGlobalLevel(zerolog.ErrorLevel) //设置全局的logger级别为error 3 fmt.Println(zerolog.GlobalLevel()) //error //zerolog.SetGlobalLevel(zerolog.Disabled) //相当于禁用所有logger,就没日志输出了 log.Print("zerolog print string") // log.Debug().Msg("zerlog debug string") //log.Fatal().Msg("zerolog fatal string") //log.Panic().Msg("zerolog panic stirng") //logger 日志记录器级别 fmt.Println(log.Logger) //{{0xc000006020} -1 <nil> [123] [{}] false} fmt.Println(log.Logger.GetLevel()) //-1 trace 默认 //child logger log1 := log.Logger.Level(zerolog.InfoLevel) //log1 := log.Logger.Level(1) fmt.Println(log1) //新建一个logger 级别为1 info级别的 //消息级别 log.Debug().Msg("defalut debug string") //logger的默认为trace -1 所以大于等于-1的都打印 log.Error().Msg("defalut error string") //如果要输出成功,必须消息级别 >= max(自己的级别,glevel) log1.Debug().Msg("log1 debug string") log1.Info().Msg("log1 info string") //log1上面定义为info >=info才打印 log1.Warn().Msg("log1 warn string") log1.Error().Msg("log1 err string") //如果gleve设置成error3 那么只能大于等于err级别的才打印 err := errors.New("error test") log.Error().Err(err).Msg("haha") log.Error().Err(err).Send() //log.Panic().Err(err).Send() } //上下文 func example2() { zerolog.SetGlobalLevel(zerolog.InfoLevel) log.Info().Bool("Success", false).Str("Rea son", "File not found").Msg("文件没找到") log.Info().Str("Name", "Tom").Floats32("Scores", []float32{87.5, 90.59}).Send() } //错误日志 func example3() { zerolog.TimeFieldFormat = zerolog.TimeFormatUnix //自定义time字段时间的格式,时间戳 //zerolog.ErrorFieldName = "err" //修改稿日志json中的缺省字段名error //错误日志 err := errors.New("自定义错误") log.Error(). //错误级别消息 Err(err). //err字段,错误消息内容 Send() //有错误消息了,message可以省略 log.Fatal().Err(err).Send() //fatal 级别 } //自定义logger func example4() { zerolog.TimeFieldFormat = zerolog.TimeFormatUnix logger := log.With(). //with 返回基于全局Logger的子logger Str("Name", "lihongxing"). Caller(). //增加日志调用的位置信息字段 Logger() //返回logger logger.Info().Send() //{"level":"info","Name":"lihongxing","time":1678277947,"caller":"E:/disk/golang/zerolog包/main.go:73"} log.Info().Send() //全局Logger {"level":"info","time":1678277947} logger = zerolog.New(os.Stdout). //不基于全局Logger,重新构造 With().Str("Name", "LIHX"). Caller(). //调用者信息,增加日志函数调用的位置信息字段 Logger(). //返回logger Level(zerolog.ErrorLevel) //重新定义Logger级别为error 3 fmt.Println(logger.GetLevel()) //error logger.Info().Send() //error级别不打印 logger.Error().Send() //{"level":"error","Name":"LIHX","caller":"E:/disk/golang/zerolog包/main.go:84"} log.Info().Send() //{"level":"info","time":1678278590} 全局的Looger } //写日志文件 func example5() { zerolog.TimeFieldFormat = zerolog.TimeFormatUnix f, err := os.OpenFile("e:/tt.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, os.ModePerm) if err != nil { log.Panic().Err(err).Send() //内部调用panic } defer f.Close() //如果只输出到文件可以去掉os.Stdout multi := zerolog.MultiLevelWriter(f, os.Stdout) //多分支写 logger := zerolog.New(multi).With().Timestamp().Logger() logger.Info().Msg("日志分两路,写入日志和打印出控制台") } func main() { //example1() //example2() //example3() ////源码全局logger的定义 ////var Logger = zerolog.New(os.Stderr).With().Timestamp().Logger() //zerolog.TimeFieldFormat = zerolog.TimeFormatUnix ////with创建一个全局Logger的子logger 这样就覆盖了全局logger //log.Logger = log.With().Str("Name", "li").Logger() //log.Info().Send() example4() //example5() }