report-rules.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. package log
  2. import (
  3. "io"
  4. "log"
  5. "os"
  6. "sync"
  7. g "github.com/anacrolix/generics"
  8. )
  9. type nameToAny struct {
  10. emptyCase bool
  11. children map[string]*nameToAny
  12. }
  13. var reportedNames reportedNamesType
  14. type reportedNamesType struct {
  15. mu sync.Mutex
  16. base nameToAny
  17. }
  18. func putReportInner(toAny *nameToAny, names []string) bool {
  19. if len(names) == 0 {
  20. if toAny.emptyCase {
  21. return false
  22. }
  23. toAny.emptyCase = true
  24. return true
  25. }
  26. g.MakeMapIfNil(&toAny.children)
  27. child, ok := toAny.children[names[0]]
  28. if !ok {
  29. child = new(nameToAny)
  30. toAny.children[names[0]] = child
  31. }
  32. return putReportInner(child, names[1:])
  33. }
  34. // Prevent duplicate logs about the same series of names.
  35. func (me *reportedNamesType) putReport(names []string) bool {
  36. me.mu.Lock()
  37. defer me.mu.Unlock()
  38. return putReportInner(&me.base, names)
  39. }
  40. var reportRulesLogger = log.New(os.Stderr, "anacrolix/log: ", 0)
  41. func init() {
  42. if os.Getenv(EnvReportRules) == "" {
  43. reportRulesLogger.SetOutput(io.Discard)
  44. }
  45. }
  46. func reportLevelFromRules(level Level, ok bool, names []string) {
  47. if !reportedNames.putReport(names) {
  48. return
  49. }
  50. if !ok {
  51. reportRulesLogger.Printf("no rule matched for %q", names)
  52. return
  53. }
  54. reportRulesLogger.Printf("got level %v for %q", level.LogString(), names)
  55. }