default.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. package log
  2. import (
  3. "context"
  4. "fmt"
  5. "io"
  6. "log"
  7. "os"
  8. "github.com/gofiber/utils/v2"
  9. "github.com/valyala/bytebufferpool"
  10. )
  11. var _ AllLogger[*log.Logger] = (*defaultLogger)(nil)
  12. type defaultLogger struct {
  13. stdlog *log.Logger
  14. level Level
  15. depth int
  16. }
  17. // privateLog logs a message at a given level log the default logger.
  18. // when the level is fatal, it will exit the program.
  19. func (l *defaultLogger) privateLog(lv Level, fmtArgs []any) {
  20. if l.level > lv {
  21. return
  22. }
  23. level := lv.toString()
  24. buf := bytebufferpool.Get()
  25. buf.WriteString(level)
  26. fmt.Fprint(buf, fmtArgs...)
  27. _ = l.stdlog.Output(l.depth, buf.String()) //nolint:errcheck // It is fine to ignore the error
  28. if lv == LevelPanic {
  29. panic(buf.String())
  30. }
  31. buf.Reset()
  32. bytebufferpool.Put(buf)
  33. if lv == LevelFatal {
  34. os.Exit(1) //nolint:revive // we want to exit the program when Fatal is called
  35. }
  36. }
  37. // privateLogf logs a formatted message at a given level log the default logger.
  38. // when the level is fatal, it will exit the program.
  39. func (l *defaultLogger) privateLogf(lv Level, format string, fmtArgs []any) {
  40. if l.level > lv {
  41. return
  42. }
  43. level := lv.toString()
  44. buf := bytebufferpool.Get()
  45. buf.WriteString(level)
  46. if len(fmtArgs) > 0 {
  47. _, _ = fmt.Fprintf(buf, format, fmtArgs...)
  48. } else {
  49. _, _ = fmt.Fprint(buf, format)
  50. }
  51. _ = l.stdlog.Output(l.depth, buf.String()) //nolint:errcheck // It is fine to ignore the error
  52. if lv == LevelPanic {
  53. panic(buf.String())
  54. }
  55. buf.Reset()
  56. bytebufferpool.Put(buf)
  57. if lv == LevelFatal {
  58. os.Exit(1) //nolint:revive // we want to exit the program when Fatal is called
  59. }
  60. }
  61. // privateLogw logs a message at a given level log the default logger.
  62. // when the level is fatal, it will exit the program.
  63. func (l *defaultLogger) privateLogw(lv Level, format string, keysAndValues []any) {
  64. if l.level > lv {
  65. return
  66. }
  67. level := lv.toString()
  68. buf := bytebufferpool.Get()
  69. buf.WriteString(level)
  70. // Write format privateLog buffer
  71. if format != "" {
  72. buf.WriteString(format)
  73. }
  74. // Write keys and values privateLog buffer
  75. if len(keysAndValues) > 0 {
  76. if (len(keysAndValues) & 1) == 1 {
  77. keysAndValues = append(keysAndValues, "KEYVALS UNPAIRED")
  78. }
  79. for i := 0; i < len(keysAndValues); i += 2 {
  80. if i > 0 || format != "" {
  81. buf.WriteByte(' ')
  82. }
  83. switch key := keysAndValues[i].(type) {
  84. case string:
  85. buf.WriteString(key)
  86. default:
  87. _, _ = fmt.Fprint(buf, key)
  88. }
  89. buf.WriteByte('=')
  90. buf.WriteString(utils.ToString(keysAndValues[i+1]))
  91. }
  92. }
  93. _ = l.stdlog.Output(l.depth, buf.String()) //nolint:errcheck // It is fine to ignore the error
  94. if lv == LevelPanic {
  95. panic(buf.String())
  96. }
  97. buf.Reset()
  98. bytebufferpool.Put(buf)
  99. if lv == LevelFatal {
  100. os.Exit(1) //nolint:revive // we want to exit the program when Fatal is called
  101. }
  102. }
  103. // Trace logs the given values at trace level.
  104. func (l *defaultLogger) Trace(v ...any) {
  105. l.privateLog(LevelTrace, v)
  106. }
  107. // Debug logs the given values at debug level.
  108. func (l *defaultLogger) Debug(v ...any) {
  109. l.privateLog(LevelDebug, v)
  110. }
  111. // Info logs the given values at info level.
  112. func (l *defaultLogger) Info(v ...any) {
  113. l.privateLog(LevelInfo, v)
  114. }
  115. // Warn logs the given values at warn level.
  116. func (l *defaultLogger) Warn(v ...any) {
  117. l.privateLog(LevelWarn, v)
  118. }
  119. // Error logs the given values at error level.
  120. func (l *defaultLogger) Error(v ...any) {
  121. l.privateLog(LevelError, v)
  122. }
  123. // Fatal logs the given values at fatal level and terminates the process.
  124. func (l *defaultLogger) Fatal(v ...any) {
  125. l.privateLog(LevelFatal, v)
  126. }
  127. // Panic logs the given values at panic level and panics.
  128. func (l *defaultLogger) Panic(v ...any) {
  129. l.privateLog(LevelPanic, v)
  130. }
  131. // Tracef formats according to a format specifier and logs at trace level.
  132. func (l *defaultLogger) Tracef(format string, v ...any) {
  133. l.privateLogf(LevelTrace, format, v)
  134. }
  135. // Debugf formats according to a format specifier and logs at debug level.
  136. func (l *defaultLogger) Debugf(format string, v ...any) {
  137. l.privateLogf(LevelDebug, format, v)
  138. }
  139. // Infof formats according to a format specifier and logs at info level.
  140. func (l *defaultLogger) Infof(format string, v ...any) {
  141. l.privateLogf(LevelInfo, format, v)
  142. }
  143. // Warnf formats according to a format specifier and logs at warn level.
  144. func (l *defaultLogger) Warnf(format string, v ...any) {
  145. l.privateLogf(LevelWarn, format, v)
  146. }
  147. // Errorf formats according to a format specifier and logs at error level.
  148. func (l *defaultLogger) Errorf(format string, v ...any) {
  149. l.privateLogf(LevelError, format, v)
  150. }
  151. // Fatalf formats according to a format specifier, logs at fatal level, and terminates the process.
  152. func (l *defaultLogger) Fatalf(format string, v ...any) {
  153. l.privateLogf(LevelFatal, format, v)
  154. }
  155. // Panicf formats according to a format specifier, logs at panic level, and panics.
  156. func (l *defaultLogger) Panicf(format string, v ...any) {
  157. l.privateLogf(LevelPanic, format, v)
  158. }
  159. // Tracew logs at trace level with a message and key/value pairs.
  160. func (l *defaultLogger) Tracew(msg string, keysAndValues ...any) {
  161. l.privateLogw(LevelTrace, msg, keysAndValues)
  162. }
  163. // Debugw logs at debug level with a message and key/value pairs.
  164. func (l *defaultLogger) Debugw(msg string, keysAndValues ...any) {
  165. l.privateLogw(LevelDebug, msg, keysAndValues)
  166. }
  167. // Infow logs at info level with a message and key/value pairs.
  168. func (l *defaultLogger) Infow(msg string, keysAndValues ...any) {
  169. l.privateLogw(LevelInfo, msg, keysAndValues)
  170. }
  171. // Warnw logs at warn level with a message and key/value pairs.
  172. func (l *defaultLogger) Warnw(msg string, keysAndValues ...any) {
  173. l.privateLogw(LevelWarn, msg, keysAndValues)
  174. }
  175. // Errorw logs at error level with a message and key/value pairs.
  176. func (l *defaultLogger) Errorw(msg string, keysAndValues ...any) {
  177. l.privateLogw(LevelError, msg, keysAndValues)
  178. }
  179. // Fatalw logs at fatal level with a message and key/value pairs, then terminates the process.
  180. func (l *defaultLogger) Fatalw(msg string, keysAndValues ...any) {
  181. l.privateLogw(LevelFatal, msg, keysAndValues)
  182. }
  183. // Panicw logs at panic level with a message and key/value pairs, then panics.
  184. func (l *defaultLogger) Panicw(msg string, keysAndValues ...any) {
  185. l.privateLogw(LevelPanic, msg, keysAndValues)
  186. }
  187. // WithContext returns a logger that shares the underlying output but adjusts the call depth.
  188. func (l *defaultLogger) WithContext(_ context.Context) CommonLogger {
  189. return &defaultLogger{
  190. stdlog: l.stdlog,
  191. level: l.level,
  192. depth: l.depth - 1,
  193. }
  194. }
  195. // SetLevel updates the minimum level that will be emitted by the logger.
  196. func (l *defaultLogger) SetLevel(level Level) {
  197. l.level = level
  198. }
  199. // SetOutput replaces the underlying writer used by the logger.
  200. func (l *defaultLogger) SetOutput(writer io.Writer) {
  201. l.stdlog.SetOutput(writer)
  202. }
  203. // Logger returns the logger instance. It can be used to adjust the logger configurations in case of need.
  204. func (l *defaultLogger) Logger() *log.Logger {
  205. return l.stdlog
  206. }
  207. // DefaultLogger returns the default logger.
  208. func DefaultLogger[T any]() AllLogger[T] {
  209. if l, ok := logger.(AllLogger[T]); ok {
  210. return l
  211. }
  212. return nil
  213. }