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