通用日志管理模块。

使用方式:

  1. import "gitee.com/johng/gf/g/os/glog"

方法列表

godoc.org/github.com/johng-cn/gf/g/os/glog

包方法

  1. func Critical(v ...interface{})
  2. func Criticalf(format string, v ...interface{})
  3. func Criticalfln(format string, v ...interface{})
  4. func Debug(v ...interface{})
  5. func Debugf(format string, v ...interface{})
  6. func Debugfln(format string, v ...interface{})
  7. func Error(v ...interface{})
  8. func Errorf(format string, v ...interface{})
  9. func Errorfln(format string, v ...interface{})
  10. func Fatal(v ...interface{})
  11. func Fatalf(format string, v ...interface{})
  12. func Fatalfln(format string, v ...interface{})
  13. func Fatalln(v ...interface{})
  14. func GetBacktrace() string
  15. func GetLevel() int
  16. func GetPath() string
  17. func Info(v ...interface{})
  18. func Infof(format string, v ...interface{})
  19. func Infofln(format string, v ...interface{})
  20. func Notice(v ...interface{})
  21. func Noticef(format string, v ...interface{})
  22. func Noticefln(format string, v ...interface{})
  23. func Panic(v ...interface{})
  24. func Panicf(format string, v ...interface{})
  25. func Panicfln(format string, v ...interface{})
  26. func Panicln(v ...interface{})
  27. func Print(v ...interface{})
  28. func PrintBacktrace()
  29. func Printf(format string, v ...interface{})
  30. func Printfln(format string, v ...interface{})
  31. func Println(v ...interface{})
  32. func SetDebug(debug bool)
  33. func SetFile(file string)
  34. func SetLevel(level int)
  35. func SetPath(path string)
  36. func SetStdPrint(open bool)
  37. func Warning(v ...interface{})
  38. func Warningf(format string, v ...interface{})
  39. func Warningfln(format string, v ...interface{})

对象方法

  1. type Logger
  2. func Backtrace(enabled bool) *Logger
  3. func Cat(category string) *Logger
  4. func File(file string) *Logger
  5. func Level(level int) *Logger
  6. func New() *Logger
  7. func StdPrint(enabled bool) *Logger
  8. func (l *Logger) Backtrace(enabled bool) *Logger
  9. func (l *Logger) Cat(category string) *Logger
  10. func (l *Logger) Clone() *Logger
  11. func (l *Logger) Critical(v ...interface{})
  12. func (l *Logger) Criticalf(format string, v ...interface{})
  13. func (l *Logger) Criticalfln(format string, v ...interface{})
  14. func (l *Logger) Debug(v ...interface{})
  15. func (l *Logger) Debugf(format string, v ...interface{})
  16. func (l *Logger) Debugfln(format string, v ...interface{})
  17. func (l *Logger) Error(v ...interface{})
  18. func (l *Logger) Errorf(format string, v ...interface{})
  19. func (l *Logger) Errorfln(format string, v ...interface{})
  20. func (l *Logger) Fatal(v ...interface{})
  21. func (l *Logger) Fatalf(format string, v ...interface{})
  22. func (l *Logger) Fatalfln(format string, v ...interface{})
  23. func (l *Logger) Fatalln(v ...interface{})
  24. func (l *Logger) File(file string) *Logger
  25. func (l *Logger) GetBacktrace() string
  26. func (l *Logger) GetIO() io.Writer
  27. func (l *Logger) GetLevel() int
  28. func (l *Logger) Info(v ...interface{})
  29. func (l *Logger) Infof(format string, v ...interface{})
  30. func (l *Logger) Infofln(format string, v ...interface{})
  31. func (l *Logger) Level(level int) *Logger
  32. func (l *Logger) Notice(v ...interface{})
  33. func (l *Logger) Noticef(format string, v ...interface{})
  34. func (l *Logger) Noticefln(format string, v ...interface{})
  35. func (l *Logger) Panic(v ...interface{})
  36. func (l *Logger) Panicf(format string, v ...interface{})
  37. func (l *Logger) Panicfln(format string, v ...interface{})
  38. func (l *Logger) Panicln(v ...interface{})
  39. func (l *Logger) Print(v ...interface{})
  40. func (l *Logger) PrintBacktrace()
  41. func (l *Logger) Printf(format string, v ...interface{})
  42. func (l *Logger) Printfln(format string, v ...interface{})
  43. func (l *Logger) Println(v ...interface{})
  44. func (l *Logger) SetBacktrace(enabled bool)
  45. func (l *Logger) SetDebug(debug bool)
  46. func (l *Logger) SetFile(file string)
  47. func (l *Logger) SetIO(w io.Writer)
  48. func (l *Logger) SetLevel(level int)
  49. func (l *Logger) SetPath(path string) error
  50. func (l *Logger) SetStdPrint(enabled bool)
  51. func (l *Logger) StdPrint(enabled bool) *Logger
  52. func (l *Logger) Warning(v ...interface{})
  53. func (l *Logger) Warningf(format string, v ...interface{})
  54. func (l *Logger) Warningfln(format string, v ...interface{})

