log.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package hclog
  2. import (
  3. "io"
  4. "log"
  5. "os"
  6. "strings"
  7. )
  8. var (
  9. DefaultOutput = os.Stderr
  10. DefaultLevel = Info
  11. )
  12. type Level int
  13. const (
  14. // This is a special level used to indicate that no level has been
  15. // set and allow for a default to be used.
  16. NoLevel Level = 0
  17. // The most verbose level. Intended to be used for the tracing of actions
  18. // in code, such as function enters/exits, etc.
  19. Trace Level = 1
  20. // For programmer lowlevel analysis.
  21. Debug Level = 2
  22. // For information about steady state operations.
  23. Info Level = 3
  24. // For information about rare but handled events.
  25. Warn Level = 4
  26. // For information about unrecoverable events.
  27. Error Level = 5
  28. )
  29. // LevelFromString returns a Level type for the named log level, or "NoLevel" if
  30. // the level string is invalid. This facilitates setting the log level via
  31. // config or environment variable by name in a predictable way.
  32. func LevelFromString(levelStr string) Level {
  33. // We don't care about case. Accept "INFO" or "info"
  34. levelStr = strings.ToLower(strings.TrimSpace(levelStr))
  35. switch levelStr {
  36. case "trace":
  37. return Trace
  38. case "debug":
  39. return Debug
  40. case "info":
  41. return Info
  42. case "warn":
  43. return Warn
  44. case "error":
  45. return Error
  46. default:
  47. return NoLevel
  48. }
  49. }
  50. // The main Logger interface. All code should code against this interface only.
  51. type Logger interface {
  52. // Args are alternating key, val pairs
  53. // keys must be strings
  54. // vals can be any type, but display is implementation specific
  55. // Emit a message and key/value pairs at the TRACE level
  56. Trace(msg string, args ...interface{})
  57. // Emit a message and key/value pairs at the DEBUG level
  58. Debug(msg string, args ...interface{})
  59. // Emit a message and key/value pairs at the INFO level
  60. Info(msg string, args ...interface{})
  61. // Emit a message and key/value pairs at the WARN level
  62. Warn(msg string, args ...interface{})
  63. // Emit a message and key/value pairs at the ERROR level
  64. Error(msg string, args ...interface{})
  65. // Indicate if TRACE logs would be emitted. This and the other Is* guards
  66. // are used to elide expensive logging code based on the current level.
  67. IsTrace() bool
  68. // Indicate if DEBUG logs would be emitted. This and the other Is* guards
  69. IsDebug() bool
  70. // Indicate if INFO logs would be emitted. This and the other Is* guards
  71. IsInfo() bool
  72. // Indicate if WARN logs would be emitted. This and the other Is* guards
  73. IsWarn() bool
  74. // Indicate if ERROR logs would be emitted. This and the other Is* guards
  75. IsError() bool
  76. // Creates a sublogger that will always have the given key/value pairs
  77. With(args ...interface{}) Logger
  78. // Create a logger that will prepend the name string on the front of all messages.
  79. // If the logger already has a name, the new value will be appended to the current
  80. // name. That way, a major subsystem can use this to decorate all it's own logs
  81. // without losing context.
  82. Named(name string) Logger
  83. // Create a logger that will prepend the name string on the front of all messages.
  84. // This sets the name of the logger to the value directly, unlike Named which honor
  85. // the current name as well.
  86. ResetNamed(name string) Logger
  87. // Return a value that conforms to the stdlib log.Logger interface
  88. StandardLogger(opts *StandardLoggerOptions) *log.Logger
  89. }
  90. type StandardLoggerOptions struct {
  91. // Indicate that some minimal parsing should be done on strings to try
  92. // and detect their level and re-emit them.
  93. // This supports the strings like [ERROR], [ERR] [TRACE], [WARN], [INFO],
  94. // [DEBUG] and strip it off before reapplying it.
  95. InferLevels bool
  96. }
  97. type LoggerOptions struct {
  98. // Name of the subsystem to prefix logs with
  99. Name string
  100. // The threshold for the logger. Anything less severe is supressed
  101. Level Level
  102. // Where to write the logs to. Defaults to os.Stdout if nil
  103. Output io.Writer
  104. // Control if the output should be in JSON.
  105. JSONFormat bool
  106. // Include file and line information in each log line
  107. IncludeLocation bool
  108. }