logger.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. package gorm
  2. import (
  3. "database/sql/driver"
  4. "fmt"
  5. "log"
  6. "os"
  7. "reflect"
  8. "regexp"
  9. "time"
  10. "unicode"
  11. )
  12. var (
  13. defaultLogger = Logger{log.New(os.Stdout, "\r\n", 0)}
  14. sqlRegexp = regexp.MustCompile(`\?`)
  15. numericPlaceHolderRegexp = regexp.MustCompile(`\$\d+`)
  16. )
  17. func isPrintable(s string) bool {
  18. for _, r := range s {
  19. if !unicode.IsPrint(r) {
  20. return false
  21. }
  22. }
  23. return true
  24. }
  25. var LogFormatter = func(values ...interface{}) (messages []interface{}) {
  26. if len(values) > 1 {
  27. var (
  28. sql string
  29. formattedValues []string
  30. level = values[0]
  31. currentTime = "\n\033[33m[" + NowFunc().Format("2006-01-02 15:04:05") + "]\033[0m"
  32. source = fmt.Sprintf("\033[35m(%v)\033[0m", values[1])
  33. )
  34. messages = []interface{}{source, currentTime}
  35. if level == "sql" {
  36. // duration
  37. messages = append(messages, fmt.Sprintf(" \033[36;1m[%.2fms]\033[0m ", float64(values[2].(time.Duration).Nanoseconds()/1e4)/100.0))
  38. // sql
  39. for _, value := range values[4].([]interface{}) {
  40. indirectValue := reflect.Indirect(reflect.ValueOf(value))
  41. if indirectValue.IsValid() {
  42. value = indirectValue.Interface()
  43. if t, ok := value.(time.Time); ok {
  44. formattedValues = append(formattedValues, fmt.Sprintf("'%v'", t.Format("2006-01-02 15:04:05")))
  45. } else if b, ok := value.([]byte); ok {
  46. if str := string(b); isPrintable(str) {
  47. formattedValues = append(formattedValues, fmt.Sprintf("'%v'", str))
  48. } else {
  49. formattedValues = append(formattedValues, "'<binary>'")
  50. }
  51. } else if r, ok := value.(driver.Valuer); ok {
  52. if value, err := r.Value(); err == nil && value != nil {
  53. formattedValues = append(formattedValues, fmt.Sprintf("'%v'", value))
  54. } else {
  55. formattedValues = append(formattedValues, "NULL")
  56. }
  57. } else {
  58. formattedValues = append(formattedValues, fmt.Sprintf("'%v'", value))
  59. }
  60. } else {
  61. formattedValues = append(formattedValues, "NULL")
  62. }
  63. }
  64. // differentiate between $n placeholders or else treat like ?
  65. if numericPlaceHolderRegexp.MatchString(values[3].(string)) {
  66. sql = values[3].(string)
  67. for index, value := range formattedValues {
  68. placeholder := fmt.Sprintf(`\$%d`, index+1)
  69. sql = regexp.MustCompile(placeholder).ReplaceAllString(sql, value)
  70. }
  71. } else {
  72. formattedValuesLength := len(formattedValues)
  73. for index, value := range sqlRegexp.Split(values[3].(string), -1) {
  74. sql += value
  75. if index < formattedValuesLength {
  76. sql += formattedValues[index]
  77. }
  78. }
  79. }
  80. messages = append(messages, sql)
  81. } else {
  82. messages = append(messages, "\033[31;1m")
  83. messages = append(messages, values[2:]...)
  84. messages = append(messages, "\033[0m")
  85. }
  86. }
  87. return
  88. }
  89. type logger interface {
  90. Print(v ...interface{})
  91. }
  92. // LogWriter log writer interface
  93. type LogWriter interface {
  94. Println(v ...interface{})
  95. }
  96. // Logger default logger
  97. type Logger struct {
  98. LogWriter
  99. }
  100. // Print format & print log
  101. func (logger Logger) Print(values ...interface{}) {
  102. logger.Println(LogFormatter(values...)...)
  103. }