log_entry.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package plugin
  2. import (
  3. "encoding/json"
  4. "time"
  5. )
  6. // logEntry is the JSON payload that gets sent to Stderr from the plugin to the host
  7. type logEntry struct {
  8. Message string `json:"@message"`
  9. Level string `json:"@level"`
  10. Timestamp time.Time `json:"timestamp"`
  11. KVPairs []*logEntryKV `json:"kv_pairs"`
  12. }
  13. // logEntryKV is a key value pair within the Output payload
  14. type logEntryKV struct {
  15. Key string `json:"key"`
  16. Value interface{} `json:"value"`
  17. }
  18. // flattenKVPairs is used to flatten KVPair slice into []interface{}
  19. // for hclog consumption.
  20. func flattenKVPairs(kvs []*logEntryKV) []interface{} {
  21. var result []interface{}
  22. for _, kv := range kvs {
  23. result = append(result, kv.Key)
  24. result = append(result, kv.Value)
  25. }
  26. return result
  27. }
  28. // parseJSON handles parsing JSON output
  29. func parseJSON(input []byte) (*logEntry, error) {
  30. var raw map[string]interface{}
  31. entry := &logEntry{}
  32. err := json.Unmarshal(input, &raw)
  33. if err != nil {
  34. return nil, err
  35. }
  36. // Parse hclog-specific objects
  37. if v, ok := raw["@message"]; ok {
  38. entry.Message = v.(string)
  39. delete(raw, "@message")
  40. }
  41. if v, ok := raw["@level"]; ok {
  42. entry.Level = v.(string)
  43. delete(raw, "@level")
  44. }
  45. if v, ok := raw["@timestamp"]; ok {
  46. t, err := time.Parse("2006-01-02T15:04:05.000000Z07:00", v.(string))
  47. if err != nil {
  48. return nil, err
  49. }
  50. entry.Timestamp = t
  51. delete(raw, "@timestamp")
  52. }
  53. // Parse dynamic KV args from the hclog payload.
  54. for k, v := range raw {
  55. entry.KVPairs = append(entry.KVPairs, &logEntryKV{
  56. Key: k,
  57. Value: v,
  58. })
  59. }
  60. return entry, nil
  61. }