Fix path handling issues in cisco_telemetry_gnmi (#6403)

- Avoid crashing when a field has no value or one of deprecated type
- Emit measurement names correctly for replies with empty origin
- Skip paths with empty names instead of adding a '/'
This commit is contained in:
Steven Barth 2019-09-24 20:05:56 +02:00 committed by Daniel Nelson
parent 817c9a69a9
commit 00d9b84234
1 changed files with 22 additions and 7 deletions

View File

@ -8,6 +8,7 @@ import (
"fmt" "fmt"
"io" "io"
"net" "net"
"path"
"strings" "strings"
"sync" "sync"
"time" "time"
@ -102,21 +103,27 @@ func (c *CiscoTelemetryGNMI) Start(acc telegraf.Accumulator) error {
// Invert explicit alias list and prefill subscription names // Invert explicit alias list and prefill subscription names
c.aliases = make(map[string]string, len(c.Subscriptions)+len(c.Aliases)) c.aliases = make(map[string]string, len(c.Subscriptions)+len(c.Aliases))
for _, subscription := range c.Subscriptions { for _, subscription := range c.Subscriptions {
var gnmiLongPath, gnmiShortPath *gnmi.Path
// Build the subscription path without keys // Build the subscription path without keys
gnmiPath, err := parsePath(subscription.Origin, subscription.Path, "") if gnmiLongPath, err = parsePath(subscription.Origin, subscription.Path, ""); err != nil {
if err != nil { return err
}
if gnmiShortPath, err = parsePath("", subscription.Path, ""); err != nil {
return err return err
} }
path, _ := c.handlePath(gnmiPath, nil, "") longPath, _ := c.handlePath(gnmiLongPath, nil, "")
shortPath, _ := c.handlePath(gnmiShortPath, nil, "")
name := subscription.Name name := subscription.Name
// If the user didn't provide a measurement name, use last path element // If the user didn't provide a measurement name, use last path element
if len(name) == 0 { if len(name) == 0 {
name = path[strings.LastIndexByte(path, '/')+1:] name = path.Base(shortPath)
} }
if len(name) > 0 { if len(name) > 0 {
c.aliases[path] = name c.aliases[longPath] = name
c.aliases[shortPath] = name
} }
} }
for alias, path := range c.Aliases { for alias, path := range c.Aliases {
@ -296,6 +303,12 @@ func (c *CiscoTelemetryGNMI) handleTelemetryField(update *gnmi.Update, tags map[
var value interface{} var value interface{}
var jsondata []byte var jsondata []byte
// Make sure a value is actually set
if update.Val == nil || update.Val.Value == nil {
log.Printf("I! [inputs.cisco_telemetry_gnmi]: Discarded empty or legacy type value with path: %s", path)
return aliasPath, nil
}
switch val := update.Val.Value.(type) { switch val := update.Val.Value.(type) {
case *gnmi.TypedValue_AsciiVal: case *gnmi.TypedValue_AsciiVal:
value = val.AsciiVal value = val.AsciiVal
@ -347,8 +360,10 @@ func (c *CiscoTelemetryGNMI) handlePath(path *gnmi.Path, tags map[string]string,
// Parse generic keys from prefix // Parse generic keys from prefix
for _, elem := range path.Elem { for _, elem := range path.Elem {
builder.WriteRune('/') if len(elem.Name) > 0 {
builder.WriteString(elem.Name) builder.WriteRune('/')
builder.WriteString(elem.Name)
}
name := builder.String() name := builder.String()
if _, exists := c.aliases[name]; exists { if _, exists := c.aliases[name]; exists {