log 包

log 包提供了一组基础的日志 API 和一个使用了 stderr 进行输出的标准实现。

标准接口如下:

  1. // Level is log level of verboser. We strongly recommend you to
  2. // follow the rules:
  3. // 1. Use LevelDebug for debug log.
  4. // 2. Use 1 for important but not frequent log.
  5. // 3. Use 2 for important and frequent log.
  6. // 4. Use 3 for not important and not frequent log.
  7. // 5. Use 4 for not important but frequent log.
  8. // 6. Use [5, LevelDebug) only if you want to custom log levels.
  9. type Level int32
  10. const (
  11. // LevelDebug is for debug info.
  12. LevelDebug Level = math.MaxInt32
  13. )
  14. // Severity has four classes to correspond with log situation.
  15. type Severity string
  16. const (
  17. // SeverityInfo is for usual log.
  18. SeverityInfo Severity = "INFO"
  19. // SeverityWarning is for warning.
  20. SeverityWarning Severity = "WARN"
  21. // SeverityError is for error.
  22. SeverityError Severity = "ERROR"
  23. // SeverityFatal is for panic error. The severity means that
  24. // a logger will output the error and exit immediately.
  25. // It can't be recovered.
  26. SeverityFatal Severity = "FATAL"
  27. )
  28. // Verboser is an interface type that implements Info(f|ln) .
  29. // See the documentation of V for more information.
  30. type Verboser interface {
  31. // Info logs to the INFO log.
  32. // Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
  33. Info(...interface{})
  34. // Infof logs to the INFO log.
  35. // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
  36. Infof(string, ...interface{})
  37. // Infoln logs to the INFO log.
  38. // Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
  39. Infoln(...interface{})
  40. }
  41. // Logger provides a set of methods to output log.
  42. type Logger interface {
  43. Verboser
  44. // V reports whether verbosity at the call site is at least the requested level.
  45. // The returned value is a Verboser, which implements Info, Infof
  46. // and Infoln. These methods will write to the Info log if called.
  47. V(Level) Verboser
  48. // Warning logs to the WARNING logs.
  49. // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
  50. Warning(...interface{})
  51. // Warningf logs to the WARNING logs.
  52. // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
  53. Warningf(string, ...interface{})
  54. // Warningln logs to the WARNING logs.
  55. // Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
  56. Warningln(...interface{})
  57. // Error logs to the ERROR logs.
  58. // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
  59. Error(...interface{})
  60. // Errorf logs to the ERROR logs.
  61. // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
  62. Errorf(string, ...interface{})
  63. // Errorln logs to the ERROR logs.
  64. // Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
  65. Errorln(...interface{})
  66. // Fatal logs to the FATAL logs, then calls os.Exit(1).
  67. // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
  68. Fatal(...interface{})
  69. // Fatalf logs to the FATAL logs, then calls os.Exit(1).
  70. // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
  71. Fatalf(string, ...interface{})
  72. // Fatalln logs to the FATAL logs, then calls os.Exit(1).
  73. // Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
  74. Fatalln(...interface{})
  75. // Clone clones current logger with new wrapper.
  76. // A positive wrapper indicates how many wrappers outside the logger.
  77. // A negative wrapper indicates how many wrappers should be stripped.
  78. Clone(wrapper int) Logger
  79. }

这套日志 API 参考了 glog 的 golang API,并且允许用户接入其他日志系统。

在实现一个自定义的 logger 之前,需要知道以下几件事情:

  1. log 包有一个默认的 logger,使用的是 StdLogger。可以通过 SetDefaultLogger() 变更。
  2. 对于不需要输出日志的场景,使用 SilentLogger 的实例而不是 nil.
  3. 正确实现 logger 的 Clone 方法。Clone 方法用于在对 logger 进行包装的时候,获取正确层级的调用栈信息。
  4. 在 Fatal* 时候,使用 os.Exit(1) 进行退出,而不是使用其他错误码(除非业务有要求)。这是标准库的日志包使用的退出码。