context.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. package log
  2. import (
  3. "path"
  4. "github.com/Sirupsen/logrus"
  5. "golang.org/x/net/context"
  6. )
  7. var (
  8. // G is an alias for GetLogger.
  9. //
  10. // We may want to define this locally to a package to get package tagged log
  11. // messages.
  12. G = GetLogger
  13. // L is an alias for the the standard logger.
  14. L = logrus.NewEntry(logrus.StandardLogger())
  15. )
  16. type (
  17. loggerKey struct{}
  18. moduleKey struct{}
  19. )
  20. // WithLogger returns a new context with the provided logger. Use in
  21. // combination with logger.WithField(s) for great effect.
  22. func WithLogger(ctx context.Context, logger *logrus.Entry) context.Context {
  23. return context.WithValue(ctx, loggerKey{}, logger)
  24. }
  25. // WithFields returns a new context with added fields to logger.
  26. func WithFields(ctx context.Context, fields logrus.Fields) context.Context {
  27. logger := ctx.Value(loggerKey{})
  28. if logger == nil {
  29. logger = L
  30. }
  31. return WithLogger(ctx, logger.(*logrus.Entry).WithFields(fields))
  32. }
  33. // WithField is convenience wrapper around WithFields.
  34. func WithField(ctx context.Context, key, value string) context.Context {
  35. return WithFields(ctx, logrus.Fields{key: value})
  36. }
  37. // GetLogger retrieves the current logger from the context. If no logger is
  38. // available, the default logger is returned.
  39. func GetLogger(ctx context.Context) *logrus.Entry {
  40. logger := ctx.Value(loggerKey{})
  41. if logger == nil {
  42. return L
  43. }
  44. return logger.(*logrus.Entry)
  45. }
  46. // WithModule adds the module to the context, appending it with a slash if a
  47. // module already exists. A module is just a roughly correlated defined by the
  48. // call tree for a given context.
  49. //
  50. // As an example, we might have a "node" module already part of a context. If
  51. // this function is called with "tls", the new value of module will be
  52. // "node/tls".
  53. //
  54. // Modules represent the call path. If the new module and last module are the
  55. // same, a new module entry will not be created. If the new module and old
  56. // older module are the same but separated by other modules, the cycle will be
  57. // represented by the module path.
  58. func WithModule(ctx context.Context, module string) context.Context {
  59. parent := GetModulePath(ctx)
  60. if parent != "" {
  61. // don't re-append module when module is the same.
  62. if path.Base(parent) == module {
  63. return ctx
  64. }
  65. module = path.Join(parent, module)
  66. }
  67. ctx = WithLogger(ctx, GetLogger(ctx).WithField("module", module))
  68. return context.WithValue(ctx, moduleKey{}, module)
  69. }
  70. // GetModulePath returns the module path for the provided context. If no module
  71. // is set, an empty string is returned.
  72. func GetModulePath(ctx context.Context) string {
  73. module := ctx.Value(moduleKey{})
  74. if module == nil {
  75. return ""
  76. }
  77. return module.(string)
  78. }