You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
2.8 KiB

8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
  1. package log
  2. import "fmt"
  3. // NewFilter wraps next and implements filtering. See the commentary on the
  4. // Option functions for a detailed description of how to configure levels. If
  5. // no options are provided, all leveled log events created with Debug, Info or
  6. // Error helper methods are squelched.
  7. func NewFilter(next Logger, options ...Option) Logger {
  8. l := &filter{
  9. next: next,
  10. }
  11. for _, option := range options {
  12. option(l)
  13. }
  14. return l
  15. }
  16. // NewFilterByLevel wraps next and implements filtering based on a given level.
  17. func NewFilterByLevel(next Logger, lvl string) Logger {
  18. var option Option
  19. switch lvl {
  20. case "info":
  21. option = AllowInfo()
  22. case "debug":
  23. option = AllowDebug()
  24. case "error":
  25. option = AllowError()
  26. default:
  27. panic(fmt.Sprintf("Expected either \"info\", \"debug\" or \"error\" log level, given %v", lvl))
  28. }
  29. return NewFilter(next, option)
  30. }
  31. type filter struct {
  32. next Logger
  33. allowed level
  34. errNotAllowed error
  35. }
  36. func (l *filter) Info(msg string, keyvals ...interface{}) error {
  37. levelAllowed := l.allowed&levelInfo != 0
  38. if !levelAllowed {
  39. return l.errNotAllowed
  40. }
  41. return l.next.Info(msg, keyvals...)
  42. }
  43. func (l *filter) Debug(msg string, keyvals ...interface{}) error {
  44. levelAllowed := l.allowed&levelDebug != 0
  45. if !levelAllowed {
  46. return l.errNotAllowed
  47. }
  48. return l.next.Debug(msg, keyvals...)
  49. }
  50. func (l *filter) Error(msg string, keyvals ...interface{}) error {
  51. levelAllowed := l.allowed&levelError != 0
  52. if !levelAllowed {
  53. return l.errNotAllowed
  54. }
  55. return l.next.Error(msg, keyvals...)
  56. }
  57. func (l *filter) With(keyvals ...interface{}) Logger {
  58. return &filter{next: l.next.With(keyvals...), allowed: l.allowed, errNotAllowed: l.errNotAllowed}
  59. }
  60. // Option sets a parameter for the filter.
  61. type Option func(*filter)
  62. // AllowAll is an alias for AllowDebug.
  63. func AllowAll() Option {
  64. return AllowDebug()
  65. }
  66. // AllowDebug allows error, info and debug level log events to pass.
  67. func AllowDebug() Option {
  68. return allowed(levelError | levelInfo | levelDebug)
  69. }
  70. // AllowInfo allows error and info level log events to pass.
  71. func AllowInfo() Option {
  72. return allowed(levelError | levelInfo)
  73. }
  74. // AllowError allows only error level log events to pass.
  75. func AllowError() Option {
  76. return allowed(levelError)
  77. }
  78. // AllowNone allows no leveled log events to pass.
  79. func AllowNone() Option {
  80. return allowed(0)
  81. }
  82. func allowed(allowed level) Option {
  83. return func(l *filter) { l.allowed = allowed }
  84. }
  85. // ErrNotAllowed sets the error to return from Log when it squelches a log
  86. // event disallowed by the configured Allow[Level] option. By default,
  87. // ErrNotAllowed is nil; in this case the log event is squelched with no
  88. // error.
  89. func ErrNotAllowed(err error) Option {
  90. return func(l *filter) { l.errNotAllowed = err }
  91. }
  92. type level byte
  93. const (
  94. levelDebug level = 1 << iota
  95. levelInfo
  96. levelError
  97. )