http urls monitor.

notepad.go 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // Copyright © 2016 Steve Francia <spf@spf13.com>.
  2. //
  3. // Use of this source code is governed by an MIT-style
  4. // license that can be found in the LICENSE file.
  5. package jwalterweatherman
  6. import (
  7. "fmt"
  8. "io"
  9. "log"
  10. )
  11. type Threshold int
  12. func (t Threshold) String() string {
  13. return prefixes[t]
  14. }
  15. const (
  16. LevelTrace Threshold = iota
  17. LevelDebug
  18. LevelInfo
  19. LevelWarn
  20. LevelError
  21. LevelCritical
  22. LevelFatal
  23. )
  24. var prefixes map[Threshold]string = map[Threshold]string{
  25. LevelTrace: "TRACE",
  26. LevelDebug: "DEBUG",
  27. LevelInfo: "INFO",
  28. LevelWarn: "WARN",
  29. LevelError: "ERROR",
  30. LevelCritical: "CRITICAL",
  31. LevelFatal: "FATAL",
  32. }
  33. // Notepad is where you leave a note!
  34. type Notepad struct {
  35. TRACE *log.Logger
  36. DEBUG *log.Logger
  37. INFO *log.Logger
  38. WARN *log.Logger
  39. ERROR *log.Logger
  40. CRITICAL *log.Logger
  41. FATAL *log.Logger
  42. LOG *log.Logger
  43. FEEDBACK *Feedback
  44. loggers [7]**log.Logger
  45. logHandle io.Writer
  46. outHandle io.Writer
  47. logThreshold Threshold
  48. stdoutThreshold Threshold
  49. prefix string
  50. flags int
  51. // One per Threshold
  52. logCounters [7]*logCounter
  53. }
  54. // NewNotepad create a new notepad.
  55. func NewNotepad(outThreshold Threshold, logThreshold Threshold, outHandle, logHandle io.Writer, prefix string, flags int) *Notepad {
  56. n := &Notepad{}
  57. n.loggers = [7]**log.Logger{&n.TRACE, &n.DEBUG, &n.INFO, &n.WARN, &n.ERROR, &n.CRITICAL, &n.FATAL}
  58. n.outHandle = outHandle
  59. n.logHandle = logHandle
  60. n.stdoutThreshold = outThreshold
  61. n.logThreshold = logThreshold
  62. if len(prefix) != 0 {
  63. n.prefix = "[" + prefix + "] "
  64. } else {
  65. n.prefix = ""
  66. }
  67. n.flags = flags
  68. n.LOG = log.New(n.logHandle,
  69. "LOG: ",
  70. n.flags)
  71. n.FEEDBACK = &Feedback{out: log.New(outHandle, "", 0), log: n.LOG}
  72. n.init()
  73. return n
  74. }
  75. // init creates the loggers for each level depending on the notepad thresholds.
  76. func (n *Notepad) init() {
  77. logAndOut := io.MultiWriter(n.outHandle, n.logHandle)
  78. for t, logger := range n.loggers {
  79. threshold := Threshold(t)
  80. counter := &logCounter{}
  81. n.logCounters[t] = counter
  82. prefix := n.prefix + threshold.String() + " "
  83. switch {
  84. case threshold >= n.logThreshold && threshold >= n.stdoutThreshold:
  85. *logger = log.New(io.MultiWriter(counter, logAndOut), prefix, n.flags)
  86. case threshold >= n.logThreshold:
  87. *logger = log.New(io.MultiWriter(counter, n.logHandle), prefix, n.flags)
  88. case threshold >= n.stdoutThreshold:
  89. *logger = log.New(io.MultiWriter(counter, n.outHandle), prefix, n.flags)
  90. default:
  91. // counter doesn't care about prefix and flags, so don't use them
  92. // for performance.
  93. *logger = log.New(counter, "", 0)
  94. }
  95. }
  96. }
  97. // SetLogThreshold changes the threshold above which messages are written to the
  98. // log file.
  99. func (n *Notepad) SetLogThreshold(threshold Threshold) {
  100. n.logThreshold = threshold
  101. n.init()
  102. }
  103. // SetLogOutput changes the file where log messages are written.
  104. func (n *Notepad) SetLogOutput(handle io.Writer) {
  105. n.logHandle = handle
  106. n.init()
  107. }
  108. // GetStdoutThreshold returns the defined Treshold for the log logger.
  109. func (n *Notepad) GetLogThreshold() Threshold {
  110. return n.logThreshold
  111. }
  112. // SetStdoutThreshold changes the threshold above which messages are written to the
  113. // standard output.
  114. func (n *Notepad) SetStdoutThreshold(threshold Threshold) {
  115. n.stdoutThreshold = threshold
  116. n.init()
  117. }
  118. // GetStdoutThreshold returns the Treshold for the stdout logger.
  119. func (n *Notepad) GetStdoutThreshold() Threshold {
  120. return n.stdoutThreshold
  121. }
  122. // SetPrefix changes the prefix used by the notepad. Prefixes are displayed between
  123. // brackets at the beginning of the line. An empty prefix won't be displayed at all.
  124. func (n *Notepad) SetPrefix(prefix string) {
  125. if len(prefix) != 0 {
  126. n.prefix = "[" + prefix + "] "
  127. } else {
  128. n.prefix = ""
  129. }
  130. n.init()
  131. }
  132. // SetFlags choose which flags the logger will display (after prefix and message
  133. // level). See the package log for more informations on this.
  134. func (n *Notepad) SetFlags(flags int) {
  135. n.flags = flags
  136. n.init()
  137. }
  138. // Feedback writes plainly to the outHandle while
  139. // logging with the standard extra information (date, file, etc).
  140. type Feedback struct {
  141. out *log.Logger
  142. log *log.Logger
  143. }
  144. func (fb *Feedback) Println(v ...interface{}) {
  145. fb.output(fmt.Sprintln(v...))
  146. }
  147. func (fb *Feedback) Printf(format string, v ...interface{}) {
  148. fb.output(fmt.Sprintf(format, v...))
  149. }
  150. func (fb *Feedback) Print(v ...interface{}) {
  151. fb.output(fmt.Sprint(v...))
  152. }
  153. func (fb *Feedback) output(s string) {
  154. if fb.out != nil {
  155. fb.out.Output(2, s)
  156. }
  157. if fb.log != nil {
  158. fb.log.Output(2, s)
  159. }
  160. }