重要的几点说明:

  1. glog是并发安全的,无论是创建的glog.Logger对象,还是提供的包方法;
  2. glog支持文件输出、日志级别、日志分类、调试管理、调用跟踪、链式操作等丰富特性;
  3. 可以使用glog.New方法创建glog.Logger对象用于自定义日志打印,也可以使用glog默认提供的包方法来打印日志。当使用包方法时,注意任何的glog.Set*设置方法都将会全局生效
  4. 日志内容格式固定为 时间 [级别] 内容 换行,其中时间精确到毫秒级别,级别为可选输出,内容为调用端的参数输入,换行为可选输出(部分方法自动为日志内容添加换行符号),日志内容例如:2018-10-10 12:00:01.568 [ERRO] 产生错误
  5. Print*/Debug*/Info*方法输出日志到标准输出(stdout),Notice*/Warning*/Error*/Critical*/Panic*/Fatal*方法输出日志到标准错误(stderr);
  6. 其中Panic*方法在输出日志信息后会引发panic错误方法,Fatal*方法在输出日志信息之后会停止进程运行,并返回进程状态码值为1(正常程序退出状态码为0);

日志级别

日志级别用于管理日志的输出,我们可以通过设定特定的日志级别来关闭/开启特定的日志内容。通过SetLevel方法可以设置日志级别,glog支持以下几种日志级别常量设定:

  1. LEVEL_ALL
  2. LEVEL_DEBU
  3. LEVEL_INFO
  4. LEVEL_NOTI
  5. LEVEL_WARN
  6. LEVEL_ERRO
  7. LEVEL_CRIT

我们可以通过位操作组合使用这几种级别,例如其中LEVEL_ALL等价于LEVEL_DEBU | LEVEL_INFO | LEVEL_NOTI | LEVEL_WARN | LEVEL_ERRO | LEVEL_CRIT。例如我们可以通过LEVEL_ALL & ^LEVEL_DEBU & ^LEVEL_INFO & ^LEVEL_NOTI来过滤掉LEVEL_DEBU/LEVEL_INFO/LEVEL_NOTI日志内容。

简单示例:

  1. package main
  2. import (
  3. "gitee.com/johng/gf/g/os/glog"
  4. )
  5. // 设置日志等级,过滤掉Info日志信息
  6. func main() {
  7. l := glog.New()
  8. l.Info("info1")
  9. l.SetLevel(glog.LEVEL_ALL^glog.LEVEL_INFO)
  10. l.Info("info2")
  11. }

执行后,输出结果为:

  1. 2018-10-10 14:38:48.687 [INFO] info1

日志目录

