logger.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package context
  2. import (
  3. "fmt"
  4. "github.com/Sirupsen/logrus"
  5. )
  6. // Logger provides a leveled-logging interface.
  7. type Logger interface {
  8. // standard logger methods
  9. Print(args ...interface{})
  10. Printf(format string, args ...interface{})
  11. Println(args ...interface{})
  12. Fatal(args ...interface{})
  13. Fatalf(format string, args ...interface{})
  14. Fatalln(args ...interface{})
  15. Panic(args ...interface{})
  16. Panicf(format string, args ...interface{})
  17. Panicln(args ...interface{})
  18. // Leveled methods, from logrus
  19. Debug(args ...interface{})
  20. Debugf(format string, args ...interface{})
  21. Debugln(args ...interface{})
  22. Error(args ...interface{})
  23. Errorf(format string, args ...interface{})
  24. Errorln(args ...interface{})
  25. Info(args ...interface{})
  26. Infof(format string, args ...interface{})
  27. Infoln(args ...interface{})
  28. Warn(args ...interface{})
  29. Warnf(format string, args ...interface{})
  30. Warnln(args ...interface{})
  31. }
  32. // WithLogger creates a new context with provided logger.
  33. func WithLogger(ctx Context, logger Logger) Context {
  34. return WithValue(ctx, "logger", logger)
  35. }
  36. // GetLoggerWithField returns a logger instance with the specified field key
  37. // and value without affecting the context. Extra specified keys will be
  38. // resolved from the context.
  39. func GetLoggerWithField(ctx Context, key, value interface{}, keys ...interface{}) Logger {
  40. return getLogrusLogger(ctx, keys...).WithField(fmt.Sprint(key), value)
  41. }
  42. // GetLoggerWithFields returns a logger instance with the specified fields
  43. // without affecting the context. Extra specified keys will be resolved from
  44. // the context.
  45. func GetLoggerWithFields(ctx Context, fields map[string]interface{}, keys ...interface{}) Logger {
  46. return getLogrusLogger(ctx, keys...).WithFields(logrus.Fields(fields))
  47. }
  48. // GetLogger returns the logger from the current context, if present. If one
  49. // or more keys are provided, they will be resolved on the context and
  50. // included in the logger. While context.Value takes an interface, any key
  51. // argument passed to GetLogger will be passed to fmt.Sprint when expanded as
  52. // a logging key field. If context keys are integer constants, for example,
  53. // its recommended that a String method is implemented.
  54. func GetLogger(ctx Context, keys ...interface{}) Logger {
  55. return getLogrusLogger(ctx, keys...)
  56. }
  57. // GetLogrusLogger returns the logrus logger for the context. If one more keys
  58. // are provided, they will be resolved on the context and included in the
  59. // logger. Only use this function if specific logrus functionality is
  60. // required.
  61. func getLogrusLogger(ctx Context, keys ...interface{}) *logrus.Entry {
  62. var logger *logrus.Entry
  63. // Get a logger, if it is present.
  64. loggerInterface := ctx.Value("logger")
  65. if loggerInterface != nil {
  66. if lgr, ok := loggerInterface.(*logrus.Entry); ok {
  67. logger = lgr
  68. }
  69. }
  70. if logger == nil {
  71. // If no logger is found, just return the standard logger.
  72. logger = logrus.NewEntry(logrus.StandardLogger())
  73. }
  74. fields := logrus.Fields{}
  75. for _, key := range keys {
  76. v := ctx.Value(key)
  77. if v != nil {
  78. fields[fmt.Sprint(key)] = v
  79. }
  80. }
  81. return logger.WithFields(fields)
  82. }