options.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // Copyright (c) 2016 Uber Technologies, Inc.
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in
  11. // all copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. // THE SOFTWARE.
  20. package zap
  21. import (
  22. "fmt"
  23. "go.uber.org/zap/zapcore"
  24. )
  25. // An Option configures a Logger.
  26. type Option interface {
  27. apply(*Logger)
  28. }
  29. // optionFunc wraps a func so it satisfies the Option interface.
  30. type optionFunc func(*Logger)
  31. func (f optionFunc) apply(log *Logger) {
  32. f(log)
  33. }
  34. // WrapCore wraps or replaces the Logger's underlying zapcore.Core.
  35. func WrapCore(f func(zapcore.Core) zapcore.Core) Option {
  36. return optionFunc(func(log *Logger) {
  37. log.core = f(log.core)
  38. })
  39. }
  40. // Hooks registers functions which will be called each time the Logger writes
  41. // out an Entry. Repeated use of Hooks is additive.
  42. //
  43. // Hooks are useful for simple side effects, like capturing metrics for the
  44. // number of emitted logs. More complex side effects, including anything that
  45. // requires access to the Entry's structured fields, should be implemented as
  46. // a zapcore.Core instead. See zapcore.RegisterHooks for details.
  47. func Hooks(hooks ...func(zapcore.Entry) error) Option {
  48. return optionFunc(func(log *Logger) {
  49. log.core = zapcore.RegisterHooks(log.core, hooks...)
  50. })
  51. }
  52. // Fields adds fields to the Logger.
  53. func Fields(fs ...Field) Option {
  54. return optionFunc(func(log *Logger) {
  55. log.core = log.core.With(fs)
  56. })
  57. }
  58. // ErrorOutput sets the destination for errors generated by the Logger. Note
  59. // that this option only affects internal errors; for sample code that sends
  60. // error-level logs to a different location from info- and debug-level logs,
  61. // see the package-level AdvancedConfiguration example.
  62. //
  63. // The supplied WriteSyncer must be safe for concurrent use. The Open and
  64. // zapcore.Lock functions are the simplest ways to protect files with a mutex.
  65. func ErrorOutput(w zapcore.WriteSyncer) Option {
  66. return optionFunc(func(log *Logger) {
  67. log.errorOutput = w
  68. })
  69. }
  70. // Development puts the logger in development mode, which makes DPanic-level
  71. // logs panic instead of simply logging an error.
  72. func Development() Option {
  73. return optionFunc(func(log *Logger) {
  74. log.development = true
  75. })
  76. }
  77. // AddCaller configures the Logger to annotate each message with the filename,
  78. // line number, and function name of zap's caller. See also WithCaller.
  79. func AddCaller() Option {
  80. return WithCaller(true)
  81. }
  82. // WithCaller configures the Logger to annotate each message with the filename,
  83. // line number, and function name of zap's caller, or not, depending on the
  84. // value of enabled. This is a generalized form of AddCaller.
  85. func WithCaller(enabled bool) Option {
  86. return optionFunc(func(log *Logger) {
  87. log.addCaller = enabled
  88. })
  89. }
  90. // AddCallerSkip increases the number of callers skipped by caller annotation
  91. // (as enabled by the AddCaller option). When building wrappers around the
  92. // Logger and SugaredLogger, supplying this Option prevents zap from always
  93. // reporting the wrapper code as the caller.
  94. func AddCallerSkip(skip int) Option {
  95. return optionFunc(func(log *Logger) {
  96. log.callerSkip += skip
  97. })
  98. }
  99. // AddStacktrace configures the Logger to record a stack trace for all messages at
  100. // or above a given level.
  101. func AddStacktrace(lvl zapcore.LevelEnabler) Option {
  102. return optionFunc(func(log *Logger) {
  103. log.addStack = lvl
  104. })
  105. }
  106. // IncreaseLevel increase the level of the logger. It has no effect if
  107. // the passed in level tries to decrease the level of the logger.
  108. func IncreaseLevel(lvl zapcore.LevelEnabler) Option {
  109. return optionFunc(func(log *Logger) {
  110. core, err := zapcore.NewIncreaseLevelCore(log.core, lvl)
  111. if err != nil {
  112. fmt.Fprintf(log.errorOutput, "failed to IncreaseLevel: %v\n", err)
  113. } else {
  114. log.core = core
  115. }
  116. })
  117. }
  118. // OnFatal sets the action to take on fatal logs.
  119. func OnFatal(action zapcore.CheckWriteAction) Option {
  120. return optionFunc(func(log *Logger) {
  121. log.onFatal = action
  122. })
  123. }
  124. // WithClock specifies the clock used by the logger to determine the current
  125. // time for logged entries. Defaults to the system clock with time.Now.
  126. func WithClock(clock zapcore.Clock) Option {
  127. return optionFunc(func(log *Logger) {
  128. log.clock = clock
  129. })
  130. }