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  }