feat(inputs.gnmi): Allow canonical field names (#13326)

This commit is contained in:
Sven Rebhan 2023-05-24 16:14:06 +02:00 committed by GitHub
parent 60ee14d50b
commit 8f07761cba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 169 additions and 65 deletions

View File

@ -52,6 +52,9 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
## gRPC Maximum Message Size
# max_msg_size = "4MB"
## Enable to get the canonical path as field-name
# canonical_field_names = false
## enable client-side TLS and define CA to authenticate the device
# enable_tls = false
# tls_ca = "/etc/telegraf/ca.pem"

View File

@ -42,23 +42,24 @@ var supportedExtensions = []string{"juniper_header"}
// gNMI plugin instance
type GNMI struct {
Addresses []string `toml:"addresses"`
Subscriptions []Subscription `toml:"subscription"`
TagSubscriptions []TagSubscription `toml:"tag_subscription"`
Aliases map[string]string `toml:"aliases"`
Encoding string `toml:"encoding"`
Origin string `toml:"origin"`
Prefix string `toml:"prefix"`
Target string `toml:"target"`
UpdatesOnly bool `toml:"updates_only"`
VendorSpecific []string `toml:"vendor_specific"`
Username string `toml:"username"`
Password string `toml:"password"`
Redial config.Duration `toml:"redial"`
MaxMsgSize config.Size `toml:"max_msg_size"`
Trace bool `toml:"dump_responses"`
EnableTLS bool `toml:"enable_tls"`
Log telegraf.Logger `toml:"-"`
Addresses []string `toml:"addresses"`
Subscriptions []Subscription `toml:"subscription"`
TagSubscriptions []TagSubscription `toml:"tag_subscription"`
Aliases map[string]string `toml:"aliases"`
Encoding string `toml:"encoding"`
Origin string `toml:"origin"`
Prefix string `toml:"prefix"`
Target string `toml:"target"`
UpdatesOnly bool `toml:"updates_only"`
VendorSpecific []string `toml:"vendor_specific"`
Username string `toml:"username"`
Password string `toml:"password"`
Redial config.Duration `toml:"redial"`
MaxMsgSize config.Size `toml:"max_msg_size"`
Trace bool `toml:"dump_responses"`
CanonicalFieldNames bool `toml:"canonical_field_names"`
EnableTLS bool `toml:"enable_tls"`
Log telegraf.Logger `toml:"-"`
internaltls.ClientConfig
// Internal state
@ -192,15 +193,18 @@ func (c *GNMI) Start(acc telegraf.Accumulator) error {
for _, addr := range c.Addresses {
go func(addr string) {
defer c.wg.Done()
confHandler := configHandler{
aliases: c.internalAliases,
subscriptions: c.TagSubscriptions,
maxSize: int(c.MaxMsgSize),
log: c.Log,
trace: c.Trace,
vendorExt: c.VendorSpecific,
h := handler{
address: addr,
aliases: c.internalAliases,
tagsubs: c.TagSubscriptions,
maxMsgSize: int(c.MaxMsgSize),
vendorExt: c.VendorSpecific,
tagStore: newTagStore(c.TagSubscriptions),
trace: c.Trace,
canonicalFieldNames: c.CanonicalFieldNames,
log: c.Log,
}
h := newHandler(addr, confHandler)
for ctx.Err() == nil {
if err := h.subscribeGNMI(ctx, acc, tlscfg, request); err != nil && ctx.Err() == nil {
acc.AddError(err)

View File

@ -28,38 +28,16 @@ import (
const eidJuniperTelemetryHeader = 1
type handler struct {
address string
aliases map[string]string
tagsubs []TagSubscription
maxMsgSize int
emptyNameWarnShown bool
vendorExt []string
tagStore *tagStore
trace bool
log telegraf.Logger
}
// Allow to convey additionnal configuration elements
type configHandler struct {
aliases map[string]string
subscriptions []TagSubscription
maxSize int
log telegraf.Logger
trace bool
vendorExt []string
}
func newHandler(addr string, confHandler configHandler) *handler {
return &handler{
address: addr,
aliases: confHandler.aliases,
tagsubs: confHandler.subscriptions,
maxMsgSize: confHandler.maxSize,
vendorExt: confHandler.vendorExt,
tagStore: newTagStore(confHandler.subscriptions),
trace: confHandler.trace,
log: confHandler.log,
}
address string
aliases map[string]string
tagsubs []TagSubscription
maxMsgSize int
emptyNameWarnShown bool
vendorExt []string
tagStore *tagStore
trace bool
canonicalFieldNames bool
log telegraf.Logger
}
// SubscribeGNMI and extract telemetry data
@ -266,15 +244,22 @@ func (h *handler) handleSubscribeResponseUpdate(acc telegraf.Accumulator, respon
// conversion on the key.
key = key[len(aliasPath)+1:]
} else if len(aliasPath) >= len(key) {
// Otherwise use the last path element as the field key.
key = path.Base(key)
if h.canonicalFieldNames {
// Strip the origin is any for the field names
if parts := strings.SplitN(key, ":", 2); len(parts) == 2 {
key = parts[1]
}
} else {
// Otherwise use the last path element as the field key.
key = path.Base(key)
// If there are no elements skip the item; this would be an
// invalid message.
key = strings.TrimLeft(key, "/.")
if key == "" {
h.log.Errorf("invalid empty path: %q", k)
continue
// If there are no elements skip the item; this would be an
// invalid message.
key = strings.TrimLeft(key, "/.")
if key == "" {
h.log.Errorf("invalid empty path: %q", k)
continue
}
}
}
grouper.Add(name, tags, timestamp, key, v)

View File

@ -16,6 +16,9 @@
## gRPC Maximum Message Size
# max_msg_size = "4MB"
## Enable to get the canonical path as field-name
# canonical_field_names = false
## enable client-side TLS and define CA to authenticate the device
# enable_tls = false
# tls_ca = "/etc/telegraf/ca.pem"

View File

@ -0,0 +1 @@
interfaces,name=eth42,path=openconfig-interfaces:/interfaces/interface,source=127.0.0.1 /interfaces/interface/descr="eth42",/interfaces/interface/config/id=42425u,/interfaces/interface/state/in_pkts=5678u,/interfaces/interface/state/out_pkts=5125u 1673608605875353770

View File

@ -0,0 +1,79 @@
[
{
"update": {
"timestamp": "1673608605875353770",
"prefix": {
"origin": "openconfig-interfaces",
"elem": [
{
"name": "interfaces"
},
{
"name": "interface",
"key":{"name":"eth42"}
}
],
"target": "subscription"
},
"update": [
{
"path": {
"elem": [
{
"name": "descr"
}
]
},
"val": {
"stringVal": "eth42"
}
},
{
"path": {
"elem": [
{
"name": "config"
},
{
"name": "id"
}
]
},
"val": {
"uintVal": "42425"
}
},
{
"path": {
"elem": [
{
"name": "state"
},
{
"name": "in-pkts"
}
]
},
"val": {
"uintVal": "5678"
}
},
{
"path": {
"elem": [
{
"name": "state"
},
{
"name": "out-pkts"
}
]
},
"val": {
"uintVal": "5125"
}
}
]
}
}
]

View File

@ -0,0 +1,29 @@
[[inputs.gnmi]]
addresses = ["dummy"]
name_override = "gnmi"
redial = "10s"
canonical_field_names = true
[[inputs.gnmi.subscription]]
name = "interfaces"
origin = "openconfig-interfaces"
path = "/interfaces/interface/descr"
subscription_mode = "sample"
sample_interval = "10s"
[[inputs.gnmi.subscription]]
name = "interfaces"
origin = "openconfig-interfaces"
path = "/interfaces/interface/config/id"
subscription_mode = "sample"
sample_interval = "10s"
[[inputs.gnmi.subscription]]
name = "interfaces"
origin = "openconfig-interfaces"
path = "/interfaces/interface/state/in-pkts"
subscription_mode = "sample"
sample_interval = "10s"
[[inputs.gnmi.subscription]]
name = "interfaces"
origin = "openconfig-interfaces"
path = "/interfaces/interface/state/out-pkts"
subscription_mode = "sample"
sample_interval = "10s"