默认情况下,glog将会输出日志内容到标准输出,我们可以通过SetPath方法设置日志输出的目录路径,这样日志内容将会写入到日志文件中,并且由于其内部使用了gfpool文件指针池,文件写入的效率相当优秀。简单示例:

  1. package main
  2. import (
  3. "gitee.com/johng/gf/g/os/glog"
  4. "gitee.com/johng/gf/g/os/gfile"
  5. "gitee.com/johng/gf/g"
  6. )
  7. // 设置日志输出路径
  8. func main() {
  9. path := "/tmp/glog"
  10. glog.SetPath(path)
  11. glog.Println("日志内容")
  12. list, err := gfile.ScanDir(path, "*")
  13. g.Dump(err)
  14. g.Dump(list)
  15. }

执行后,输出内容为:

  1. 2018-10-10 14:03:46.904 日志内容
  2. null
  3. [
  4. "/tmp/glog/2018-10-10.log"
  5. ]

当通过SetPath设置日志的输出目录,如果目录不存在时,将会递归创建该目录路径。可以看到,执行Println之后,在/tmp下创建了日志目录glog,并且在其下生成了日志文件。同时,我们也可以看见日志内容不仅输出到了文件,默认情况下也输出到了终端,我们可以通过SetStdPrint(false)方法来关闭终端的日志输出,这样日志内容仅会输出到日志文件中。

我们也可以通过gf框架的g.SetLogLevel/g.SetDebug模块来管理日志级别、调试信息。对应的日志等级如下:

  1. LOG_LEVEL_ALL
  2. LOG_LEVEL_DEBU
  3. LOG_LEVEL_INFO
  4. LOG_LEVEL_NOTI
  5. LOG_LEVEL_WARN
  6. LOG_LEVEL_ERRO
  7. LOG_LEVEL_CRIT

日志文件

默认情况下,日志文件名称以当前时间日期命名,格式为YYYY-MM-DD.log,我们可以使用SetFile方法来设置文件名称的格式,并且文件名称格式支持【gtime时间格式】。简单示例:

  1. package main
  2. import (
  3. "gitee.com/johng/gf/g/os/glog"
  4. "gitee.com/johng/gf/g/os/gfile"
  5. "gitee.com/johng/gf/g"
  6. )
  7. // 设置日志等级
  8. func main() {
  9. l := glog.New()
  10. path := "/tmp/glog"
  11. l.SetPath(path)
  12. l.SetStdPrint(false)
  13. // 使用默认文件名称格式
  14. l.Println("标准文件名称格式,使用当前时间时期")
  15. // 通过SetFile设置文件名称格式
  16. l.SetFile("stdout.log")
  17. l.Println("设置日志输出文件名称格式为同一个文件")
  18. // 链式操作设置文件名称格式
  19. l.File("stderr.log").Println("支持链式操作")
  20. l.File("error-{Ymd}.log").Println("文件名称支持带gtime日期格式")
  21. l.File("access-{Ymd}.log").Println("文件名称支持带gtime日期格式")
  22. list, err := gfile.ScanDir(path, "*")
  23. g.Dump(err)
  24. g.Dump(list)
  25. }

执行后,输出结果为:

  1. null
  2. [
  3. "/tmp/glog/2018-10-10.log",
  4. "/tmp/glog/access-20181010.log",
  5. "/tmp/glog/error-20181010.log",
  6. "/tmp/glog/stderr.log",
  7. "/tmp/glog/stdout.log"
  8. ]

可以看到,文件名称格式中如果需要使用gtime时间格式,格式内容需要使用{xxx}包含起来。该示例中也使用到了链式操作的特性,具体请看后续说明。

链式操作

glog模块支持非常简便的链式操作方式,相关链式操作方法如下:

  1. // 是否开启终端输出
  2. func StdPrint(enabled bool) *Logger
  3. // 是否开启trace打印
  4. func Backtrace(enabled bool) *Logger
  5. // 设置日志文件分类
  6. func Cat(category string) *Logger
  7. // 设置日志文件格式
  8. func File(file string) *Logger
  9. // 设置日志打印级别
  10. func Level(level int) *Logger

