logger.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. package logger
  2. import (
  3. "log"
  4. "os"
  5. "time"
  6. "github.com/jinzhu/gorm/utils"
  7. )
  8. // Colors
  9. const (
  10. Reset = "\033[0m"
  11. Red = "\033[31m"
  12. Green = "\033[32m"
  13. Yellow = "\033[33m"
  14. Blue = "\033[34m"
  15. Magenta = "\033[35m"
  16. Cyan = "\033[36m"
  17. White = "\033[37m"
  18. Redbold = "\033[31;1m"
  19. YellowBold = "\033[33;1m"
  20. )
  21. // LogLevel
  22. type LogLevel int
  23. const (
  24. Error LogLevel = iota + 1
  25. Warn
  26. Info
  27. )
  28. // Writer log writer interface
  29. type Writer interface {
  30. Printf(string, ...interface{})
  31. }
  32. type Config struct {
  33. SlowThreshold time.Duration
  34. Colorful bool
  35. LogLevel LogLevel
  36. }
  37. // Interface logger interface
  38. type Interface interface {
  39. LogMode(LogLevel) Interface
  40. Info(string, ...interface{})
  41. Warn(string, ...interface{})
  42. Error(string, ...interface{})
  43. Trace(begin time.Time, fc func() (string, int64), err error)
  44. }
  45. var Default = New(log.New(os.Stdout, "\r\n", log.LstdFlags), Config{
  46. SlowThreshold: 100 * time.Millisecond,
  47. LogLevel: Warn,
  48. Colorful: true,
  49. })
  50. func New(writer Writer, config Config) Interface {
  51. var (
  52. infoPrefix = "%s\n[info] "
  53. warnPrefix = "%s\n[warn] "
  54. errPrefix = "%s\n[error] "
  55. tracePrefix = "%s\n[%v] [rows:%d] %s"
  56. traceErrPrefix = "%s\n[%v] [rows:%d] %s"
  57. )
  58. if config.Colorful {
  59. infoPrefix = Green + "%s\n" + Reset + Green + "[info] " + Reset
  60. warnPrefix = Blue + "%s\n" + Reset + Magenta + "[warn] " + Reset
  61. errPrefix = Magenta + "%s\n" + Reset + Red + "[error] " + Reset
  62. tracePrefix = Green + "%s\n" + Reset + YellowBold + "[%.3fms] " + Green + "[rows:%d]" + Reset + " %s"
  63. traceErrPrefix = Magenta + "%s\n" + Reset + Redbold + "[%.3fms] " + Yellow + "[rows:%d]" + Reset + " %s"
  64. }
  65. return logger{
  66. Writer: writer,
  67. Config: config,
  68. infoPrefix: infoPrefix,
  69. warnPrefix: warnPrefix,
  70. errPrefix: errPrefix,
  71. tracePrefix: tracePrefix,
  72. traceErrPrefix: traceErrPrefix,
  73. }
  74. }
  75. type logger struct {
  76. Writer
  77. Config
  78. infoPrefix, warnPrefix, errPrefix string
  79. tracePrefix, traceErrPrefix string
  80. }
  81. // LogMode log mode
  82. func (l logger) LogMode(level LogLevel) Interface {
  83. l.LogLevel = level
  84. return l
  85. }
  86. // Info print info
  87. func (l logger) Info(msg string, data ...interface{}) {
  88. if l.LogLevel >= Info {
  89. l.Printf(l.infoPrefix+msg, append([]interface{}{utils.FileWithLineNum()}, data...)...)
  90. }
  91. }
  92. // Warn print warn messages
  93. func (l logger) Warn(msg string, data ...interface{}) {
  94. if l.LogLevel >= Warn {
  95. l.Printf(l.warnPrefix+msg, append([]interface{}{utils.FileWithLineNum()}, data...)...)
  96. }
  97. }
  98. // Error print error messages
  99. func (l logger) Error(msg string, data ...interface{}) {
  100. if l.LogLevel >= Error {
  101. l.Printf(l.errPrefix+msg, append([]interface{}{utils.FileWithLineNum()}, data...)...)
  102. }
  103. }
  104. // Trace print sql message
  105. func (l logger) Trace(begin time.Time, fc func() (string, int64), err error) {
  106. if elapsed := time.Now().Sub(begin); err != nil || elapsed > l.SlowThreshold {
  107. sql, rows := fc()
  108. fileline := utils.FileWithLineNum()
  109. if err != nil {
  110. fileline += " " + err.Error()
  111. }
  112. l.Printf(l.traceErrPrefix, fileline, float64(elapsed.Nanoseconds())/1e6, rows, sql)
  113. } else if l.LogLevel >= Info {
  114. sql, rows := fc()
  115. l.Printf(l.tracePrefix, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, rows, sql)
  116. }
  117. }