github.com/observiq/carbon@v0.9.11-0.20200820160507-1b872e368a5e/operator/builtin/parser/json.go (about) 1 package parser 2 3 import ( 4 "context" 5 "fmt" 6 7 jsoniter "github.com/json-iterator/go" 8 "github.com/observiq/carbon/entry" 9 "github.com/observiq/carbon/operator" 10 "github.com/observiq/carbon/operator/helper" 11 ) 12 13 func init() { 14 operator.Register("json_parser", func() operator.Builder { return NewJSONParserConfig("") }) 15 } 16 17 func NewJSONParserConfig(operatorID string) *JSONParserConfig { 18 return &JSONParserConfig{ 19 ParserConfig: helper.NewParserConfig(operatorID, "json_parser"), 20 } 21 } 22 23 // JSONParserConfig is the configuration of a JSON parser operator. 24 type JSONParserConfig struct { 25 helper.ParserConfig `yaml:",inline"` 26 } 27 28 // Build will build a JSON parser operator. 29 func (c JSONParserConfig) Build(context operator.BuildContext) (operator.Operator, error) { 30 parserOperator, err := c.ParserConfig.Build(context) 31 if err != nil { 32 return nil, err 33 } 34 35 jsonParser := &JSONParser{ 36 ParserOperator: parserOperator, 37 json: jsoniter.ConfigFastest, 38 } 39 40 return jsonParser, nil 41 } 42 43 // JSONParser is an operator that parses JSON. 44 type JSONParser struct { 45 helper.ParserOperator 46 json jsoniter.API 47 } 48 49 // Process will parse an entry for JSON. 50 func (j *JSONParser) Process(ctx context.Context, entry *entry.Entry) error { 51 return j.ParserOperator.ProcessWith(ctx, entry, j.parse) 52 } 53 54 // parse will parse a value as JSON. 55 func (j *JSONParser) parse(value interface{}) (interface{}, error) { 56 var parsedValue map[string]interface{} 57 switch m := value.(type) { 58 case string: 59 err := j.json.UnmarshalFromString(m, &parsedValue) 60 if err != nil { 61 return nil, err 62 } 63 case []byte: 64 err := j.json.Unmarshal(m, &parsedValue) 65 if err != nil { 66 return nil, err 67 } 68 default: 69 return nil, fmt.Errorf("type %T cannot be parsed as JSON", value) 70 } 71 return parsedValue, nil 72 }