in plugins/parsers/json_v2/parser.go [269:391]
func (p *Parser) expandArray(result MetricNode, timestamp time.Time) ([]telegraf.Metric, error) {
var results []telegraf.Metric
if result.IsObject() {
if !p.iterateObjects {
p.Log.Debugf("Found object in query ignoring it please use 'object' to gather metrics from objects")
return results, nil
}
r, err := p.combineObject(result, timestamp)
if err != nil {
return nil, err
}
results = append(results, r...)
return results, nil
}
if result.IsArray() {
var err error
if result.IncludeCollection == nil && (len(p.objectConfig.FieldPaths) > 0 || len(p.objectConfig.TagPaths) > 0) {
result.IncludeCollection = p.existsInpathResults(result.Index)
}
result.ForEach(func(_, val gjson.Result) bool {
m := metric.New(
p.measurementName,
map[string]string{},
map[string]interface{}{},
timestamp,
)
if val.IsObject() {
n := result
n.ParentIndex += val.Index
n.Metric = m
n.Result = val
r, err := p.combineObject(n, timestamp)
if err != nil {
return false
}
results = append(results, r...)
if len(results) != 0 {
for _, newResult := range results {
mergeMetric(result.Metric, newResult)
}
}
return true
}
mergeMetric(result.Metric, m)
n := result
n.ParentIndex += val.Index
n.Metric = m
n.Result = val
r, err := p.expandArray(n, timestamp)
if err != nil {
return false
}
results = append(results, r...)
return true
})
if err != nil {
return nil, err
}
} else {
if p.objectConfig.TimestampKey != "" && result.SetName == p.objectConfig.TimestampKey {
if p.objectConfig.TimestampFormat == "" {
err := fmt.Errorf("use of 'timestamp_query' requires 'timestamp_format'")
return nil, err
}
timestamp, err := internal.ParseTimestamp(p.objectConfig.TimestampFormat, result.String(), p.objectConfig.TimestampTimezone)
if err != nil {
return nil, err
}
result.Metric.SetTime(timestamp)
} else {
switch result.Value().(type) {
case nil: // Ignore JSON values that are set as null
default:
outputName := result.OutputName
desiredType := result.DesiredType
if len(p.objectConfig.FieldPaths) > 0 || len(p.objectConfig.TagPaths) > 0 {
var pathResult *PathResult
// When IncludeCollection isn't nil, that means the current result is included in the collection.
if result.IncludeCollection != nil {
pathResult = result.IncludeCollection
} else {
// Verify that the result should be included based on the results of fieldpaths and tag paths
pathResult = p.existsInpathResults(result.ParentIndex)
}
if pathResult == nil {
return results, nil
}
if pathResult.tag {
result.Tag = true
}
if !pathResult.tag {
desiredType = pathResult.Type
}
if pathResult.Rename != "" {
outputName = pathResult.Rename
}
}
if result.Tag {
desiredType = "string"
}
v, err := p.convertType(result.Result, desiredType, result.SetName)
if err != nil {
return nil, err
}
if result.Tag {
result.Metric.AddTag(outputName, v.(string))
} else {
result.Metric.AddField(outputName, v)
}
}
}
results = append(results, result.Metric)
}
return results, nil
}