zapgrpc.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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 zapgrpc provides a logger that is compatible with grpclog.
  21. package zapgrpc // import "go.uber.org/zap/zapgrpc"
  22. import (
  23. "fmt"
  24. "go.uber.org/zap"
  25. "go.uber.org/zap/zapcore"
  26. )
  27. // See https://github.com/grpc/grpc-go/blob/v1.35.0/grpclog/loggerv2.go#L77-L86
  28. const (
  29. grpcLvlInfo = 0
  30. grpcLvlWarn = 1
  31. grpcLvlError = 2
  32. grpcLvlFatal = 3
  33. )
  34. var (
  35. // _grpcToZapLevel maps gRPC log levels to zap log levels.
  36. // See https://pkg.go.dev/go.uber.org/zap@v1.16.0/zapcore#Level
  37. _grpcToZapLevel = map[int]zapcore.Level{
  38. grpcLvlInfo: zapcore.InfoLevel,
  39. grpcLvlWarn: zapcore.WarnLevel,
  40. grpcLvlError: zapcore.ErrorLevel,
  41. grpcLvlFatal: zapcore.FatalLevel,
  42. }
  43. )
  44. // An Option overrides a Logger's default configuration.
  45. type Option interface {
  46. apply(*Logger)
  47. }
  48. type optionFunc func(*Logger)
  49. func (f optionFunc) apply(log *Logger) {
  50. f(log)
  51. }
  52. // WithDebug configures a Logger to print at zap's DebugLevel instead of
  53. // InfoLevel.
  54. // It only affects the Printf, Println and Print methods, which are only used in the gRPC v1 grpclog.Logger API.
  55. //
  56. // Deprecated: use grpclog.SetLoggerV2() for v2 API.
  57. func WithDebug() Option {
  58. return optionFunc(func(logger *Logger) {
  59. logger.print = &printer{
  60. enab: logger.levelEnabler,
  61. level: zapcore.DebugLevel,
  62. print: logger.delegate.Debug,
  63. printf: logger.delegate.Debugf,
  64. }
  65. })
  66. }
  67. // withWarn redirects the fatal level to the warn level, which makes testing
  68. // easier. This is intentionally unexported.
  69. func withWarn() Option {
  70. return optionFunc(func(logger *Logger) {
  71. logger.fatal = &printer{
  72. enab: logger.levelEnabler,
  73. level: zapcore.WarnLevel,
  74. print: logger.delegate.Warn,
  75. printf: logger.delegate.Warnf,
  76. }
  77. })
  78. }
  79. // NewLogger returns a new Logger.
  80. func NewLogger(l *zap.Logger, options ...Option) *Logger {
  81. logger := &Logger{
  82. delegate: l.Sugar(),
  83. levelEnabler: l.Core(),
  84. }
  85. logger.print = &printer{
  86. enab: logger.levelEnabler,
  87. level: zapcore.InfoLevel,
  88. print: logger.delegate.Info,
  89. printf: logger.delegate.Infof,
  90. }
  91. logger.fatal = &printer{
  92. enab: logger.levelEnabler,
  93. level: zapcore.FatalLevel,
  94. print: logger.delegate.Fatal,
  95. printf: logger.delegate.Fatalf,
  96. }
  97. for _, option := range options {
  98. option.apply(logger)
  99. }
  100. return logger
  101. }
  102. // printer implements Print, Printf, and Println operations for a Zap level.
  103. //
  104. // We use it to customize Debug vs Info, and Warn vs Fatal for Print and Fatal
  105. // respectively.
  106. type printer struct {
  107. enab zapcore.LevelEnabler
  108. level zapcore.Level
  109. print func(...interface{})
  110. printf func(string, ...interface{})
  111. }
  112. func (v *printer) Print(args ...interface{}) {
  113. v.print(args...)
  114. }
  115. func (v *printer) Printf(format string, args ...interface{}) {
  116. v.printf(format, args...)
  117. }
  118. func (v *printer) Println(args ...interface{}) {
  119. if v.enab.Enabled(v.level) {
  120. v.print(sprintln(args))
  121. }
  122. }
  123. // Logger adapts zap's Logger to be compatible with grpclog.LoggerV2 and the deprecated grpclog.Logger.
  124. type Logger struct {
  125. delegate *zap.SugaredLogger
  126. levelEnabler zapcore.LevelEnabler
  127. print *printer
  128. fatal *printer
  129. // printToDebug bool
  130. // fatalToWarn bool
  131. }
  132. // Print implements grpclog.Logger.
  133. //
  134. // Deprecated: use [Logger.Info].
  135. func (l *Logger) Print(args ...interface{}) {
  136. l.print.Print(args...)
  137. }
  138. // Printf implements grpclog.Logger.
  139. //
  140. // Deprecated: use [Logger.Infof].
  141. func (l *Logger) Printf(format string, args ...interface{}) {
  142. l.print.Printf(format, args...)
  143. }
  144. // Println implements grpclog.Logger.
  145. //
  146. // Deprecated: use [Logger.Info].
  147. func (l *Logger) Println(args ...interface{}) {
  148. l.print.Println(args...)
  149. }
  150. // Info implements grpclog.LoggerV2.
  151. func (l *Logger) Info(args ...interface{}) {
  152. l.delegate.Info(args...)
  153. }
  154. // Infoln implements grpclog.LoggerV2.
  155. func (l *Logger) Infoln(args ...interface{}) {
  156. if l.levelEnabler.Enabled(zapcore.InfoLevel) {
  157. l.delegate.Info(sprintln(args))
  158. }
  159. }
  160. // Infof implements grpclog.LoggerV2.
  161. func (l *Logger) Infof(format string, args ...interface{}) {
  162. l.delegate.Infof(format, args...)
  163. }
  164. // Warning implements grpclog.LoggerV2.
  165. func (l *Logger) Warning(args ...interface{}) {
  166. l.delegate.Warn(args...)
  167. }
  168. // Warningln implements grpclog.LoggerV2.
  169. func (l *Logger) Warningln(args ...interface{}) {
  170. if l.levelEnabler.Enabled(zapcore.WarnLevel) {
  171. l.delegate.Warn(sprintln(args))
  172. }
  173. }
  174. // Warningf implements grpclog.LoggerV2.
  175. func (l *Logger) Warningf(format string, args ...interface{}) {
  176. l.delegate.Warnf(format, args...)
  177. }
  178. // Error implements grpclog.LoggerV2.
  179. func (l *Logger) Error(args ...interface{}) {
  180. l.delegate.Error(args...)
  181. }
  182. // Errorln implements grpclog.LoggerV2.
  183. func (l *Logger) Errorln(args ...interface{}) {
  184. if l.levelEnabler.Enabled(zapcore.ErrorLevel) {
  185. l.delegate.Error(sprintln(args))
  186. }
  187. }
  188. // Errorf implements grpclog.LoggerV2.
  189. func (l *Logger) Errorf(format string, args ...interface{}) {
  190. l.delegate.Errorf(format, args...)
  191. }
  192. // Fatal implements grpclog.LoggerV2.
  193. func (l *Logger) Fatal(args ...interface{}) {
  194. l.fatal.Print(args...)
  195. }
  196. // Fatalln implements grpclog.LoggerV2.
  197. func (l *Logger) Fatalln(args ...interface{}) {
  198. l.fatal.Println(args...)
  199. }
  200. // Fatalf implements grpclog.LoggerV2.
  201. func (l *Logger) Fatalf(format string, args ...interface{}) {
  202. l.fatal.Printf(format, args...)
  203. }
  204. // V implements grpclog.LoggerV2.
  205. func (l *Logger) V(level int) bool {
  206. return l.levelEnabler.Enabled(_grpcToZapLevel[level])
  207. }
  208. func sprintln(args []interface{}) string {
  209. s := fmt.Sprintln(args...)
  210. // Drop the new line character added by Sprintln
  211. return s[:len(s)-1]
  212. }