log.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. package log
  2. import (
  3. "fmt"
  4. "io"
  5. "os"
  6. "sync"
  7. "github.com/labstack/gommon/color"
  8. "github.com/mattn/go-colorable"
  9. "github.com/mattn/go-isatty"
  10. )
  11. type (
  12. Logger struct {
  13. level Level
  14. out io.Writer
  15. prefix string
  16. mu sync.Mutex
  17. }
  18. Level uint8
  19. )
  20. const (
  21. TRACE = iota
  22. DEBUG
  23. INFO
  24. NOTICE
  25. WARN
  26. ERROR
  27. FATAL
  28. OFF
  29. )
  30. var (
  31. global = New("-")
  32. levels []string
  33. )
  34. func New(prefix string) (l *Logger) {
  35. l = &Logger{
  36. level: INFO,
  37. prefix: prefix,
  38. }
  39. l.SetOutput(colorable.NewColorableStdout())
  40. return
  41. }
  42. func (l *Logger) SetPrefix(p string) {
  43. l.prefix = p
  44. }
  45. func (l *Logger) SetLevel(v Level) {
  46. l.level = v
  47. }
  48. func (l *Logger) Level() Level {
  49. return l.level
  50. }
  51. func (l *Logger) SetOutput(w io.Writer) {
  52. l.out = w
  53. color.Disable()
  54. if w, ok := w.(*os.File); ok && isatty.IsTerminal(w.Fd()) {
  55. color.Enable()
  56. }
  57. // NOTE: Reintialize levels to reflect color enable/disable call.
  58. initLevels()
  59. }
  60. func (l *Logger) Print(msg interface{}, args ...interface{}) {
  61. f := fmt.Sprintf("%s", msg)
  62. fmt.Fprintf(l.out, f, args...)
  63. }
  64. func (l *Logger) Println(msg interface{}, args ...interface{}) {
  65. f := fmt.Sprintf("%s\n", msg)
  66. fmt.Fprintf(l.out, f, args...)
  67. }
  68. func (l *Logger) Trace(msg interface{}, args ...interface{}) {
  69. l.log(TRACE, l.out, msg, args...)
  70. }
  71. func (l *Logger) Debug(msg interface{}, args ...interface{}) {
  72. l.log(DEBUG, l.out, msg, args...)
  73. }
  74. func (l *Logger) Info(msg interface{}, args ...interface{}) {
  75. l.log(INFO, l.out, msg, args...)
  76. }
  77. func (l *Logger) Notice(msg interface{}, args ...interface{}) {
  78. l.log(NOTICE, l.out, msg, args...)
  79. }
  80. func (l *Logger) Warn(msg interface{}, args ...interface{}) {
  81. l.log(WARN, l.out, msg, args...)
  82. }
  83. func (l *Logger) Error(msg interface{}, args ...interface{}) {
  84. l.log(ERROR, l.out, msg, args...)
  85. }
  86. func (l *Logger) Fatal(msg interface{}, args ...interface{}) {
  87. l.log(FATAL, l.out, msg, args...)
  88. os.Exit(1)
  89. }
  90. func SetPrefix(p string) {
  91. global.SetPrefix(p)
  92. }
  93. func SetLevel(v Level) {
  94. global.SetLevel(v)
  95. }
  96. func SetOutput(w io.Writer) {
  97. global.SetOutput(w)
  98. }
  99. func Print(msg interface{}, args ...interface{}) {
  100. global.Print(msg, args...)
  101. }
  102. func Println(msg interface{}, args ...interface{}) {
  103. global.Println(msg, args...)
  104. }
  105. func Trace(msg interface{}, args ...interface{}) {
  106. global.Trace(msg, args...)
  107. }
  108. func Debug(msg interface{}, args ...interface{}) {
  109. global.Debug(msg, args...)
  110. }
  111. func Info(msg interface{}, args ...interface{}) {
  112. global.Info(msg, args...)
  113. }
  114. func Notice(msg interface{}, args ...interface{}) {
  115. global.Notice(msg, args...)
  116. }
  117. func Warn(msg interface{}, args ...interface{}) {
  118. global.Warn(msg, args...)
  119. }
  120. func Error(msg interface{}, args ...interface{}) {
  121. global.Error(msg, args...)
  122. }
  123. func Fatal(msg interface{}, args ...interface{}) {
  124. global.Fatal(msg, args...)
  125. }
  126. func (l *Logger) log(v Level, w io.Writer, msg interface{}, args ...interface{}) {
  127. l.mu.Lock()
  128. defer l.mu.Unlock()
  129. if v >= l.level {
  130. // TODO: Improve performance
  131. f := fmt.Sprintf("%s|%s|%v\n", levels[v], l.prefix, msg)
  132. fmt.Fprintf(w, f, args...)
  133. }
  134. }
  135. func initLevels() {
  136. levels = []string{
  137. color.Cyan("TRACE"),
  138. color.Blue("DEBUG"),
  139. color.Green("INFO"),
  140. color.Magenta("NOTICE"),
  141. color.Yellow("WARN"),
  142. color.Red("ERROR"),
  143. color.RedBg("FATAL"),
  144. }
  145. }
  146. func init() {
  147. initLevels()
  148. }