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.

116 lines
2.9 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. // Error is returned if level is not info, error or debug.
  18. func NewFilterByLevel(next Logger, lvl string) (Logger, error) {
  19. var option Option
  20. switch lvl {
  21. case "info":
  22. option = AllowInfo()
  23. case "debug":
  24. option = AllowDebug()
  25. case "error":
  26. option = AllowError()
  27. default:
  28. return nil, fmt.Errorf("Expected either \"info\", \"debug\" or \"error\" log level, given %v", lvl)
  29. }
  30. return NewFilter(next, option), nil
  31. }
  32. type filter struct {
  33. next Logger
  34. allowed level
  35. errNotAllowed error
  36. }
  37. func (l *filter) Info(msg string, keyvals ...interface{}) error {
  38. levelAllowed := l.allowed&levelInfo != 0
  39. if !levelAllowed {
  40. return l.errNotAllowed
  41. }
  42. return l.next.Info(msg, keyvals...)
  43. }
  44. func (l *filter) Debug(msg string, keyvals ...interface{}) error {
  45. levelAllowed := l.allowed&levelDebug != 0
  46. if !levelAllowed {
  47. return l.errNotAllowed
  48. }
  49. return l.next.Debug(msg, keyvals...)
  50. }
  51. func (l *filter) Error(msg string, keyvals ...interface{}) error {
  52. levelAllowed := l.allowed&levelError != 0
  53. if !levelAllowed {
  54. return l.errNotAllowed
  55. }
  56. return l.next.Error(msg, keyvals...)
  57. }
  58. func (l *filter) With(keyvals ...interface{}) Logger {
  59. return &filter{next: l.next.With(keyvals...), allowed: l.allowed, errNotAllowed: l.errNotAllowed}
  60. }
  61. // Option sets a parameter for the filter.
  62. type Option func(*filter)
  63. // AllowAll is an alias for AllowDebug.
  64. func AllowAll() Option {
  65. return AllowDebug()
  66. }
  67. // AllowDebug allows error, info and debug level log events to pass.
  68. func AllowDebug() Option {
  69. return allowed(levelError | levelInfo | levelDebug)
  70. }
  71. // AllowInfo allows error and info level log events to pass.
  72. func AllowInfo() Option {
  73. return allowed(levelError | levelInfo)
  74. }
  75. // AllowError allows only error level log events to pass.
  76. func AllowError() Option {
  77. return allowed(levelError)
  78. }
  79. // AllowNone allows no leveled log events to pass.
  80. func AllowNone() Option {
  81. return allowed(0)
  82. }
  83. func allowed(allowed level) Option {
  84. return func(l *filter) { l.allowed = allowed }
  85. }
  86. // ErrNotAllowed sets the error to return from Log when it squelches a log
  87. // event disallowed by the configured Allow[Level] option. By default,
  88. // ErrNotAllowed is nil; in this case the log event is squelched with no
  89. // error.
  90. func ErrNotAllowed(err error) Option {
  91. return func(l *filter) { l.errNotAllowed = err }
  92. }
  93. type level byte
  94. const (
  95. levelDebug level = 1 << iota
  96. levelInfo
  97. levelError
  98. )