formatter.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. package logrus
  2. import "time"
  3. // Default key names for the default fields
  4. const (
  5. defaultTimestampFormat = time.RFC3339
  6. FieldKeyMsg = "msg"
  7. FieldKeyLevel = "level"
  8. FieldKeyTime = "time"
  9. FieldKeyLogrusError = "logrus_error"
  10. FieldKeyFunc = "func"
  11. FieldKeyFile = "file"
  12. )
  13. // The Formatter interface is used to implement a custom Formatter. It takes an
  14. // `Entry`. It exposes all the fields, including the default ones:
  15. //
  16. // * `entry.Data["msg"]`. The message passed from Info, Warn, Error ..
  17. // * `entry.Data["time"]`. The timestamp.
  18. // * `entry.Data["level"]. The level the entry was logged at.
  19. //
  20. // Any additional fields added with `WithField` or `WithFields` are also in
  21. // `entry.Data`. Format is expected to return an array of bytes which are then
  22. // logged to `logger.Out`.
  23. type Formatter interface {
  24. Format(*Entry) ([]byte, error)
  25. }
  26. // This is to not silently overwrite `time`, `msg`, `func` and `level` fields when
  27. // dumping it. If this code wasn't there doing:
  28. //
  29. // logrus.WithField("level", 1).Info("hello")
  30. //
  31. // Would just silently drop the user provided level. Instead with this code
  32. // it'll logged as:
  33. //
  34. // {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."}
  35. //
  36. // It's not exported because it's still using Data in an opinionated way. It's to
  37. // avoid code duplication between the two default formatters.
  38. func prefixFieldClashes(data Fields, fieldMap FieldMap, reportCaller bool) {
  39. timeKey := fieldMap.resolve(FieldKeyTime)
  40. if t, ok := data[timeKey]; ok {
  41. data["fields."+timeKey] = t
  42. delete(data, timeKey)
  43. }
  44. msgKey := fieldMap.resolve(FieldKeyMsg)
  45. if m, ok := data[msgKey]; ok {
  46. data["fields."+msgKey] = m
  47. delete(data, msgKey)
  48. }
  49. levelKey := fieldMap.resolve(FieldKeyLevel)
  50. if l, ok := data[levelKey]; ok {
  51. data["fields."+levelKey] = l
  52. delete(data, levelKey)
  53. }
  54. logrusErrKey := fieldMap.resolve(FieldKeyLogrusError)
  55. if l, ok := data[logrusErrKey]; ok {
  56. data["fields."+logrusErrKey] = l
  57. delete(data, logrusErrKey)
  58. }
  59. // If reportCaller is not set, 'func' will not conflict.
  60. if reportCaller {
  61. funcKey := fieldMap.resolve(FieldKeyFunc)
  62. if l, ok := data[funcKey]; ok {
  63. data["fields."+funcKey] = l
  64. }
  65. fileKey := fieldMap.resolve(FieldKeyFile)
  66. if l, ok := data[fileKey]; ok {
  67. data["fields."+fileKey] = l
  68. }
  69. }
  70. }