简单示例:

  1. package main
  2. import (
  3. "gitee.com/johng/gf/g/os/glog"
  4. "gitee.com/johng/gf/g/os/gfile"
  5. "gitee.com/johng/gf/g"
  6. )
  7. func main() {
  8. path := "/tmp/glog-cat"
  9. glog.SetPath(path)
  10. glog.StdPrint(false).Cat("cat1").Cat("cat2").Println("test")
  11. list, err := gfile.ScanDir(path, "*", true)
  12. g.Dump(err)
  13. g.Dump(list)
  14. }

执行后,输出结果为:

  1. null
  2. [
  3. "/tmp/glog-cat/cat1",
  4. "/tmp/glog-cat/cat1/cat2",
  5. "/tmp/glog-cat/cat1/cat2/2018-10-10.log",
  6. ]

Trace特性

错误日志信息支持trace特性,可以通过Notice*/Warning*/Error*/Critical*/Panic*/Fatal*错误方法触发,也可以通过GetBacktrace/PrintBacktrace获取/打印。错误信息的trace信息对于调试错误来说相当有用。

示例1,通过错误方法触发

  1. package main
  2. import (
  3. "gitee.com/johng/gf/g/os/glog"
  4. )
  5. func main() {
  6. glog.Error("发生错误!")
  7. }

打印出的结果如下:

  1. 2018-01-11 17:20:10 [ERRO] 发生错误!
  2. Trace:
  3. 1. /home/john/Workspace/Go/gitee.com/johng/gf/geg/other/test.go:8

示例2,通过trace方法打印

  1. package main
  2. import (
  3. "gitee.com/johng/gf/g/os/glog"
  4. "fmt"
  5. )
  6. func main() {
  7. glog.PrintBacktrace()
  8. glog.New().PrintBacktrace()
  9. fmt.Println(glog.GetBacktrace())
  10. fmt.Println(glog.New().GetBacktrace())
  11. }

执行后,输出结果为:

  1. 2018-10-10 15:18:34.346 1. /home/john/Workspace/Go/GOPATH/src/gitee.com/johng/gf/geg/os/glog/glog_backtrace.go:10
  2. 2018-10-10 15:18:34.346 1. /home/john/Workspace/Go/GOPATH/src/gitee.com/johng/gf/geg/os/glog/glog_backtrace.go:11
  3. 1. /home/john/Workspace/Go/GOPATH/src/gitee.com/johng/gf/geg/os/glog/glog_backtrace.go:13
  4. 1. /home/john/Workspace/Go/GOPATH/src/gitee.com/johng/gf/geg/os/glog/glog_backtrace.go:14

Debug特性

Debug/Debugf/Debugfln是非常有用的几个方法,用于调试信息的记录,常用于开发/测试环境中,当应用上线之后可以方便地使用SetDebug进行开启/关闭。

  1. package main
  2. import (
  3. "time"
  4. "gitee.com/johng/gf/g/os/glog"
  5. "gitee.com/johng/gf/g/os/gtime"
  6. )
  7. func main() {
  8. gtime.SetTimeout(3*time.Second, func() {
  9. glog.SetDebug(false)
  10. })
  11. for {
  12. glog.Debug(gtime.Datetime())
  13. time.Sleep(time.Second)
  14. }
  15. }

该示例中使用glog.Debug方法输出调试信息,3秒后关闭调试信息的输出。执行后,输出结果如下,可以看到只输出了3条日志信息,后续的调试日志信息由于通过SetDebug方法关闭后,便不再输出。

  1. 2018-07-22 12:20:11.100 [DEBU] 2018-07-22 12:20:11
  2. 2018-07-22 12:20:12.101 [DEBU] 2018-07-22 12:20:12
  3. 2018-07-22 12:20:13.101 [DEBU] 2018-07-22 12:20:13