log.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. package log
  2. import (
  3. "fmt"
  4. "io"
  5. "os"
  6. "sync"
  7. "github.com/mattn/go-colorable"
  8. "github.com/mattn/go-isatty"
  9. "github.com/labstack/gommon/color"
  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. DEBUG = iota
  22. INFO
  23. WARN
  24. ERROR
  25. FATAL
  26. OFF
  27. )
  28. var (
  29. global = New("-")
  30. levels []string
  31. )
  32. func New(prefix string) (l *Logger) {
  33. l = &Logger{
  34. level: INFO,
  35. prefix: prefix,
  36. }
  37. l.SetOutput(colorable.NewColorableStdout())
  38. return
  39. }
  40. func (l *Logger) SetPrefix(p string) {
  41. l.prefix = p
  42. }
  43. func (l *Logger) SetLevel(v Level) {
  44. l.level = v
  45. }
  46. func (l *Logger) Level() Level {
  47. return l.level
  48. }
  49. func (l *Logger) SetOutput(w io.Writer) {
  50. l.out = w
  51. color.Disable()
  52. if w, ok := w.(*os.File); ok && isatty.IsTerminal(w.Fd()) {
  53. color.Enable()
  54. }
  55. // NOTE: Reintialize levels to reflect color enable/disable call.
  56. initLevels()
  57. }
  58. func (l *Logger) Print(i ...interface{}) {
  59. fmt.Println(i...)
  60. }
  61. func (l *Logger) Printf(format string, args ...interface{}) {
  62. f := fmt.Sprintf("%s\n", format)
  63. fmt.Fprintf(l.out, f, args...)
  64. }
  65. func (l *Logger) Debug(i ...interface{}) {
  66. l.log(DEBUG, "", i...)
  67. }
  68. func (l *Logger) Debugf(format string, args ...interface{}) {
  69. l.log(DEBUG, format, args...)
  70. }
  71. func (l *Logger) Info(i ...interface{}) {
  72. l.log(INFO, "", i...)
  73. }
  74. func (l *Logger) Infof(format string, args ...interface{}) {
  75. l.log(INFO, format, args...)
  76. }
  77. func (l *Logger) Warn(i ...interface{}) {
  78. l.log(WARN, "", i...)
  79. }
  80. func (l *Logger) Warnf(format string, args ...interface{}) {
  81. l.log(WARN, format, args...)
  82. }
  83. func (l *Logger) Error(i ...interface{}) {
  84. l.log(ERROR, "", i...)
  85. }
  86. func (l *Logger) Errorf(format string, args ...interface{}) {
  87. l.log(ERROR, format, args...)
  88. }
  89. func (l *Logger) Fatal(i ...interface{}) {
  90. l.log(FATAL, "", i...)
  91. os.Exit(1)
  92. }
  93. func (l *Logger) Fatalf(format string, args ...interface{}) {
  94. l.log(FATAL, format, args...)
  95. os.Exit(1)
  96. }
  97. func SetPrefix(p string) {
  98. global.SetPrefix(p)
  99. }
  100. func SetLevel(v Level) {
  101. global.SetLevel(v)
  102. }
  103. func SetOutput(w io.Writer) {
  104. global.SetOutput(w)
  105. }
  106. func Print(i ...interface{}) {
  107. global.Print(i...)
  108. }
  109. func Printf(format string, args ...interface{}) {
  110. global.Printf(format, args...)
  111. }
  112. func Debug(i ...interface{}) {
  113. global.Debug(i...)
  114. }
  115. func Debugf(format string, args ...interface{}) {
  116. global.Debugf(format, args...)
  117. }
  118. func Info(i ...interface{}) {
  119. global.Info(i...)
  120. }
  121. func Infof(format string, args ...interface{}) {
  122. global.Infof(format, args...)
  123. }
  124. func Warn(i ...interface{}) {
  125. global.Warn(i...)
  126. }
  127. func Warnf(format string, args ...interface{}) {
  128. global.Warnf(format, args...)
  129. }
  130. func Error(i ...interface{}) {
  131. global.Error(i...)
  132. }
  133. func Errorf(format string, args ...interface{}) {
  134. global.Errorf(format, args...)
  135. }
  136. func Fatal(i ...interface{}) {
  137. global.Fatal(i...)
  138. }
  139. func Fatalf(format string, args ...interface{}) {
  140. global.Fatalf(format, args...)
  141. }
  142. func (l *Logger) log(v Level, format string, args ...interface{}) {
  143. l.mu.Lock()
  144. defer l.mu.Unlock()
  145. if v >= l.level {
  146. if format == "" && len(args) > 0 {
  147. args[0] = fmt.Sprintf("%s|%s|%s", levels[v], l.prefix, args[0])
  148. fmt.Fprintln(l.out, args...)
  149. } else {
  150. // TODO: Improve performance
  151. f := fmt.Sprintf("%s|%s|%s\n", levels[v], l.prefix, format)
  152. fmt.Fprintf(l.out, f, args...)
  153. }
  154. }
  155. }
  156. func initLevels() {
  157. levels = []string{
  158. color.Blue("DEBUG"),
  159. color.Green("INFO"),
  160. color.Yellow("WARN"),
  161. color.Red("ERROR"),
  162. color.RedBg("FATAL"),
  163. }
  164. }
  165. func init() {
  166. initLevels()
  167. }