logger.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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. Colorful: true,
  48. })
  49. func New(writer Writer, config Config) Interface {
  50. var (
  51. infoPrefix = "%s\n[info] "
  52. warnPrefix = "%s\n[warn] "
  53. errPrefix = "%s\n[error] "
  54. tracePrefix = "%s\n[%v] [rows:%d] %s"
  55. traceErrPrefix = "%s\n[%v] [rows:%d] %s"
  56. )
  57. if config.Colorful {
  58. infoPrefix = Green + "%s\n" + Reset + Green + "[info] " + Reset
  59. warnPrefix = Blue + "%s\n" + Reset + Magenta + "[warn] " + Reset
  60. errPrefix = Magenta + "%s\n" + Reset + Red + "[error] " + Reset
  61. tracePrefix = Green + "%s\n" + Reset + YellowBold + "[%.3fms] " + Green + "[rows:%d]" + Reset + " %s"
  62. traceErrPrefix = Magenta + "%s\n" + Reset + Redbold + "[%.3fms] " + Yellow + "[rows:%d]" + Reset + " %s"
  63. }
  64. return logger{
  65. Writer: writer,
  66. Config: config,
  67. infoPrefix: infoPrefix,
  68. warnPrefix: warnPrefix,
  69. errPrefix: errPrefix,
  70. tracePrefix: tracePrefix,
  71. traceErrPrefix: traceErrPrefix,
  72. }
  73. }
  74. type logger struct {
  75. Writer
  76. Config
  77. infoPrefix, warnPrefix, errPrefix string
  78. tracePrefix, traceErrPrefix string
  79. }
  80. // LogMode log mode
  81. func (l logger) LogMode(level LogLevel) Interface {
  82. l.LogLevel = level
  83. return l
  84. }
  85. // Info print info
  86. func (l logger) Info(msg string, data ...interface{}) {
  87. if l.LogLevel >= Info {
  88. l.Printf(l.infoPrefix+msg, append([]interface{}{utils.FileWithLineNum()}, data...)...)
  89. }
  90. }
  91. // Warn print warn messages
  92. func (l logger) Warn(msg string, data ...interface{}) {
  93. if l.LogLevel >= Warn {
  94. l.Printf(l.warnPrefix+msg, append([]interface{}{utils.FileWithLineNum()}, data...)...)
  95. }
  96. }
  97. // Error print error messages
  98. func (l logger) Error(msg string, data ...interface{}) {
  99. if l.LogLevel >= Error {
  100. l.Printf(l.errPrefix+msg, append([]interface{}{utils.FileWithLineNum()}, data...)...)
  101. }
  102. }
  103. // Trace print sql message
  104. func (l logger) Trace(begin time.Time, fc func() (string, int64), err error) {
  105. if elapsed := time.Now().Sub(begin); err != nil || elapsed > l.SlowThreshold {
  106. sql, rows := fc()
  107. fileline := utils.FileWithLineNum()
  108. if err != nil {
  109. fileline += " " + err.Error()
  110. }
  111. l.Printf(l.traceErrPrefix, fileline, float64(elapsed.Nanoseconds())/1e6, rows, sql)
  112. } else if l.LogLevel >= Info {
  113. sql, rows := fc()
  114. l.Printf(l.tracePrefix, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, rows, sql)
  115. }
  116. }