log.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. package log
  2. import (
  3. "fmt"
  4. "time"
  5. "k8s.io/klog"
  6. )
  7. var seen = make(map[string]int)
  8. func Errorf(format string, a ...interface{}) {
  9. klog.Errorf(fmt.Sprintf("[Error] %s", format), a...)
  10. }
  11. func DedupedErrorf(format string, logTypeLimit int, a ...interface{}) {
  12. timesLogged, ok := seen[format]
  13. if !ok {
  14. seen[format] = 1
  15. } else if timesLogged > logTypeLimit {
  16. f := fmt.Sprintf("[Error] %s", format)
  17. klog.Errorf("%s seen more than %d times, suppressing future logs", f, logTypeLimit)
  18. } else {
  19. seen[format] += 1
  20. klog.Errorf(fmt.Sprintf("[Error] %s", format), a...)
  21. }
  22. }
  23. func Warningf(format string, a ...interface{}) {
  24. klog.V(2).Infof(fmt.Sprintf("[Warning] %s", format), a...)
  25. }
  26. func DedupedWarningf(format string, logTypeLimit int, a ...interface{}) {
  27. timesLogged, ok := seen[format]
  28. if !ok {
  29. seen[format] = 1
  30. } else if timesLogged > logTypeLimit {
  31. f := fmt.Sprintf("[Error] %s", format)
  32. klog.Errorf("%s seen more than %d times, suppressing future logs", f, logTypeLimit)
  33. } else {
  34. seen[format] += 1
  35. klog.V(2).Infof(fmt.Sprintf("[Warning] %s", format), a...)
  36. }
  37. }
  38. func Infof(format string, a ...interface{}) {
  39. klog.V(3).Infof(fmt.Sprintf("[Info] %s", format), a...)
  40. }
  41. func Profilef(format string, a ...interface{}) {
  42. klog.V(3).Infof(fmt.Sprintf("[Profiler] %s", format), a...)
  43. }
  44. func Debugf(format string, a ...interface{}) {
  45. klog.V(4).Infof(fmt.Sprintf("[Debug] %s", format), a...)
  46. }
  47. func Profile(start time.Time, name string) {
  48. elapsed := time.Since(start)
  49. Profilef("%s: %s", elapsed, name)
  50. }
  51. func ProfileWithThreshold(start time.Time, threshold time.Duration, name string) {
  52. elapsed := time.Since(start)
  53. if elapsed > threshold {
  54. Profilef("%s: %s", elapsed, name)
  55. }
  56. }
  57. type Profiler struct {
  58. profiles map[string]time.Duration
  59. starts map[string]time.Time
  60. }
  61. func NewProfiler() *Profiler {
  62. return &Profiler{
  63. profiles: map[string]time.Duration{},
  64. starts: map[string]time.Time{},
  65. }
  66. }
  67. func (p *Profiler) Start(name string) {
  68. if p == nil {
  69. return
  70. }
  71. p.starts[name] = time.Now()
  72. }
  73. func (p *Profiler) Stop(name string) time.Duration {
  74. if p == nil {
  75. return 0
  76. }
  77. if start, ok := p.starts[name]; ok {
  78. elapsed := time.Since(start)
  79. p.profiles[name] += elapsed
  80. return elapsed
  81. }
  82. return 0
  83. }
  84. func (p *Profiler) Log(name string) {
  85. if p == nil {
  86. return
  87. }
  88. Profilef("%s: %s", p.profiles[name], name)
  89. }
  90. func (p *Profiler) LogAll() {
  91. if p == nil {
  92. return
  93. }
  94. // Print profiles, largest to smallest. (Inefficienct, but shouldn't matter.)
  95. print := map[string]time.Duration{}
  96. for name, value := range p.profiles {
  97. print[name] = value
  98. }
  99. for len(print) > 0 {
  100. largest := ""
  101. for name := range print {
  102. if print[name] > print[largest] {
  103. largest = name
  104. }
  105. }
  106. Profilef("%s: %s", print[largest], largest)
  107. delete(print, largest)
  108. }
  109. }