entry.go 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package gonx
  2. import (
  3. "fmt"
  4. "strconv"
  5. "strings"
  6. )
  7. // Shortcut for the map of strings
  8. type Fields map[string]string
  9. // Parsed log record. Use Get method to retrieve a value by name instead of
  10. // threating this as a map, because inner representation is in design.
  11. type Entry struct {
  12. fields Fields
  13. }
  14. // Creates an empty Entry to be filled later
  15. func NewEmptyEntry() *Entry {
  16. return &Entry{make(Fields)}
  17. }
  18. // Creates an Entry with fiven fields
  19. func NewEntry(fields Fields) *Entry {
  20. return &Entry{fields}
  21. }
  22. // Return entry field value by name or empty string and error if it
  23. // does not exist.
  24. func (entry *Entry) Field(name string) (value string, err error) {
  25. value, ok := entry.fields[name]
  26. if !ok {
  27. err = fmt.Errorf("field '%v' does not found in record %+v", name, *entry)
  28. }
  29. return
  30. }
  31. // Return entry field value as float64. Rutuen nil if field does not exists
  32. // and convertion error if cannot cast a type.
  33. func (entry *Entry) FloatField(name string) (value float64, err error) {
  34. tmp, err := entry.Field(name)
  35. if err == nil {
  36. value, err = strconv.ParseFloat(tmp, 64)
  37. }
  38. return
  39. }
  40. // Field value setter
  41. func (entry *Entry) SetField(name string, value string) {
  42. entry.fields[name] = value
  43. }
  44. // Float field value setter. It accepts float64, but still store it as a
  45. // string in the same fields map. The precision is 2, its enough for log
  46. // parsing task
  47. func (entry *Entry) SetFloatField(name string, value float64) {
  48. entry.SetField(name, strconv.FormatFloat(value, 'f', 2, 64))
  49. }
  50. // Integer field value setter. It accepts float64, but still store it as a
  51. // string in the same fields map.
  52. func (entry *Entry) SetUintField(name string, value uint64) {
  53. entry.SetField(name, strconv.FormatUint(uint64(value), 10))
  54. }
  55. // Merge two entries by updating values for master entry with given.
  56. func (master *Entry) Merge(entry *Entry) {
  57. for name, value := range entry.fields {
  58. master.SetField(name, value)
  59. }
  60. }
  61. func (entry *Entry) FieldsHash(fields []string) string {
  62. var key []string
  63. for _, name := range fields {
  64. value, err := entry.Field(name)
  65. if err != nil {
  66. value = "NULL"
  67. }
  68. key = append(key, fmt.Sprintf("'%v'=%v", name, value))
  69. }
  70. return strings.Join(key, ";")
  71. }
  72. func (entry *Entry) Partial(fields []string) *Entry {
  73. partial := NewEmptyEntry()
  74. for _, name := range fields {
  75. value, _ := entry.Field(name)
  76. partial.SetField(name, value)
  77. }
  78. return partial
  79. }