代码改变世界

golang标准库log+第三方zerolog

  dribs  阅读(525)  评论(0编辑  收藏  举报
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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给 包外使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 大约在源码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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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()
}

  

 

相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
历史上的今天:
2018-03-08 django后台处理前端上传和显示图片
点击右上角即可分享
微信分享提示