in plugins/inputs/cisco_telemetry_mdt/cisco_telemetry_mdt.go [529:665]
func (c *CiscoTelemetryMDT) parseContentField(grouper *metric.SeriesGrouper, field *telemetry.TelemetryField, prefix string,
encodingPath string, tags map[string]string, timestamp time.Time) {
name := strings.Replace(field.Name, "-", "_", -1)
if (name == "modTs" || name == "createTs") && decodeValue(field) == "never" {
return
}
if len(name) == 0 {
name = prefix
} else if len(prefix) > 0 {
name = prefix + "/" + name
}
extraTags := c.extraTags[strings.Replace(encodingPath, "-", "_", -1)+"/"+name]
if value := decodeValue(field); value != nil {
// Do alias lookup, to shorten measurement names
measurement := encodingPath
if alias, ok := c.internalAliases[encodingPath]; ok {
measurement = alias
} else {
c.mutex.Lock()
if _, haveWarned := c.warned[encodingPath]; !haveWarned {
c.Log.Debugf("No measurement alias for encoding path: %s", encodingPath)
c.warned[encodingPath] = struct{}{}
}
c.mutex.Unlock()
}
if val := c.nxosValueXform(field, value, encodingPath); val != nil {
if err := grouper.Add(measurement, tags, timestamp, name, val); err != nil {
c.Log.Errorf("adding field %q to group failed: %v", name, err)
}
} else {
if err := grouper.Add(measurement, tags, timestamp, name, value); err != nil {
c.Log.Errorf("adding field %q to group failed: %v", name, err)
}
}
return
}
if len(extraTags) > 0 {
for _, subfield := range field.Fields {
if _, isExtraTag := extraTags[subfield.Name]; isExtraTag {
tags[name+"/"+strings.Replace(subfield.Name, "-", "_", -1)] = decodeTag(subfield)
}
}
}
var nxAttributes, nxChildren, nxRows *telemetry.TelemetryField
isNXOS := !strings.ContainsRune(encodingPath, ':') // IOS-XR and IOS-XE have a colon in their encoding path, NX-OS does not
isEVENT := isNXOS && strings.Contains(encodingPath, "EVENT-LIST")
nxChildren = nil
nxAttributes = nil
for _, subfield := range field.Fields {
if isNXOS && subfield.Name == "attributes" && len(subfield.Fields) > 0 {
nxAttributes = subfield.Fields[0]
} else if isNXOS && subfield.Name == "children" && len(subfield.Fields) > 0 {
if !isEVENT {
nxChildren = subfield
} else {
sub := subfield.Fields
if len(sub) > 0 && sub[0] != nil && sub[0].Fields[0].Name == "subscriptionId" && len(sub[0].Fields) >= 2 {
nxAttributes = sub[0].Fields[1].Fields[0].Fields[0].Fields[0].Fields[0].Fields[0]
}
}
//if nxAttributes == NULL then class based query.
if nxAttributes == nil {
//call function walking over walking list.
for _, sub := range subfield.Fields {
c.parseClassAttributeField(grouper, sub, encodingPath, tags, timestamp)
}
}
} else if isNXOS && strings.HasPrefix(subfield.Name, "ROW_") {
nxRows = subfield
} else if _, isExtraTag := extraTags[subfield.Name]; !isExtraTag { // Regular telemetry decoding
c.parseContentField(grouper, subfield, name, encodingPath, tags, timestamp)
}
}
if nxAttributes == nil && nxRows == nil {
return
} else if nxRows != nil {
// NXAPI structure: https://developer.cisco.com/docs/cisco-nexus-9000-series-nx-api-cli-reference-release-9-2x/
for _, row := range nxRows.Fields {
for i, subfield := range row.Fields {
if i == 0 { // First subfield contains the index, promote it from value to tag
tags[prefix] = decodeTag(subfield)
//We can have subfield so recursively handle it.
if len(row.Fields) == 1 {
tags["row_number"] = strconv.FormatInt(int64(i), 10)
c.parseContentField(grouper, subfield, "", encodingPath, tags, timestamp)
}
} else {
c.parseContentField(grouper, subfield, "", encodingPath, tags, timestamp)
}
// Nxapi we can't identify keys always from prefix
tags["row_number"] = strconv.FormatInt(int64(i), 10)
}
delete(tags, prefix)
}
return
}
// DME structure: https://developer.cisco.com/site/nxapi-dme-model-reference-api/
rn := ""
dn := false
for _, subfield := range nxAttributes.Fields {
if subfield.Name == "rn" {
rn = decodeTag(subfield)
} else if subfield.Name == "dn" {
dn = true
}
}
if len(rn) > 0 {
tags[prefix] = rn
} else if !dn { // Check for distinguished name being present
c.acc.AddError(fmt.Errorf("NX-OS decoding failed: missing dn field"))
return
}
for _, subfield := range nxAttributes.Fields {
if subfield.Name != "rn" {
c.parseContentField(grouper, subfield, "", encodingPath, tags, timestamp)
}
}
if nxChildren != nil {
// This is a nested structure, children will inherit relative name keys of parent
for _, subfield := range nxChildren.Fields {
c.parseContentField(grouper, subfield, prefix, encodingPath, tags, timestamp)
}
}
delete(tags, prefix)
}