1
0
Fork 0

Adding upstream version 1.34.4.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-05-24 07:26:29 +02:00
parent e393c3af3f
commit 4978089aab
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
4963 changed files with 677545 additions and 0 deletions

View file

@ -0,0 +1,276 @@
# gNMI (gRPC Network Management Interface) Input Plugin
This plugin consumes telemetry data based on [gNMI][gnmi] subscriptions. TLS is
supported for authentication and encryption. This plugin is vendor-agnostic and
is supported on any platform that supports the gNMI specification.
For Cisco devices the plugin has been optimized to support gNMI telemetry as
produced by Cisco IOS XR (64-bit) version 6.5.1, Cisco NX-OS 9.3 and
Cisco IOS XE 16.12 and later.
⭐ Telegraf v1.15.0
🏷️ network
💻 all
[gnmi]: https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-specification.md
## Service Input <!-- @/docs/includes/service_input.md -->
This plugin is a service input. Normal plugins gather metrics determined by the
interval setting. Service plugins start a service to listen and wait for
metrics or events to occur. Service plugins have two key differences from
normal plugins:
1. The global or plugin specific `interval` setting may not apply
2. The CLI options of `--test`, `--test-wait`, and `--once` may not produce
output for this plugin
## Global configuration options <!-- @/docs/includes/plugin_config.md -->
In addition to the plugin-specific configuration settings, plugins support
additional global and plugin configuration settings. These settings are used to
modify metrics, tags, and field or create aliases and configure ordering, etc.
See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
[CONFIGURATION.md]: ../../../docs/CONFIGURATION.md#plugins
## Secret-store support
This plugin supports secrets from secret-stores for the `username` and
`password` options. See the [secret-store documentation][SECRETSTORE] for more
details on how to use them.
[SECRETSTORE]: ../../../docs/CONFIGURATION.md#secret-store-secrets
## Configuration
```toml @sample.conf
# gNMI telemetry input plugin
[[inputs.gnmi]]
## Address and port of the gNMI GRPC server
addresses = ["10.49.234.114:57777"]
## define credentials
username = "cisco"
password = "cisco"
## gNMI encoding requested (one of: "proto", "json", "json_ietf", "bytes")
# encoding = "proto"
## redial in case of failures after
# redial = "10s"
## gRPC Keepalive settings
## See https://pkg.go.dev/google.golang.org/grpc/keepalive
## The client will ping the server to see if the transport is still alive if it has
## not see any activity for the given time.
## If not set, none of the keep-alive setting (including those below) will be applied.
## If set and set below 10 seconds, the gRPC library will apply a minimum value of 10s will be used instead.
# keepalive_time = ""
## Timeout for seeing any activity after the keep-alive probe was
## sent. If no activity is seen the connection is closed.
# keepalive_timeout = ""
## gRPC Maximum Message Size
# max_msg_size = "4MB"
## Subtree depth for depth extension (disables if < 1)
## see https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-depth.md
# depth = 0
## Enable to get the canonical path as field-name
# canonical_field_names = false
## Remove leading slashes and dots in field-name
# trim_field_names = false
## Only receive updates for the state, also suppresses receiving the initial state
# updates_only = false
## Enforces the namespace of the first element as origin for aliases and
## response paths, required for backward compatibility.
## NOTE: Set to 'false' if possible but be aware that this might change the path tag!
# enforce_first_namespace_as_origin = true
## Guess the path-tag if an update does not contain a prefix-path
## Supported values are
## none -- do not add a 'path' tag
## common path -- use the common path elements of all fields in an update
## subscription -- use the subscription path
# path_guessing_strategy = "none"
## Prefix tags from path keys with the path element
# prefix_tag_key_with_path = false
## Optional client-side TLS to authenticate the device
## Set to true/false to enforce TLS being enabled/disabled. If not set,
## enable TLS only if any of the other options are specified.
# tls_enable =
## Trusted root certificates for server
# tls_ca = "/path/to/cafile"
## Used for TLS client certificate authentication
# tls_cert = "/path/to/certfile"
## Used for TLS client certificate authentication
# tls_key = "/path/to/keyfile"
## Password for the key file if it is encrypted
# tls_key_pwd = ""
## Send the specified TLS server name via SNI
# tls_server_name = "kubernetes.example.com"
## Minimal TLS version to accept by the client
# tls_min_version = "TLS12"
## List of ciphers to accept, by default all secure ciphers will be accepted
## See https://pkg.go.dev/crypto/tls#pkg-constants for supported values.
## Use "all", "secure" and "insecure" to add all support ciphers, secure
## suites or insecure suites respectively.
# tls_cipher_suites = ["secure"]
## Renegotiation method, "never", "once" or "freely"
# tls_renegotiation_method = "never"
## Use TLS but skip chain & host verification
# insecure_skip_verify = false
## gNMI subscription prefix (optional, can usually be left empty)
## See: https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-specification.md#222-paths
# origin = ""
# prefix = ""
# target = ""
## Vendor specific options
## This defines what vendor specific options to load.
## * Juniper Header Extension (juniper_header): some sensors are directly managed by
## Linecard, which adds the Juniper GNMI Header Extension. Enabling this
## allows the decoding of the Extension header if present. Currently this knob
## adds component, component_id & sub_component_id as additional tags
# vendor_specific = []
## YANG model paths for decoding IETF JSON payloads
## Model files are loaded recursively from the given directories. Disabled if
## no models are specified.
# yang_model_paths = []
## Define additional aliases to map encoding paths to measurement names
# [inputs.gnmi.aliases]
# ifcounters = "openconfig:/interfaces/interface/state/counters"
[[inputs.gnmi.subscription]]
## Name of the measurement that will be emitted
name = "ifcounters"
## Origin and path of the subscription
## See: https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-specification.md#222-paths
##
## origin usually refers to a (YANG) data model implemented by the device
## and path to a specific substructure inside it that should be subscribed
## to (similar to an XPath). YANG models can be found e.g. here:
## https://github.com/YangModels/yang/tree/master/vendor/cisco/xr
origin = "openconfig-interfaces"
path = "/interfaces/interface/state/counters"
## Subscription mode ("target_defined", "sample", "on_change") and interval
subscription_mode = "sample"
sample_interval = "10s"
## Suppress redundant transmissions when measured values are unchanged
# suppress_redundant = false
## If suppression is enabled, send updates at least every X seconds anyway
# heartbeat_interval = "60s"
## Tag subscriptions are applied as tags to other subscriptions.
# [[inputs.gnmi.tag_subscription]]
# ## When applying this value as a tag to other metrics, use this tag name
# name = "descr"
#
# ## All other subscription fields are as normal
# origin = "openconfig-interfaces"
# path = "/interfaces/interface/state"
# subscription_mode = "on_change"
#
# ## Match strategy to use for the tag.
# ## Tags are only applied for metrics of the same address. The following
# ## settings are valid:
# ## unconditional -- always match
# ## name -- match by the "name" key
# ## This resembles the previous 'tag-only' behavior.
# ## elements -- match by the keys in the path filtered by the path
# ## parts specified `elements` below
# ## By default, 'elements' is used if the 'elements' option is provided,
# ## otherwise match by 'name'.
# # match = ""
#
# ## For the 'elements' match strategy, at least one path-element name must
# ## be supplied containing at least one key to match on. Multiple path
# ## elements can be specified in any order. All given keys must be equal
# ## for a match.
# # elements = ["description", "interface"]
```
## Metrics
Each configured subscription will emit a different measurement. Each leaf in a
GNMI SubscribeResponse Update message will produce a field reading in the
measurement. GNMI PathElement keys for leaves will attach tags to the field(s).
## Example Output
```text
ifcounters,path=openconfig-interfaces:/interfaces/interface/state/counters,host=linux,name=MgmtEth0/RP0/CPU0/0,source=10.49.234.115,descr/description=Foo in-multicast-pkts=0i,out-multicast-pkts=0i,out-errors=0i,out-discards=0i,in-broadcast-pkts=0i,out-broadcast-pkts=0i,in-discards=0i,in-unknown-protos=0i,in-errors=0i,out-unicast-pkts=0i,in-octets=0i,out-octets=0i,last-clear="2019-05-22T16:53:21Z",in-unicast-pkts=0i 1559145777425000000
ifcounters,path=openconfig-interfaces:/interfaces/interface/state/counters,host=linux,name=GigabitEthernet0/0/0/0,source=10.49.234.115,descr/description=Bar out-multicast-pkts=0i,out-broadcast-pkts=0i,in-errors=0i,out-errors=0i,in-discards=0i,out-octets=0i,in-unknown-protos=0i,in-unicast-pkts=0i,in-octets=0i,in-multicast-pkts=0i,in-broadcast-pkts=0i,last-clear="2019-05-22T16:54:50Z",out-unicast-pkts=0i,out-discards=0i 1559145777425000000
```
## Troubleshooting
### Empty metric-name warning
Some devices (e.g. Juniper) report spurious data with response paths not
corresponding to any subscription. In those cases, Telegraf will not be able
to determine the metric name for the response and you get an
*empty metric-name warning*
For example if you subscribe to `/junos/system/linecard/cpu/memory` but the
corresponding response arrives with path
`/components/component/properties/property/...` To avoid those issues, you can
manually map the response to a metric name using the `aliases` option like
```toml
[[inputs.gnmi]]
addresses = ["..."]
[inputs.gnmi.aliases]
memory = "/components"
[[inputs.gnmi.subscription]]
name = "memory"
origin = "openconfig"
path = "/junos/system/linecard/cpu/memory"
subscription_mode = "sample"
sample_interval = "60s"
```
If this does *not* solve the issue, please follow the warning instructions and
open an issue with the response, your configuration and the metric you expect.
### Missing `path` tag
Some devices (e.g. Arista) omit the prefix and specify the path in the update
if there is only one value reported. This leads to a missing `path` tag for
the resulting metrics. In those cases you should set `path_guessing_strategy`
to `subscription` to use the subscription path as `path` tag.
Other devices might omit the prefix in updates altogether. Here setting
`path_guessing_strategy` to `common path` can help to infer the `path` tag by
using the part of the path that is common to all values in the update.
### TLS handshake failure
When receiving an error like
```text
2024-01-01T00:00:00Z E! [inputs.gnmi] Error in plugin: failed to setup subscription: rpc error: code = Unavailable desc = connection error: desc = "transport: authentication handshake failed: remote error: tls: handshake failure"
```
this might be due to insecure TLS configurations in the GNMI server. Please
check the minimum TLS version provided by the server as well as the cipher suite
used. You might want to use the `tls_min_version` or `tls_cipher_suites` setting
respectively to work-around the issue. Please be careful to not undermine the
security of the connection between the plugin and the device!

View file

@ -0,0 +1,381 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.30.0
// protoc v3.12.4
// source: GnmiJuniperTelemetryHeaderExtension.proto
package jnpr_gnmi_extention
import (
reflect "reflect"
sync "sync"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type StreamType int32
const (
StreamType_INITIAL_SYNC StreamType = 0
StreamType_ONCHANGE StreamType = 1
StreamType_PERIODIC StreamType = 2
)
// Enum value maps for StreamType.
var (
StreamType_name = map[int32]string{
0: "INITIAL_SYNC",
1: "ONCHANGE",
2: "PERIODIC",
}
StreamType_value = map[string]int32{
"INITIAL_SYNC": 0,
"ONCHANGE": 1,
"PERIODIC": 2,
}
)
func (x StreamType) Enum() *StreamType {
p := new(StreamType)
*p = x
return p
}
func (x StreamType) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (StreamType) Descriptor() protoreflect.EnumDescriptor {
return file_GnmiJuniperTelemetryHeaderExtension_proto_enumTypes[0].Descriptor()
}
func (StreamType) Type() protoreflect.EnumType {
return &file_GnmiJuniperTelemetryHeaderExtension_proto_enumTypes[0]
}
func (x StreamType) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use StreamType.Descriptor instead.
func (StreamType) EnumDescriptor() ([]byte, []int) {
return file_GnmiJuniperTelemetryHeaderExtension_proto_rawDescGZIP(), []int{0}
}
// Present as first gNMI update in all packets
type GnmiJuniperTelemetryHeaderExtension struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// router name:export IP address
SystemId string `protobuf:"bytes,1,opt,name=system_id,json=systemId,proto3" json:"system_id,omitempty"`
// line card / RE (slot number)
ComponentId uint32 `protobuf:"varint,2,opt,name=component_id,json=componentId,proto3" json:"component_id,omitempty"`
// PFE (if applicable)
SubComponentId uint32 `protobuf:"varint,3,opt,name=sub_component_id,json=subComponentId,proto3" json:"sub_component_id,omitempty"`
// Internal sensor name
SensorName string `protobuf:"bytes,4,opt,name=sensor_name,json=sensorName,proto3" json:"sensor_name,omitempty"`
// Sensor path in the subscribe request
SubscribedPath string `protobuf:"bytes,5,opt,name=subscribed_path,json=subscribedPath,proto3" json:"subscribed_path,omitempty"`
// Internal sensor path in junos
StreamedPath string `protobuf:"bytes,6,opt,name=streamed_path,json=streamedPath,proto3" json:"streamed_path,omitempty"`
Component string `protobuf:"bytes,7,opt,name=component,proto3" json:"component,omitempty"`
// Sequence number, monotonically increasing for each
SequenceNumber uint64 `protobuf:"varint,8,opt,name=sequence_number,json=sequenceNumber,proto3" json:"sequence_number,omitempty"`
// Payload get timestamp in milliseconds
PayloadGetTimestamp int64 `protobuf:"varint,9,opt,name=payload_get_timestamp,json=payloadGetTimestamp,proto3" json:"payload_get_timestamp,omitempty"`
// Stream creation timestamp in milliseconds
StreamCreationTimestamp int64 `protobuf:"varint,10,opt,name=stream_creation_timestamp,json=streamCreationTimestamp,proto3" json:"stream_creation_timestamp,omitempty"`
// [Deprecated] Event timestamp in milliseconds
//
// Deprecated: Marked as deprecated in GnmiJuniperTelemetryHeaderExtension.proto.
EventTimestamp int64 `protobuf:"varint,11,opt,name=event_timestamp,json=eventTimestamp,proto3" json:"event_timestamp,omitempty"`
// Export timestamp in milliseconds
ExportTimestamp int64 `protobuf:"varint,12,opt,name=export_timestamp,json=exportTimestamp,proto3" json:"export_timestamp,omitempty"`
// Subsequence number
SubSequenceNumber uint64 `protobuf:"varint,13,opt,name=sub_sequence_number,json=subSequenceNumber,proto3" json:"sub_sequence_number,omitempty"`
// End of marker
Eom bool `protobuf:"varint,14,opt,name=eom,proto3" json:"eom,omitempty"`
// Event publish timestamp in milliseconds
EventPublishTimestamp int64 `protobuf:"varint,15,opt,name=event_publish_timestamp,json=eventPublishTimestamp,proto3" json:"event_publish_timestamp,omitempty"`
// Stream type of packet
StreamId StreamType `protobuf:"varint,16,opt,name=stream_id,json=streamId,proto3,enum=StreamType" json:"stream_id,omitempty"`
}
func (x *GnmiJuniperTelemetryHeaderExtension) Reset() {
*x = GnmiJuniperTelemetryHeaderExtension{}
if protoimpl.UnsafeEnabled {
mi := &file_GnmiJuniperTelemetryHeaderExtension_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GnmiJuniperTelemetryHeaderExtension) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GnmiJuniperTelemetryHeaderExtension) ProtoMessage() {}
func (x *GnmiJuniperTelemetryHeaderExtension) ProtoReflect() protoreflect.Message {
mi := &file_GnmiJuniperTelemetryHeaderExtension_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GnmiJuniperTelemetryHeaderExtension.ProtoReflect.Descriptor instead.
func (*GnmiJuniperTelemetryHeaderExtension) Descriptor() ([]byte, []int) {
return file_GnmiJuniperTelemetryHeaderExtension_proto_rawDescGZIP(), []int{0}
}
func (x *GnmiJuniperTelemetryHeaderExtension) GetSystemId() string {
if x != nil {
return x.SystemId
}
return ""
}
func (x *GnmiJuniperTelemetryHeaderExtension) GetComponentId() uint32 {
if x != nil {
return x.ComponentId
}
return 0
}
func (x *GnmiJuniperTelemetryHeaderExtension) GetSubComponentId() uint32 {
if x != nil {
return x.SubComponentId
}
return 0
}
func (x *GnmiJuniperTelemetryHeaderExtension) GetSensorName() string {
if x != nil {
return x.SensorName
}
return ""
}
func (x *GnmiJuniperTelemetryHeaderExtension) GetSubscribedPath() string {
if x != nil {
return x.SubscribedPath
}
return ""
}
func (x *GnmiJuniperTelemetryHeaderExtension) GetStreamedPath() string {
if x != nil {
return x.StreamedPath
}
return ""
}
func (x *GnmiJuniperTelemetryHeaderExtension) GetComponent() string {
if x != nil {
return x.Component
}
return ""
}
func (x *GnmiJuniperTelemetryHeaderExtension) GetSequenceNumber() uint64 {
if x != nil {
return x.SequenceNumber
}
return 0
}
func (x *GnmiJuniperTelemetryHeaderExtension) GetPayloadGetTimestamp() int64 {
if x != nil {
return x.PayloadGetTimestamp
}
return 0
}
func (x *GnmiJuniperTelemetryHeaderExtension) GetStreamCreationTimestamp() int64 {
if x != nil {
return x.StreamCreationTimestamp
}
return 0
}
// Deprecated: Marked as deprecated in GnmiJuniperTelemetryHeaderExtension.proto.
func (x *GnmiJuniperTelemetryHeaderExtension) GetEventTimestamp() int64 {
if x != nil {
return x.EventTimestamp
}
return 0
}
func (x *GnmiJuniperTelemetryHeaderExtension) GetExportTimestamp() int64 {
if x != nil {
return x.ExportTimestamp
}
return 0
}
func (x *GnmiJuniperTelemetryHeaderExtension) GetSubSequenceNumber() uint64 {
if x != nil {
return x.SubSequenceNumber
}
return 0
}
func (x *GnmiJuniperTelemetryHeaderExtension) GetEom() bool {
if x != nil {
return x.Eom
}
return false
}
func (x *GnmiJuniperTelemetryHeaderExtension) GetEventPublishTimestamp() int64 {
if x != nil {
return x.EventPublishTimestamp
}
return 0
}
func (x *GnmiJuniperTelemetryHeaderExtension) GetStreamId() StreamType {
if x != nil {
return x.StreamId
}
return StreamType_INITIAL_SYNC
}
var File_GnmiJuniperTelemetryHeaderExtension_proto protoreflect.FileDescriptor
var file_GnmiJuniperTelemetryHeaderExtension_proto_rawDesc = []byte{
0x0a, 0x29, 0x47, 0x6e, 0x6d, 0x69, 0x4a, 0x75, 0x6e, 0x69, 0x70, 0x65, 0x72, 0x54, 0x65, 0x6c,
0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65,
0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb1, 0x05, 0x0a, 0x23,
0x47, 0x6e, 0x6d, 0x69, 0x4a, 0x75, 0x6e, 0x69, 0x70, 0x65, 0x72, 0x54, 0x65, 0x6c, 0x65, 0x6d,
0x65, 0x74, 0x72, 0x79, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73,
0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x64,
0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e,
0x74, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x75, 0x62, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f,
0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x73,
0x75, 0x62, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a,
0x0b, 0x73, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27,
0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x64, 0x5f, 0x70, 0x61, 0x74,
0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69,
0x62, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x74, 0x72, 0x65, 0x61,
0x6d, 0x65, 0x64, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1c, 0x0a, 0x09,
0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52,
0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x65,
0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x08, 0x20,
0x01, 0x28, 0x04, 0x52, 0x0e, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x4e, 0x75, 0x6d,
0x62, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x15, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x67,
0x65, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x09, 0x20, 0x01,
0x28, 0x03, 0x52, 0x13, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x47, 0x65, 0x74, 0x54, 0x69,
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3a, 0x0a, 0x19, 0x73, 0x74, 0x72, 0x65, 0x61,
0x6d, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73,
0x74, 0x61, 0x6d, 0x70, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x73, 0x74, 0x72, 0x65,
0x61, 0x6d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
0x61, 0x6d, 0x70, 0x12, 0x2b, 0x0a, 0x0f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x69, 0x6d,
0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x42, 0x02, 0x18, 0x01,
0x52, 0x0e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
0x12, 0x29, 0x0a, 0x10, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73,
0x74, 0x61, 0x6d, 0x70, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x65, 0x78, 0x70, 0x6f,
0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2e, 0x0a, 0x13, 0x73,
0x75, 0x62, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62,
0x65, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x73, 0x75, 0x62, 0x53, 0x65, 0x71,
0x75, 0x65, 0x6e, 0x63, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x65,
0x6f, 0x6d, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x65, 0x6f, 0x6d, 0x12, 0x36, 0x0a,
0x17, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x5f, 0x74,
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15,
0x65, 0x76, 0x65, 0x6e, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x54, 0x69, 0x6d, 0x65,
0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x28, 0x0a, 0x09, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f,
0x69, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0b, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61,
0x6d, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x64, 0x2a,
0x3a, 0x0a, 0x0a, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a,
0x0c, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x10, 0x00, 0x12,
0x0c, 0x0a, 0x08, 0x4f, 0x4e, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x01, 0x12, 0x0c, 0x0a,
0x08, 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44, 0x49, 0x43, 0x10, 0x02, 0x42, 0x17, 0x5a, 0x15, 0x2e,
0x3b, 0x6a, 0x6e, 0x70, 0x72, 0x5f, 0x67, 0x6e, 0x6d, 0x69, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e,
0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_GnmiJuniperTelemetryHeaderExtension_proto_rawDescOnce sync.Once
file_GnmiJuniperTelemetryHeaderExtension_proto_rawDescData = file_GnmiJuniperTelemetryHeaderExtension_proto_rawDesc
)
func file_GnmiJuniperTelemetryHeaderExtension_proto_rawDescGZIP() []byte {
file_GnmiJuniperTelemetryHeaderExtension_proto_rawDescOnce.Do(func() {
file_GnmiJuniperTelemetryHeaderExtension_proto_rawDescData = protoimpl.X.CompressGZIP(file_GnmiJuniperTelemetryHeaderExtension_proto_rawDescData)
})
return file_GnmiJuniperTelemetryHeaderExtension_proto_rawDescData
}
var file_GnmiJuniperTelemetryHeaderExtension_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_GnmiJuniperTelemetryHeaderExtension_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_GnmiJuniperTelemetryHeaderExtension_proto_goTypes = []interface{}{
(StreamType)(0), // 0: StreamType
(*GnmiJuniperTelemetryHeaderExtension)(nil), // 1: GnmiJuniperTelemetryHeaderExtension
}
var file_GnmiJuniperTelemetryHeaderExtension_proto_depIdxs = []int32{
0, // 0: GnmiJuniperTelemetryHeaderExtension.stream_id:type_name -> StreamType
1, // [1:1] is the sub-list for method output_type
1, // [1:1] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_GnmiJuniperTelemetryHeaderExtension_proto_init() }
func file_GnmiJuniperTelemetryHeaderExtension_proto_init() {
if File_GnmiJuniperTelemetryHeaderExtension_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_GnmiJuniperTelemetryHeaderExtension_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GnmiJuniperTelemetryHeaderExtension); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_GnmiJuniperTelemetryHeaderExtension_proto_rawDesc,
NumEnums: 1,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_GnmiJuniperTelemetryHeaderExtension_proto_goTypes,
DependencyIndexes: file_GnmiJuniperTelemetryHeaderExtension_proto_depIdxs,
EnumInfos: file_GnmiJuniperTelemetryHeaderExtension_proto_enumTypes,
MessageInfos: file_GnmiJuniperTelemetryHeaderExtension_proto_msgTypes,
}.Build()
File_GnmiJuniperTelemetryHeaderExtension_proto = out.File
file_GnmiJuniperTelemetryHeaderExtension_proto_rawDesc = nil
file_GnmiJuniperTelemetryHeaderExtension_proto_goTypes = nil
file_GnmiJuniperTelemetryHeaderExtension_proto_depIdxs = nil
}

490
plugins/inputs/gnmi/gnmi.go Normal file
View file

@ -0,0 +1,490 @@
//go:generate ../../../tools/config_includer/generator
//go:generate ../../../tools/readme_config_includer/generator
package gnmi
import (
"context"
_ "embed"
"errors"
"fmt"
"net"
"strings"
"sync"
"time"
"github.com/google/gnxi/utils/xpath"
"github.com/openconfig/gnmi/proto/gnmi"
"github.com/openconfig/gnmi/proto/gnmi_ext"
"google.golang.org/grpc/keepalive"
"google.golang.org/grpc/metadata"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/config"
"github.com/influxdata/telegraf/internal/choice"
common_tls "github.com/influxdata/telegraf/plugins/common/tls"
"github.com/influxdata/telegraf/plugins/common/yangmodel"
"github.com/influxdata/telegraf/plugins/inputs"
)
//go:embed sample.conf
var sampleConfig string
// Currently supported GNMI Extensions
var supportedExtensions = []string{"juniper_header"}
// Define the warning to show if we cannot get a metric name.
const emptyNameWarning = `Got empty metric-name for response (field %q), usually
indicating configuration issues as the response cannot be related to any
subscription.Please open an issue on https://github.com/influxdata/telegraf
including your device model and the following response data:
%+v
This message is only printed once.`
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 config.Secret `toml:"username"`
Password config.Secret `toml:"password"`
Redial config.Duration `toml:"redial"`
MaxMsgSize config.Size `toml:"max_msg_size"`
Depth int32 `toml:"depth"`
Trace bool `toml:"dump_responses"`
CanonicalFieldNames bool `toml:"canonical_field_names"`
TrimFieldNames bool `toml:"trim_field_names"`
PrefixTagKeyWithPath bool `toml:"prefix_tag_key_with_path"`
GuessPathTag bool `toml:"guess_path_tag" deprecated:"1.30.0;1.35.0;use 'path_guessing_strategy' instead"`
GuessPathStrategy string `toml:"path_guessing_strategy"`
EnableTLS bool `toml:"enable_tls" deprecated:"1.27.0;1.35.0;use 'tls_enable' instead"`
KeepaliveTime config.Duration `toml:"keepalive_time"`
KeepaliveTimeout config.Duration `toml:"keepalive_timeout"`
YangModelPaths []string `toml:"yang_model_paths"`
EnforceFirstNamespaceAsOrigin bool `toml:"enforce_first_namespace_as_origin"`
Log telegraf.Logger `toml:"-"`
common_tls.ClientConfig
// Internal state
internalAliases map[*pathInfo]string
decoder *yangmodel.Decoder
cancel context.CancelFunc
wg sync.WaitGroup
}
type subscription struct {
Name string `toml:"name"`
Origin string `toml:"origin"`
Path string `toml:"path"`
SubscriptionMode string `toml:"subscription_mode"`
SampleInterval config.Duration `toml:"sample_interval"`
SuppressRedundant bool `toml:"suppress_redundant"`
HeartbeatInterval config.Duration `toml:"heartbeat_interval"`
TagOnly bool `toml:"tag_only" deprecated:"1.25.0;1.35.0;please use 'tag_subscription's instead"`
fullPath *gnmi.Path
}
type tagSubscription struct {
subscription
Match string `toml:"match"`
Elements []string `toml:"elements"`
}
func (*GNMI) SampleConfig() string {
return sampleConfig
}
func (c *GNMI) Init() error {
// Check options
switch c.Encoding {
case "":
c.Encoding = "proto"
case "proto", "json", "json_ietf", "bytes":
// Do nothing, those are valid
default:
return fmt.Errorf("unsupported encoding %s", c.Encoding)
}
if time.Duration(c.Redial) <= 0 {
return errors.New("redial duration must be positive")
}
// Check vendor_specific options configured by user
if err := choice.CheckSlice(c.VendorSpecific, supportedExtensions); err != nil {
return fmt.Errorf("unsupported vendor_specific option: %w", err)
}
// Check path guessing and handle deprecated option
if c.GuessPathTag {
if c.GuessPathStrategy == "" {
c.GuessPathStrategy = "common path"
}
if c.GuessPathStrategy != "common path" {
return errors.New("conflicting settings between 'guess_path_tag' and 'path_guessing_strategy'")
}
}
switch c.GuessPathStrategy {
case "", "none", "common path", "subscription":
default:
return fmt.Errorf("invalid 'path_guessing_strategy' %q", c.GuessPathStrategy)
}
// Use the new TLS option for enabling
// Honor deprecated option
enable := (c.ClientConfig.Enable != nil && *c.ClientConfig.Enable) || c.EnableTLS
c.ClientConfig.Enable = &enable
// Split the subscriptions into "normal" and "tag" subscription
// and prepare them.
for i := len(c.Subscriptions) - 1; i >= 0; i-- {
subscription := c.Subscriptions[i]
// Check the subscription
if subscription.Name == "" {
return fmt.Errorf("empty 'name' found for subscription %d", i+1)
}
if subscription.Path == "" {
return fmt.Errorf("empty 'path' found for subscription %d", i+1)
}
// Support and convert legacy TagOnly subscriptions
if subscription.TagOnly {
tagSub := tagSubscription{
subscription: subscription,
Match: "name",
}
c.TagSubscriptions = append(c.TagSubscriptions, tagSub)
// Remove from the original subscriptions list
c.Subscriptions = append(c.Subscriptions[:i], c.Subscriptions[i+1:]...)
continue
}
if err := subscription.buildFullPath(c); err != nil {
return err
}
}
for idx := range c.TagSubscriptions {
if err := c.TagSubscriptions[idx].buildFullPath(c); err != nil {
return err
}
if c.TagSubscriptions[idx].TagOnly != c.TagSubscriptions[0].TagOnly {
return errors.New("do not mix legacy tag_only subscriptions and tag subscriptions")
}
switch c.TagSubscriptions[idx].Match {
case "":
if len(c.TagSubscriptions[idx].Elements) > 0 {
c.TagSubscriptions[idx].Match = "elements"
} else {
c.TagSubscriptions[idx].Match = "name"
}
case "unconditional":
case "name":
case "elements":
if len(c.TagSubscriptions[idx].Elements) == 0 {
return errors.New("tag_subscription must have at least one element")
}
default:
return fmt.Errorf("unknown match type %q for tag-subscription %q", c.TagSubscriptions[idx].Match, c.TagSubscriptions[idx].Name)
}
}
// Invert explicit alias list and prefill subscription names
c.internalAliases = make(map[*pathInfo]string, len(c.Subscriptions)+len(c.Aliases)+len(c.TagSubscriptions))
for _, s := range c.Subscriptions {
if err := s.buildAlias(c.internalAliases, c.EnforceFirstNamespaceAsOrigin); err != nil {
return err
}
}
for _, s := range c.TagSubscriptions {
if err := s.buildAlias(c.internalAliases, c.EnforceFirstNamespaceAsOrigin); err != nil {
return err
}
}
for alias, encodingPath := range c.Aliases {
path := newInfoFromString(encodingPath)
if c.EnforceFirstNamespaceAsOrigin {
path.enforceFirstNamespaceAsOrigin()
}
c.internalAliases[path] = alias
}
c.Log.Debugf("Internal alias mapping: %+v", c.internalAliases)
// Warn about configures insecure cipher suites
insecure := common_tls.InsecureCiphers(c.ClientConfig.TLSCipherSuites)
if len(insecure) > 0 {
c.Log.Warnf("Configured insecure cipher suites: %s", strings.Join(insecure, ","))
}
// Check the TLS configuration
if _, err := c.ClientConfig.TLSConfig(); err != nil {
if errors.Is(err, common_tls.ErrCipherUnsupported) {
secure, insecure := common_tls.Ciphers()
c.Log.Info("Supported secure ciphers:")
for _, name := range secure {
c.Log.Infof(" %s", name)
}
c.Log.Info("Supported insecure ciphers:")
for _, name := range insecure {
c.Log.Infof(" %s", name)
}
}
return err
}
// Load the YANG models if specified by the user
if len(c.YangModelPaths) > 0 {
decoder, err := yangmodel.NewDecoder(c.YangModelPaths...)
if err != nil {
return fmt.Errorf("creating YANG model decoder failed: %w", err)
}
c.decoder = decoder
}
return nil
}
func (c *GNMI) Start(acc telegraf.Accumulator) error {
// Validate configuration
request, err := c.newSubscribeRequest()
if err != nil {
return err
}
// Generate TLS config if enabled
tlscfg, err := c.ClientConfig.TLSConfig()
if err != nil {
return err
}
// Prepare the context, optionally with credentials
var ctx context.Context
ctx, c.cancel = context.WithCancel(context.Background())
if !c.Username.Empty() {
usernameSecret, err := c.Username.Get()
if err != nil {
return fmt.Errorf("getting username failed: %w", err)
}
username := usernameSecret.String()
usernameSecret.Destroy()
passwordSecret, err := c.Password.Get()
if err != nil {
return fmt.Errorf("getting password failed: %w", err)
}
password := passwordSecret.String()
passwordSecret.Destroy()
ctx = metadata.AppendToOutgoingContext(ctx, "username", username, "password", password)
}
// Create a goroutine for each device, dial and subscribe
c.wg.Add(len(c.Addresses))
for _, addr := range c.Addresses {
go func(addr string) {
defer c.wg.Done()
host, port, err := net.SplitHostPort(addr)
if err != nil {
acc.AddError(fmt.Errorf("unable to parse address %s: %w", addr, err))
return
}
h := handler{
host: host,
port: port,
aliases: c.internalAliases,
tagsubs: c.TagSubscriptions,
maxMsgSize: int(c.MaxMsgSize),
vendorExt: c.VendorSpecific,
tagStore: newTagStore(c.TagSubscriptions),
trace: c.Trace,
canonicalFieldNames: c.CanonicalFieldNames,
trimSlash: c.TrimFieldNames,
tagPathPrefix: c.PrefixTagKeyWithPath,
guessPathStrategy: c.GuessPathStrategy,
decoder: c.decoder,
enforceFirstNamespaceAsOrigin: c.EnforceFirstNamespaceAsOrigin,
log: c.Log,
ClientParameters: keepalive.ClientParameters{
Time: time.Duration(c.KeepaliveTime),
Timeout: time.Duration(c.KeepaliveTimeout),
PermitWithoutStream: false,
},
}
for ctx.Err() == nil {
if err := h.subscribeGNMI(ctx, acc, tlscfg, request); err != nil && ctx.Err() == nil {
acc.AddError(err)
}
select {
case <-ctx.Done():
case <-time.After(time.Duration(c.Redial)):
}
}
}(addr)
}
return nil
}
func (*GNMI) Gather(telegraf.Accumulator) error {
return nil
}
func (c *GNMI) Stop() {
c.cancel()
c.wg.Wait()
}
func (s *subscription) buildSubscription() (*gnmi.Subscription, error) {
gnmiPath, err := parsePath(s.Origin, s.Path, "")
if err != nil {
return nil, err
}
mode, ok := gnmi.SubscriptionMode_value[strings.ToUpper(s.SubscriptionMode)]
if !ok {
return nil, fmt.Errorf("invalid subscription mode %s", s.SubscriptionMode)
}
return &gnmi.Subscription{
Path: gnmiPath,
Mode: gnmi.SubscriptionMode(mode),
HeartbeatInterval: uint64(time.Duration(s.HeartbeatInterval).Nanoseconds()),
SampleInterval: uint64(time.Duration(s.SampleInterval).Nanoseconds()),
SuppressRedundant: s.SuppressRedundant,
}, nil
}
// Create a new gNMI SubscribeRequest
func (c *GNMI) newSubscribeRequest() (*gnmi.SubscribeRequest, error) {
// Create subscription objects
subscriptions := make([]*gnmi.Subscription, 0, len(c.Subscriptions)+len(c.TagSubscriptions))
for _, subscription := range c.TagSubscriptions {
sub, err := subscription.buildSubscription()
if err != nil {
return nil, err
}
subscriptions = append(subscriptions, sub)
}
for _, subscription := range c.Subscriptions {
sub, err := subscription.buildSubscription()
if err != nil {
return nil, err
}
subscriptions = append(subscriptions, sub)
}
// Construct subscribe request
gnmiPath, err := parsePath(c.Origin, c.Prefix, c.Target)
if err != nil {
return nil, err
}
// Do not provide an empty prefix. Required for Huawei NE40 router v8.21
// (and possibly others). See https://github.com/influxdata/telegraf/issues/12273.
if gnmiPath.Origin == "" && gnmiPath.Target == "" && len(gnmiPath.Elem) == 0 {
gnmiPath = nil
}
if c.Encoding != "proto" && c.Encoding != "json" && c.Encoding != "json_ietf" && c.Encoding != "bytes" {
return nil, fmt.Errorf("unsupported encoding %s", c.Encoding)
}
var extensions []*gnmi_ext.Extension
if c.Depth > 0 {
extensions = []*gnmi_ext.Extension{
{
Ext: &gnmi_ext.Extension_Depth{
Depth: &gnmi_ext.Depth{
Level: uint32(c.Depth),
},
},
},
}
}
return &gnmi.SubscribeRequest{
Request: &gnmi.SubscribeRequest_Subscribe{
Subscribe: &gnmi.SubscriptionList{
Prefix: gnmiPath,
Mode: gnmi.SubscriptionList_STREAM,
Encoding: gnmi.Encoding(gnmi.Encoding_value[strings.ToUpper(c.Encoding)]),
Subscription: subscriptions,
UpdatesOnly: c.UpdatesOnly,
},
},
Extension: extensions,
}, nil
}
// ParsePath from XPath-like string to gNMI path structure
func parsePath(origin, pathToParse, target string) (*gnmi.Path, error) {
gnmiPath, err := xpath.ToGNMIPath(pathToParse)
if err != nil {
return nil, err
}
gnmiPath.Origin = origin
gnmiPath.Target = target
return gnmiPath, err
}
func (s *subscription) buildFullPath(c *GNMI) error {
var err error
if s.fullPath, err = xpath.ToGNMIPath(s.Path); err != nil {
return err
}
s.fullPath.Origin = s.Origin
s.fullPath.Target = c.Target
if c.Prefix != "" {
prefix, err := xpath.ToGNMIPath(c.Prefix)
if err != nil {
return err
}
s.fullPath.Elem = append(prefix.Elem, s.fullPath.Elem...)
if s.Origin == "" && c.Origin != "" {
s.fullPath.Origin = c.Origin
}
}
return nil
}
func (s *subscription) buildAlias(aliases map[*pathInfo]string, enforceFirstNamespaceAsOrigin bool) error {
// Build the subscription path without keys
path, err := parsePath(s.Origin, s.Path, "")
if err != nil {
return err
}
info := newInfoFromPathWithoutKeys(path)
if enforceFirstNamespaceAsOrigin {
info.enforceFirstNamespaceAsOrigin()
}
// If the user didn't provide a measurement name, use last path element
name := s.Name
if name == "" && len(info.segments) > 0 {
name = info.segments[len(info.segments)-1].id
}
if name != "" {
aliases[info] = name
}
return nil
}
func init() {
inputs.Add("gnmi", func() telegraf.Input {
return &GNMI{
Redial: config.Duration(10 * time.Second),
EnforceFirstNamespaceAsOrigin: true,
}
})
// Backwards compatible alias:
inputs.Add("cisco_telemetry_gnmi", func() telegraf.Input {
return &GNMI{
Redial: config.Duration(10 * time.Second),
EnforceFirstNamespaceAsOrigin: true,
}
})
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,351 @@
package gnmi
import (
"context"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"io"
"net"
"sort"
"strconv"
"strings"
"time"
"github.com/openconfig/gnmi/proto/gnmi"
"github.com/openconfig/gnmi/proto/gnmi_ext"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/keepalive"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/internal/choice"
"github.com/influxdata/telegraf/metric"
"github.com/influxdata/telegraf/plugins/common/yangmodel"
"github.com/influxdata/telegraf/plugins/inputs/gnmi/extensions/jnpr_gnmi_extention"
"github.com/influxdata/telegraf/selfstat"
)
const eidJuniperTelemetryHeader = 1
type handler struct {
host string
port string
aliases map[*pathInfo]string
tagsubs []tagSubscription
maxMsgSize int
emptyNameWarnShown bool
vendorExt []string
tagStore *tagStore
trace bool
canonicalFieldNames bool
trimSlash bool
tagPathPrefix bool
guessPathStrategy string
decoder *yangmodel.Decoder
enforceFirstNamespaceAsOrigin bool
log telegraf.Logger
keepalive.ClientParameters
}
// SubscribeGNMI and extract telemetry data
func (h *handler) subscribeGNMI(ctx context.Context, acc telegraf.Accumulator, tlscfg *tls.Config, request *gnmi.SubscribeRequest) error {
var creds credentials.TransportCredentials
if tlscfg != nil {
creds = credentials.NewTLS(tlscfg)
} else {
creds = insecure.NewCredentials()
}
opts := []grpc.DialOption{
grpc.WithTransportCredentials(creds),
}
if h.maxMsgSize > 0 {
opts = append(opts, grpc.WithDefaultCallOptions(
grpc.MaxCallRecvMsgSize(h.maxMsgSize),
))
}
if h.ClientParameters.Time > 0 {
opts = append(opts, grpc.WithKeepaliveParams(h.ClientParameters))
}
// Used to report the status of the TCP connection to the device. If the
// GNMI connection goes down, but TCP is still up this will still report
// connected until the TCP connection times out.
connectStat := selfstat.Register("gnmi", "grpc_connection_status", map[string]string{"source": h.host})
defer connectStat.Set(0)
address := net.JoinHostPort(h.host, h.port)
client, err := grpc.NewClient(address, opts...)
if err != nil {
return fmt.Errorf("failed to dial: %w", err)
}
defer client.Close()
subscribeClient, err := gnmi.NewGNMIClient(client).Subscribe(ctx)
if err != nil {
return fmt.Errorf("failed to setup subscription: %w", err)
}
// If io.EOF is returned, the stream may have ended and stream status
// can be determined by calling Recv.
if err := subscribeClient.Send(request); err != nil && !errors.Is(err, io.EOF) {
return fmt.Errorf("failed to send subscription request: %w", err)
}
connectStat.Set(1)
h.log.Debugf("Connection to gNMI device %s established", address)
defer h.log.Debugf("Connection to gNMI device %s closed", address)
for ctx.Err() == nil {
var reply *gnmi.SubscribeResponse
if reply, err = subscribeClient.Recv(); err != nil {
if !errors.Is(err, io.EOF) && ctx.Err() == nil {
return fmt.Errorf("aborted gNMI subscription: %w", err)
}
break
}
if h.trace {
buf, err := protojson.Marshal(reply)
if err != nil {
h.log.Debugf("Marshal failed: %v", err)
} else {
t := reply.GetUpdate().GetTimestamp()
h.log.Debugf("Got update_%v: %s", t, string(buf))
}
}
if response, ok := reply.Response.(*gnmi.SubscribeResponse_Update); ok {
h.handleSubscribeResponseUpdate(acc, response, reply.GetExtension())
}
}
return nil
}
// Handle SubscribeResponse_Update message from gNMI and parse contained telemetry data
func (h *handler) handleSubscribeResponseUpdate(acc telegraf.Accumulator, response *gnmi.SubscribeResponse_Update, extension []*gnmi_ext.Extension) {
grouper := metric.NewSeriesGrouper()
timestamp := time.Unix(0, response.Update.Timestamp)
// Extract tags from potential extension in the update notification
headerTags := make(map[string]string)
for _, ext := range extension {
currentExt := ext.GetRegisteredExt().Msg
if currentExt == nil {
break
}
switch ext.GetRegisteredExt().Id {
case eidJuniperTelemetryHeader:
// Juniper Header extension
// Decode it only if user requested it
if choice.Contains("juniper_header", h.vendorExt) {
juniperHeader := &jnpr_gnmi_extention.GnmiJuniperTelemetryHeaderExtension{}
if err := proto.Unmarshal(currentExt, juniperHeader); err != nil {
h.log.Errorf("unmarshal gnmi Juniper Header extension failed: %v", err)
} else {
// Add only relevant Tags from the Juniper Header extension.
// These are required for aggregation
headerTags["component_id"] = strconv.FormatUint(uint64(juniperHeader.GetComponentId()), 10)
headerTags["component"] = juniperHeader.GetComponent()
headerTags["sub_component_id"] = strconv.FormatUint(uint64(juniperHeader.GetSubComponentId()), 10)
}
}
default:
continue
}
}
// Extract the path part valid for the whole set of updates if any
prefix := newInfoFromPath(response.Update.Prefix)
if h.enforceFirstNamespaceAsOrigin {
prefix.enforceFirstNamespaceAsOrigin()
}
// Add info to the tags
headerTags["source"] = h.host
if !prefix.empty() {
headerTags["path"] = prefix.fullPath()
}
// Process and remove tag-updates from the response first so we can
// add all available tags to the metrics later.
var valueFields []updateField
for _, update := range response.Update.Update {
fullPath := prefix.append(update.Path)
if h.enforceFirstNamespaceAsOrigin {
prefix.enforceFirstNamespaceAsOrigin()
}
if update.Path.Origin != "" {
fullPath.origin = update.Path.Origin
}
fields, err := h.newFieldsFromUpdate(fullPath, update)
if err != nil {
h.log.Errorf("Processing update %v failed: %v", update, err)
}
// Prepare tags from prefix
tags := make(map[string]string, len(headerTags))
for key, val := range headerTags {
tags[key] = val
}
for key, val := range fullPath.tags(h.tagPathPrefix) {
tags[key] = val
}
// TODO: Handle each field individually to allow in-JSON tags
var tagUpdate bool
for _, tagSub := range h.tagsubs {
if !fullPath.equalsPathNoKeys(tagSub.fullPath) {
continue
}
h.log.Debugf("Tag-subscription update for %q: %+v", tagSub.Name, update)
if err := h.tagStore.insert(tagSub, fullPath, fields, tags); err != nil {
h.log.Errorf("Inserting tag failed: %v", err)
}
tagUpdate = true
break
}
if !tagUpdate {
valueFields = append(valueFields, fields...)
}
}
// Some devices do not provide a prefix, so do some guesswork based
// on the paths of the fields
if headerTags["path"] == "" && h.guessPathStrategy == "common path" {
if prefixPath := guessPrefixFromUpdate(valueFields); prefixPath != "" {
headerTags["path"] = prefixPath
}
}
// Parse individual update message and create measurements
for _, field := range valueFields {
if field.path.empty() {
continue
}
// Prepare tags from prefix
fieldTags := field.path.tags(h.tagPathPrefix)
tags := make(map[string]string, len(headerTags)+len(fieldTags))
for key, val := range headerTags {
tags[key] = val
}
for key, val := range fieldTags {
tags[key] = val
}
// Add the tags derived via tag-subscriptions
for k, v := range h.tagStore.lookup(field.path, tags) {
tags[k] = v
}
// Lookup alias for the metric
aliasPath, name := h.lookupAlias(field.path)
if name == "" {
h.log.Debugf("No measurement alias for gNMI path: %s", field.path)
if !h.emptyNameWarnShown {
if buf, err := json.Marshal(response); err == nil {
h.log.Warnf(emptyNameWarning, field.path, string(buf))
} else {
h.log.Warnf(emptyNameWarning, field.path, response.Update)
}
h.emptyNameWarnShown = true
}
}
aliasInfo := newInfoFromString(aliasPath)
if h.enforceFirstNamespaceAsOrigin {
aliasInfo.enforceFirstNamespaceAsOrigin()
}
if tags["path"] == "" && h.guessPathStrategy == "subscription" {
tags["path"] = aliasInfo.String()
}
// Group metrics
var key string
if h.canonicalFieldNames {
// Strip the origin is any for the field names
field.path.origin = ""
key = field.path.String()
key = strings.ReplaceAll(key, "-", "_")
} else {
// If the alias is a subpath of the field path and the alias is
// shorter than the full path to avoid an empty key, then strip the
// common part of the field is prefixed with the alias path. Note
// the origins can match or be empty and be considered equal.
if relative := aliasInfo.relative(field.path, true); relative != "" {
key = relative
} else {
// Otherwise use the last path element as the field key
key = field.path.base()
}
key = strings.ReplaceAll(key, "-", "_")
}
if h.trimSlash {
key = strings.TrimLeft(key, "/.")
}
if key == "" {
h.log.Errorf("Invalid empty path %q with alias %q", field.path.String(), aliasPath)
continue
}
grouper.Add(name, tags, timestamp, key, field.value)
}
// Add grouped measurements
for _, metricToAdd := range grouper.Metrics() {
acc.AddMetric(metricToAdd)
}
}
// Try to find the alias for the given path
type aliasCandidate struct {
path, alias string
}
func (h *handler) lookupAlias(info *pathInfo) (aliasPath, alias string) {
candidates := make([]aliasCandidate, 0)
for i, a := range h.aliases {
if !i.isSubPathOf(info) {
continue
}
candidates = append(candidates, aliasCandidate{i.String(), a})
}
if len(candidates) == 0 {
return "", ""
}
// Reverse sort the candidates by path length so we can use the longest match
sort.SliceStable(candidates, func(i, j int) bool {
return len(candidates[i].path) > len(candidates[j].path)
})
return candidates[0].path, candidates[0].alias
}
func guessPrefixFromUpdate(fields []updateField) string {
if len(fields) == 0 {
return ""
}
if len(fields) == 1 {
return fields[0].path.dir()
}
segments := make([]segment, 0, len(fields[0].path.segments))
commonPath := &pathInfo{
origin: fields[0].path.origin,
segments: append(segments, fields[0].path.segments...),
}
for _, f := range fields[1:] {
commonPath.keepCommonPart(f.path)
}
if commonPath.empty() {
return ""
}
return commonPath.String()
}

403
plugins/inputs/gnmi/path.go Normal file
View file

@ -0,0 +1,403 @@
package gnmi
import (
"strings"
"github.com/openconfig/gnmi/proto/gnmi"
)
type keySegment struct {
name string
path string
kv map[string]string
}
type segment struct {
namespace string
id string
}
type pathInfo struct {
origin string
target string
segments []segment
keyValues []keySegment
}
func newInfoFromString(path string) *pathInfo {
if path == "" {
return &pathInfo{}
}
parts := strings.Split(path, "/")
var origin string
if strings.HasSuffix(parts[0], ":") {
origin = strings.TrimSuffix(parts[0], ":")
parts = parts[1:]
}
info := &pathInfo{origin: origin}
for _, part := range parts {
if part == "" {
continue
}
info.segments = append(info.segments, segment{id: part})
}
info.normalize()
return info
}
func newInfoFromPathWithoutKeys(path *gnmi.Path) *pathInfo {
info := &pathInfo{
origin: path.Origin,
segments: make([]segment, 0, len(path.Elem)),
}
for _, elem := range path.Elem {
if elem.Name == "" {
continue
}
info.segments = append(info.segments, segment{id: elem.Name})
}
info.normalize()
return info
}
func newInfoFromPath(paths ...*gnmi.Path) *pathInfo {
if len(paths) == 0 {
return nil
}
info := &pathInfo{}
if paths[0] != nil {
info.origin = paths[0].Origin
info.target = paths[0].Target
}
for _, p := range paths {
if p == nil {
continue
}
for _, elem := range p.Elem {
if elem.Name != "" {
info.segments = append(info.segments, segment{id: elem.Name})
}
if len(elem.Key) == 0 {
continue
}
keyInfo := keySegment{
name: elem.Name,
path: info.String(),
kv: make(map[string]string, len(elem.Key)),
}
for k, v := range elem.Key {
keyInfo.kv[k] = v
}
info.keyValues = append(info.keyValues, keyInfo)
}
}
info.normalize()
return info
}
func (pi *pathInfo) empty() bool {
return len(pi.segments) == 0
}
func (pi *pathInfo) append(paths ...*gnmi.Path) *pathInfo {
// Copy the existing info
segments := make([]segment, 0, len(pi.segments))
path := &pathInfo{
origin: pi.origin,
target: pi.target,
segments: append(segments, pi.segments...),
keyValues: make([]keySegment, 0, len(pi.keyValues)),
}
for _, elem := range pi.keyValues {
keyInfo := keySegment{
name: elem.name,
path: elem.path,
kv: make(map[string]string, len(elem.kv)),
}
for k, v := range elem.kv {
keyInfo.kv[k] = v
}
path.keyValues = append(path.keyValues, keyInfo)
}
// Add the new segments
for _, p := range paths {
for _, elem := range p.Elem {
if elem.Name != "" {
path.segments = append(path.segments, segment{id: elem.Name})
}
if len(elem.Key) == 0 {
continue
}
keyInfo := keySegment{
name: elem.Name,
path: path.String(),
kv: make(map[string]string, len(elem.Key)),
}
for k, v := range elem.Key {
keyInfo.kv[k] = v
}
path.keyValues = append(path.keyValues, keyInfo)
}
}
path.normalize()
return path
}
func (pi *pathInfo) appendSegments(segments ...string) *pathInfo {
// Copy the existing info
seg := make([]segment, 0, len(segments))
path := &pathInfo{
origin: pi.origin,
target: pi.target,
segments: append(seg, pi.segments...),
keyValues: make([]keySegment, 0, len(pi.keyValues)),
}
for _, elem := range pi.keyValues {
keyInfo := keySegment{
name: elem.name,
path: elem.path,
kv: make(map[string]string, len(elem.kv)),
}
for k, v := range elem.kv {
keyInfo.kv[k] = v
}
path.keyValues = append(path.keyValues, keyInfo)
}
// Add the new segments
for _, s := range segments {
if s == "" {
continue
}
path.segments = append(path.segments, segment{id: s})
}
path.normalize()
return path
}
func (pi *pathInfo) normalize() {
if len(pi.segments) == 0 {
return
}
// Extract namespaces from segments
for i, s := range pi.segments {
if ns, id, found := strings.Cut(s.id, ":"); found {
pi.segments[i].namespace = ns
pi.segments[i].id = id
}
}
// Remove empty segments
segments := make([]segment, 0, len(pi.segments))
for _, s := range pi.segments {
if s.id != "" {
segments = append(segments, s)
}
}
pi.segments = segments
}
func (pi *pathInfo) enforceFirstNamespaceAsOrigin() {
if len(pi.segments) == 0 {
return
}
// Some devices supply the origin as part of the first path element,
// so try to find and extract it there.
if pi.segments[0].namespace != "" {
pi.origin = pi.segments[0].namespace
pi.segments[0].namespace = ""
}
}
func (pi *pathInfo) equalsPathNoKeys(path *gnmi.Path) bool {
if len(pi.segments) != len(path.Elem) {
return false
}
for i, s := range pi.segments {
if s.id != path.Elem[i].Name {
return false
}
}
return true
}
func (pi *pathInfo) isSubPathOf(path *pathInfo) bool {
// If both set an origin it has to match. Otherwise we ignore the origin
if pi.origin != "" && path.origin != "" && pi.origin != path.origin {
return false
}
// The "parent" path should have the same length or be shorter than the
// sub-path to have a chance to match
if len(pi.segments) > len(path.segments) {
return false
}
// Compare the elements and exit if we find a mismatch
for i, p := range pi.segments {
ps := path.segments[i]
if p.namespace != "" && ps.namespace != "" && p.namespace != ps.namespace {
return false
}
if p.id != ps.id {
return false
}
}
return true
}
func (pi *pathInfo) relative(path *pathInfo, withNamespace bool) string {
if !pi.isSubPathOf(path) || len(pi.segments) == len(path.segments) {
return ""
}
segments := path.segments[len(pi.segments):len(path.segments)]
var r string
if withNamespace && segments[0].namespace != "" {
r = segments[0].namespace + ":" + segments[0].id
} else {
r = segments[0].id
}
for _, s := range segments[1:] {
if withNamespace && s.namespace != "" {
r += "/" + s.namespace + ":" + s.id
} else {
r += "/" + s.id
}
}
return r
}
func (pi *pathInfo) keepCommonPart(path *pathInfo) {
shortestLen := len(pi.segments)
if len(path.segments) < shortestLen {
shortestLen = len(path.segments)
}
// Compare the elements and stop as soon as they do mismatch
var matchLen int
for i, p := range pi.segments[:shortestLen] {
if p != path.segments[i] {
break
}
matchLen = i + 1
}
if matchLen < 1 {
pi.segments = nil
return
}
pi.segments = pi.segments[:matchLen]
}
func (pi *pathInfo) dir() string {
if len(pi.segments) <= 1 {
return ""
}
var dir string
if pi.origin != "" {
dir = pi.origin + ":"
}
for _, s := range pi.segments[:len(pi.segments)-1] {
if s.namespace != "" {
dir += "/" + s.namespace + ":" + s.id
} else {
dir += "/" + s.id
}
}
return dir
}
func (pi *pathInfo) base() string {
if len(pi.segments) == 0 {
return ""
}
s := pi.segments[len(pi.segments)-1]
if s.namespace != "" {
return s.namespace + ":" + s.id
}
return s.id
}
func (pi *pathInfo) path() (origin, path string) {
if len(pi.segments) == 0 {
return pi.origin, "/"
}
for _, s := range pi.segments {
path += "/" + s.id
}
return pi.origin, path
}
func (pi *pathInfo) fullPath() string {
var path string
if pi.origin != "" {
path = pi.origin + ":"
}
if len(pi.segments) == 0 {
return path
}
for _, s := range pi.segments {
if s.namespace != "" {
path += "/" + s.namespace + ":" + s.id
} else {
path += "/" + s.id
}
}
return path
}
func (pi *pathInfo) String() string {
if len(pi.segments) == 0 {
return ""
}
origin, path := pi.path()
if origin != "" {
return origin + ":" + path
}
return path
}
func (pi *pathInfo) tags(pathPrefix bool) map[string]string {
tags := make(map[string]string, len(pi.keyValues))
for _, s := range pi.keyValues {
var prefix string
if pathPrefix && s.name != "" {
prefix = s.name + "_"
}
for k, v := range s.kv {
key := strings.ReplaceAll(prefix+k, "-", "_")
// Use short-form of key if possible
if _, exists := tags[key]; !exists {
tags[key] = v
continue
}
tags[s.path+"/"+key] = v
}
}
return tags
}

View file

@ -0,0 +1,158 @@
# gNMI telemetry input plugin
[[inputs.gnmi]]
## Address and port of the gNMI GRPC server
addresses = ["10.49.234.114:57777"]
## define credentials
username = "cisco"
password = "cisco"
## gNMI encoding requested (one of: "proto", "json", "json_ietf", "bytes")
# encoding = "proto"
## redial in case of failures after
# redial = "10s"
## gRPC Keepalive settings
## See https://pkg.go.dev/google.golang.org/grpc/keepalive
## The client will ping the server to see if the transport is still alive if it has
## not see any activity for the given time.
## If not set, none of the keep-alive setting (including those below) will be applied.
## If set and set below 10 seconds, the gRPC library will apply a minimum value of 10s will be used instead.
# keepalive_time = ""
## Timeout for seeing any activity after the keep-alive probe was
## sent. If no activity is seen the connection is closed.
# keepalive_timeout = ""
## gRPC Maximum Message Size
# max_msg_size = "4MB"
## Subtree depth for depth extension (disables if < 1)
## see https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-depth.md
# depth = 0
## Enable to get the canonical path as field-name
# canonical_field_names = false
## Remove leading slashes and dots in field-name
# trim_field_names = false
## Only receive updates for the state, also suppresses receiving the initial state
# updates_only = false
## Enforces the namespace of the first element as origin for aliases and
## response paths, required for backward compatibility.
## NOTE: Set to 'false' if possible but be aware that this might change the path tag!
# enforce_first_namespace_as_origin = true
## Guess the path-tag if an update does not contain a prefix-path
## Supported values are
## none -- do not add a 'path' tag
## common path -- use the common path elements of all fields in an update
## subscription -- use the subscription path
# path_guessing_strategy = "none"
## Prefix tags from path keys with the path element
# prefix_tag_key_with_path = false
## Optional client-side TLS to authenticate the device
## Set to true/false to enforce TLS being enabled/disabled. If not set,
## enable TLS only if any of the other options are specified.
# tls_enable =
## Trusted root certificates for server
# tls_ca = "/path/to/cafile"
## Used for TLS client certificate authentication
# tls_cert = "/path/to/certfile"
## Used for TLS client certificate authentication
# tls_key = "/path/to/keyfile"
## Password for the key file if it is encrypted
# tls_key_pwd = ""
## Send the specified TLS server name via SNI
# tls_server_name = "kubernetes.example.com"
## Minimal TLS version to accept by the client
# tls_min_version = "TLS12"
## List of ciphers to accept, by default all secure ciphers will be accepted
## See https://pkg.go.dev/crypto/tls#pkg-constants for supported values.
## Use "all", "secure" and "insecure" to add all support ciphers, secure
## suites or insecure suites respectively.
# tls_cipher_suites = ["secure"]
## Renegotiation method, "never", "once" or "freely"
# tls_renegotiation_method = "never"
## Use TLS but skip chain & host verification
# insecure_skip_verify = false
## gNMI subscription prefix (optional, can usually be left empty)
## See: https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-specification.md#222-paths
# origin = ""
# prefix = ""
# target = ""
## Vendor specific options
## This defines what vendor specific options to load.
## * Juniper Header Extension (juniper_header): some sensors are directly managed by
## Linecard, which adds the Juniper GNMI Header Extension. Enabling this
## allows the decoding of the Extension header if present. Currently this knob
## adds component, component_id & sub_component_id as additional tags
# vendor_specific = []
## YANG model paths for decoding IETF JSON payloads
## Model files are loaded recursively from the given directories. Disabled if
## no models are specified.
# yang_model_paths = []
## Define additional aliases to map encoding paths to measurement names
# [inputs.gnmi.aliases]
# ifcounters = "openconfig:/interfaces/interface/state/counters"
[[inputs.gnmi.subscription]]
## Name of the measurement that will be emitted
name = "ifcounters"
## Origin and path of the subscription
## See: https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-specification.md#222-paths
##
## origin usually refers to a (YANG) data model implemented by the device
## and path to a specific substructure inside it that should be subscribed
## to (similar to an XPath). YANG models can be found e.g. here:
## https://github.com/YangModels/yang/tree/master/vendor/cisco/xr
origin = "openconfig-interfaces"
path = "/interfaces/interface/state/counters"
## Subscription mode ("target_defined", "sample", "on_change") and interval
subscription_mode = "sample"
sample_interval = "10s"
## Suppress redundant transmissions when measured values are unchanged
# suppress_redundant = false
## If suppression is enabled, send updates at least every X seconds anyway
# heartbeat_interval = "60s"
## Tag subscriptions are applied as tags to other subscriptions.
# [[inputs.gnmi.tag_subscription]]
# ## When applying this value as a tag to other metrics, use this tag name
# name = "descr"
#
# ## All other subscription fields are as normal
# origin = "openconfig-interfaces"
# path = "/interfaces/interface/state"
# subscription_mode = "on_change"
#
# ## Match strategy to use for the tag.
# ## Tags are only applied for metrics of the same address. The following
# ## settings are valid:
# ## unconditional -- always match
# ## name -- match by the "name" key
# ## This resembles the previous 'tag-only' behavior.
# ## elements -- match by the keys in the path filtered by the path
# ## parts specified `elements` below
# ## By default, 'elements' is used if the 'elements' option is provided,
# ## otherwise match by 'name'.
# # match = ""
#
# ## For the 'elements' match strategy, at least one path-element name must
# ## be supplied containing at least one key to match on. Multiple path
# ## elements can be specified in any order. All given keys must be equal
# ## for a match.
# # elements = ["description", "interface"]

View file

@ -0,0 +1,135 @@
# gNMI telemetry input plugin
[[inputs.gnmi]]
## Address and port of the gNMI GRPC server
addresses = ["10.49.234.114:57777"]
## define credentials
username = "cisco"
password = "cisco"
## gNMI encoding requested (one of: "proto", "json", "json_ietf", "bytes")
# encoding = "proto"
## redial in case of failures after
# redial = "10s"
## gRPC Keepalive settings
## See https://pkg.go.dev/google.golang.org/grpc/keepalive
## The client will ping the server to see if the transport is still alive if it has
## not see any activity for the given time.
## If not set, none of the keep-alive setting (including those below) will be applied.
## If set and set below 10 seconds, the gRPC library will apply a minimum value of 10s will be used instead.
# keepalive_time = ""
## Timeout for seeing any activity after the keep-alive probe was
## sent. If no activity is seen the connection is closed.
# keepalive_timeout = ""
## gRPC Maximum Message Size
# max_msg_size = "4MB"
## Subtree depth for depth extension (disables if < 1)
## see https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-depth.md
# depth = 0
## Enable to get the canonical path as field-name
# canonical_field_names = false
## Remove leading slashes and dots in field-name
# trim_field_names = false
## Only receive updates for the state, also suppresses receiving the initial state
# updates_only = false
## Enforces the namespace of the first element as origin for aliases and
## response paths, required for backward compatibility.
## NOTE: Set to 'false' if possible but be aware that this might change the path tag!
# enforce_first_namespace_as_origin = true
## Guess the path-tag if an update does not contain a prefix-path
## Supported values are
## none -- do not add a 'path' tag
## common path -- use the common path elements of all fields in an update
## subscription -- use the subscription path
# path_guessing_strategy = "none"
## Prefix tags from path keys with the path element
# prefix_tag_key_with_path = false
## Optional client-side TLS to authenticate the device
{{template "/plugins/common/tls/client.conf"}}
## gNMI subscription prefix (optional, can usually be left empty)
## See: https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-specification.md#222-paths
# origin = ""
# prefix = ""
# target = ""
## Vendor specific options
## This defines what vendor specific options to load.
## * Juniper Header Extension (juniper_header): some sensors are directly managed by
## Linecard, which adds the Juniper GNMI Header Extension. Enabling this
## allows the decoding of the Extension header if present. Currently this knob
## adds component, component_id & sub_component_id as additional tags
# vendor_specific = []
## YANG model paths for decoding IETF JSON payloads
## Model files are loaded recursively from the given directories. Disabled if
## no models are specified.
# yang_model_paths = []
## Define additional aliases to map encoding paths to measurement names
# [inputs.gnmi.aliases]
# ifcounters = "openconfig:/interfaces/interface/state/counters"
[[inputs.gnmi.subscription]]
## Name of the measurement that will be emitted
name = "ifcounters"
## Origin and path of the subscription
## See: https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-specification.md#222-paths
##
## origin usually refers to a (YANG) data model implemented by the device
## and path to a specific substructure inside it that should be subscribed
## to (similar to an XPath). YANG models can be found e.g. here:
## https://github.com/YangModels/yang/tree/master/vendor/cisco/xr
origin = "openconfig-interfaces"
path = "/interfaces/interface/state/counters"
## Subscription mode ("target_defined", "sample", "on_change") and interval
subscription_mode = "sample"
sample_interval = "10s"
## Suppress redundant transmissions when measured values are unchanged
# suppress_redundant = false
## If suppression is enabled, send updates at least every X seconds anyway
# heartbeat_interval = "60s"
## Tag subscriptions are applied as tags to other subscriptions.
# [[inputs.gnmi.tag_subscription]]
# ## When applying this value as a tag to other metrics, use this tag name
# name = "descr"
#
# ## All other subscription fields are as normal
# origin = "openconfig-interfaces"
# path = "/interfaces/interface/state"
# subscription_mode = "on_change"
#
# ## Match strategy to use for the tag.
# ## Tags are only applied for metrics of the same address. The following
# ## settings are valid:
# ## unconditional -- always match
# ## name -- match by the "name" key
# ## This resembles the previous 'tag-only' behavior.
# ## elements -- match by the keys in the path filtered by the path
# ## parts specified `elements` below
# ## By default, 'elements' is used if the 'elements' option is provided,
# ## otherwise match by 'name'.
# # match = ""
#
# ## For the 'elements' match strategy, at least one path-element name must
# ## be supplied containing at least one key to match on. Multiple path
# ## elements can be specified in any order. All given keys must be equal
# ## for a match.
# # elements = ["description", "interface"]

View file

@ -0,0 +1,188 @@
package gnmi
import (
"fmt"
"sort"
"strings"
"github.com/influxdata/telegraf/internal"
)
type tagStore struct {
unconditional map[string]string
names map[string]map[string]string
elements elementsStore
}
type elementsStore struct {
required [][]string
tags map[string]map[string]string
}
func newTagStore(subs []tagSubscription) *tagStore {
store := tagStore{
unconditional: make(map[string]string),
names: make(map[string]map[string]string),
elements: elementsStore{
required: make([][]string, 0, len(subs)),
tags: make(map[string]map[string]string),
},
}
for _, s := range subs {
if s.Match == "elements" {
store.elements.required = append(store.elements.required, s.Elements)
}
}
return &store
}
// Store tags extracted from TagSubscriptions
func (s *tagStore) insert(subscription tagSubscription, path *pathInfo, values []updateField, tags map[string]string) error {
switch subscription.Match {
case "unconditional":
for _, f := range values {
tagName := subscription.Name
if len(f.path.segments) > 0 {
key := f.path.base()
key = strings.ReplaceAll(key, "-", "_")
tagName += "/" + key
}
sv, err := internal.ToString(f.value)
if err != nil {
return fmt.Errorf("conversion error for %v: %w", f.value, err)
}
if sv == "" {
delete(s.unconditional, tagName)
} else {
s.unconditional[tagName] = sv
}
}
case "name":
// Get the lookup key
key, found := tags["name"]
if !found {
return nil
}
// Make sure we have a valid map for the key
if _, exists := s.names[key]; !exists {
s.names[key] = make(map[string]string)
}
// Add the values
for _, f := range values {
tagName := subscription.Name
if len(f.path.segments) > 0 {
key := f.path.base()
key = strings.ReplaceAll(key, "-", "_")
tagName += "/" + key
}
sv, err := internal.ToString(f.value)
if err != nil {
return fmt.Errorf("conversion error for %v: %w", f.value, err)
}
if sv == "" {
delete(s.names[key], tagName)
} else {
s.names[key][tagName] = sv
}
}
case "elements":
key, match := getElementsKeys(path, subscription.Elements)
if !match || len(values) == 0 {
return nil
}
// Make sure we have a valid map for the key
if _, exists := s.elements.tags[key]; !exists {
s.elements.tags[key] = make(map[string]string)
}
// Add the values
for _, f := range values {
tagName := subscription.Name
if len(f.path.segments) > 0 {
key := f.path.base()
key = strings.ReplaceAll(key, "-", "_")
tagName += "/" + key
}
sv, err := internal.ToString(f.value)
if err != nil {
return fmt.Errorf("conversion error for %v: %w", f.value, err)
}
if sv == "" {
delete(s.elements.tags[key], tagName)
} else {
s.elements.tags[key][tagName] = sv
}
}
default:
return fmt.Errorf("unknown match strategy %q", subscription.Match)
}
return nil
}
func (s *tagStore) lookup(path *pathInfo, metricTags map[string]string) map[string]string {
// Add all unconditional tags
tags := make(map[string]string, len(s.unconditional))
for k, v := range s.unconditional {
tags[k] = v
}
// Match names
key, found := metricTags["name"]
if found {
for k, v := range s.names[key] {
tags[k] = v
}
}
// Match elements
for _, requiredKeys := range s.elements.required {
key, match := getElementsKeys(path, requiredKeys)
if !match {
continue
}
for k, v := range s.elements.tags[key] {
tags[k] = v
}
}
return tags
}
func getElementsKeys(path *pathInfo, elements []string) (string, bool) {
// Search for the required path elements and collect a ordered
// list of their values to in the form
// elementName1={keyA=valueA,keyB=valueB,...},...,elementNameN={keyY=valueY,keyZ=valueZ}
// where each elements' key-value list is enclosed in curly brackets.
keyParts := make([]string, 0, len(elements))
for _, requiredElement := range elements {
var found bool
var elementKVs []string
for _, segment := range path.keyValues {
if segment.name == requiredElement {
for k, v := range segment.kv {
elementKVs = append(elementKVs, k+"="+v)
}
found = true
break
}
}
// The element was not found, but all must match
if !found {
return "", false
}
// We need to order the element's key-value pairs as the map
// returns elements in random order
sort.Strings(elementKVs)
// Collect the element
keyParts = append(keyParts, requiredElement+"={"+strings.Join(elementKVs, ",")+"}")
}
return strings.Join(keyParts, ","), true
}

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,23 @@
[[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"
subscription_mode = "sample"
sample_interval = "10s"

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,24 @@
[[inputs.gnmi]]
addresses = ["dummy"]
name_override = "gnmi"
redial = "10s"
canonical_field_names = true
trim_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"
subscription_mode = "sample"
sample_interval = "10s"

View file

@ -0,0 +1 @@
oc-neigh-state,source=127.0.0.1,neighbor_address=192.0.2.1,name=default,oc-neigh-desc/description=EXAMPLE-PEER,/network-instances/network-instance/protocols/protocol/name=BGP,identifier=BGP session_state="ESTABLISHED" 1543236572000000000

View file

@ -0,0 +1,116 @@
[
{
"update": {
"timestamp": "1543236571000000000",
"prefix": {},
"update": [
{
"path": {
"elem": [
{
"name": "network-instances"
},
{
"name": "network-instance",
"key": {
"name": "default"
}
},
{
"name": "protocols"
},
{
"name": "protocol",
"key": {
"identifier": "BGP",
"name": "BGP"
}
},
{
"name": "bgp"
},
{
"name": "neighbors"
},
{
"name": "neighbor",
"key": {
"neighbor_address": "192.0.2.1"
}
},
{
"name": "state"
},
{
"name": "description"
}
]
},
"val": {
"stringVal": "EXAMPLE-PEER"
}
}
]
}
},
{
"syncResponse": true
},
{
"update": {
"timestamp": "1543236572000000000",
"prefix": {},
"update": [
{
"path": {
"elem": [
{
"name": "network-instances"
},
{
"name": "network-instance",
"key": {
"name": "default"
}
},
{
"name": "protocols"
},
{
"name": "protocol",
"key": {
"identifier": "BGP",
"name": "BGP"
}
},
{
"name": "bgp"
},
{
"name": "neighbors"
},
{
"name": "neighbor",
"key": {
"neighbor_address": "192.0.2.1"
}
},
{
"name": "state"
},
{
"name": "session-state"
}
]
},
"val": {
"stringVal": "ESTABLISHED"
}
}
]
}
},
{
"syncResponse": true
}
]

View file

@ -0,0 +1,14 @@
[[inputs.gnmi]]
addresses = ["127.0.0.1"]
[[inputs.gnmi.subscription]]
name = "oc-neigh-state"
origin = "openconfig"
path = "/network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/state/session-state"
subscription_mode = "sample"
sample_interval = "10s"
[[inputs.gnmi.tag_subscription]]
name = "oc-neigh-desc"
origin = "openconfig"
path = "/network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/state/description"
subscription_mode = "on_change"
elements = ["network-instance", "protocol", "neighbor"]

View file

@ -0,0 +1 @@
ifcounters,path=openconfig-interfaces:/interfaces/interface/state,name=eth42,descr/description=eth42,source=127.0.0.1 counters=5678i 1673608605875353770

View file

@ -0,0 +1,49 @@
[
{
"update": {
"timestamp": "1673608605875353770",
"prefix": {
"origin": "openconfig-interfaces",
"elem": [
{
"name": "interfaces"
},
{
"name": "interface",
"key":{"name":"eth42"}
},
{
"name": "state"
}
],
"target": "subscription"
},
"update": [
{
"path": {
"elem": [
{
"name": "counters"
}
]
},
"val": {
"intVal": "5678"
}
},
{
"path": {
"elem": [
{
"name": "description"
}
]
},
"val": {
"stringVal": "eth42"
}
}
]
}
}
]

View file

@ -0,0 +1,15 @@
[[inputs.gnmi]]
addresses = ["dummy"]
name_override = "gnmi"
redial = "10s"
[[inputs.gnmi.subscription]]
name = "ifcounters"
origin = "openconfig-interfaces"
path = "/interfaces/interface/state/counters"
subscription_mode = "sample"
sample_interval = "10s"
[[inputs.gnmi.tag_subscription]]
name = "descr"
origin = "openconfig-interfaces"
path = "/interfaces/interface/state/description"
subscription_mode = "on_change"

View file

@ -0,0 +1 @@
ifcounters,path=openconfig-interfaces:/interfaces/interface/state,name=eth42,descr/description=eth42,source=127.0.0.1 counters=5678i 1673608605875353770

View file

@ -0,0 +1,49 @@
[
{
"update": {
"timestamp": "1673608605875353770",
"prefix": {
"origin": "openconfig-interfaces",
"elem": [
{
"name": "interfaces"
},
{
"name": "interface",
"key":{"name":"eth42"}
},
{
"name": "state"
}
],
"target": "subscription"
},
"update": [
{
"path": {
"elem": [
{
"name": "counters"
}
]
},
"val": {
"intVal": "5678"
}
},
{
"path": {
"elem": [
{
"name": "description"
}
]
},
"val": {
"stringVal": "eth42"
}
}
]
}
}
]

View file

@ -0,0 +1,16 @@
[[inputs.gnmi]]
addresses = ["rt-01:nnnnn", "rt-02:nnnnn"]
name_override = "gnmi"
redial = "10s"
[[inputs.gnmi.subscription]]
name = "ifcounters"
origin = "openconfig-interfaces"
path = "/interfaces/interface/state/counters"
subscription_mode = "sample"
sample_interval = "10s"
[[inputs.gnmi.subscription]]
name = "descr"
origin = "openconfig-interfaces"
path = "/interfaces/interface/state/description"
subscription_mode = "on_change"
tag_only = true

View file

@ -0,0 +1,7 @@
optical_channel,component_name=CM-1,source=127.0.0.1 cpu/openconfig_platform_cpu:utilization/state/avg=13u,cpu/openconfig_platform_cpu:utilization/state/instant=16u,cpu/openconfig_platform_cpu:utilization/state/interval=3600000000000u,cpu/openconfig_platform_cpu:utilization/state/max=17u,cpu/openconfig_platform_cpu:utilization/state/min=8u,name="CM-1",state/memory/available=5041100000u,state/memory/utilized=3099808000u,state/temperature/avg=20.5,state/temperature/instant=20.399999618530273,state/temperature/interval=3600000000000u,state/temperature/max=20.700000762939453,state/temperature/min=20.399999618530273 1714598222912553000
optical_channel,component_name=AP-1,source=127.0.0.1 name="AP-1",state/temperature/avg=34.099998474121094,state/temperature/instant=34.29999923706055,state/temperature/interval=3600000000000u,state/temperature/max=34.599998474121094,state/temperature/min=33.599998474121094 1714598222912553000
optical_channel,component_name=LM-1,source=127.0.0.1 name="LM-1",state/temperature/avg=40.79999923706055,state/temperature/instant=40.599998474121094,state/temperature/interval=3600000000000u,state/temperature/max=41.400001525878906,state/temperature/min=40.400001525878906 1714598222912553000
optical_channel,component_name=LM-1,source=127.0.0.1,subcomponent_name=PORT-1-1 subcomponents/subcomponent/config/name="PORT-1-1",subcomponents/subcomponent/name="PORT-1-1",subcomponents/subcomponent/state/name="PORT-1-1" 1714598222912553000
optical_channel,component_name=LM-1,source=127.0.0.1,subcomponent_name=PORT-1-2 subcomponents/subcomponent/config/name="PORT-1-2",subcomponents/subcomponent/name="PORT-1-2",subcomponents/subcomponent/state/name="PORT-1-2" 1714598222912553000
optical_channel,component_name=LM-1,source=127.0.0.1,subcomponent_name=PORT-1-4 subcomponents/subcomponent/config/name="PORT-1-4",subcomponents/subcomponent/name="PORT-1-4",subcomponents/subcomponent/state/name="PORT-1-4" 1714598222912553000
optical_channel,component_name=LM-1,source=127.0.0.1,subcomponent_name=PORT-1-12 subcomponents/subcomponent/config/name="PORT-1-12",subcomponents/subcomponent/name="PORT-1-12",subcomponents/subcomponent/state/name="PORT-1-12" 1714598222912553000

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,10 @@
[[inputs.gnmi]]
addresses = ["dummy"]
prefix_tag_key_with_path = true
[[inputs.gnmi.subscription]]
name = "optical_channel"
path = "/components/component[name=*]"
subscription_mode = "sample"
origin = "openconfig-platform"
sample_interval = "10s"

View file

@ -0,0 +1 @@
interface,name=ethernet-1/1,source=127.0.0.1 interface=1i,transceiver=2i,ethernet=3i,ethernet/flow_control="false",sflow="disable" 1679648530391910312

View file

@ -0,0 +1,94 @@
[
{
"update": {
"timestamp": "1679648530391910312",
"update": [
{
"path": {
"origin": "srl_nokia-interfaces",
"elem": [
{
"name": "interface",
"key":{"name":"ethernet-1/1"}
}
]
},
"val": {
"intVal": "1"
}
},
{
"path": {
"origin": "srl_nokia-interfaces",
"elem": [
{
"name": "interface",
"key":{"name":"ethernet-1/1"}
},
{
"name": "transceiver"
}
]
},
"val": {
"intVal": "2"
}
},
{
"path": {
"origin": "srl_nokia-interfaces",
"elem": [
{
"name": "interface",
"key":{"name":"ethernet-1/1"}
},
{
"name": "ethernet"
}
]
},
"val": {
"intVal": "3"
}
},
{
"path": {
"origin": "srl_nokia-interfaces",
"elem": [
{
"name": "interface",
"key":{"name":"ethernet-1/1"}
},
{
"name": "ethernet"
},
{
"name": "flow-control"
}
]
},
"val": {
"stringVal": "false"
}
},
{
"path": {
"origin": "srl_nokia-interfaces",
"elem": [
{
"name": "interface",
"key":{"name":"ethernet-1/1"}
},
{
"name": "sflow"
}
]
},
"val": {
"stringVal": "disable"
}
}
]
}
}
]

View file

@ -0,0 +1,10 @@
[[inputs.gnmi]]
addresses = ["dummy"]
name_override = "gnmi"
redial = "10s"
[[inputs.gnmi.subscription]]
name = "interface"
path = "/interface"
subscription_mode = "sample"
sample_interval = "10s"

View file

@ -0,0 +1,119 @@
components,/components/component/properties/property/name=mem-util-kernel-size,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=671088216u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=187929304u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-utilization,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=28i 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-ifd-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=97240u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-ifd-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=442u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-ifd-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-ifd-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-ifl-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=95272u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-ifl-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=132u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-ifl-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-ifl-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-iff-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=38640u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-iff-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=178u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-iff-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-iff-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-rt-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=82592u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-rt-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=914609u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-rt-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=914255u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-rt-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-rtt-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=7212u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-rtt-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=25u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-rtt-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-rtt-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-nh-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=180544u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-nh-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=519u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-nh-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=21u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-nh-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-filter-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=144380u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-filter-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=2674u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-filter-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=739u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-filter-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-cos-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=41488u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-cos-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=383u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-cos-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=53u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-cos-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-cos-halp-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=482008u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-cos-halp-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=102u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-cos-halp-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-cos-halp-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-rt-mac-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=20u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-rt-mac-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=1u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-rt-mac-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-rt-mac-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-fpdl-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=364u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-fpdl-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=16u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-fpdl-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=9u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-fpdl-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-fpb-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=56u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-fpb-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=4u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-fpb-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=2u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-fpb-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-fpb-syms-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=104u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-fpb-syms-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=4u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-fpb-syms-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=2u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-fpb-syms-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-agent-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=19548u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-agent-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=1679742u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-agent-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=1679691u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-agent-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-an-stats-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=5503680u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-an-stats-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=10192u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-an-stats-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-an-stats-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-resolve-bind-point-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=72u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-resolve-bind-point-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=12u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-resolve-bind-point-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=6u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-resolve-bind-point-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-entry-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=95436u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-entry-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=2812u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-entry-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=1435u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-entry-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-tcam-entry-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=33920u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-tcam-entry-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=546u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-tcam-entry-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-tcam-entry-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-id-entry-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=448u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-id-entry-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=40u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-id-entry-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=24u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-id-entry-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-bmap-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=9216u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-bmap-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=62u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-bmap-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=24u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-bmap-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-hw-hdl-rule-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=49172u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-hw-hdl-rule-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=2257u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-hw-hdl-rule-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=1140u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-hw-hdl-rule-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-lagmatch-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=72u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-lagmatch-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=2u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-lagmatch-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-lagmatch-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-cntr-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=372008u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-cntr-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=4444u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-cntr-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=1628u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-cntr-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-policer-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=192544u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-policer-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=600u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-policer-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=240u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-policer-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-misc-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=984u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-misc-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=83u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-misc-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=1u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-dfw-misc-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-halp-unknown-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=92u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-halp-unknown-allocations,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=3u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-halp-unknown-frees,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=2u 1688641479762000000
components,/components/component/properties/property/name=mem-util-kernel-halp-unknown-allocations-failed,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=0u 1688641479762000000
components,/components/component/properties/property/name=mem-util-dma-size,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=67108864u 1688641479762000000
components,/components/component/properties/property/name=mem-util-dma-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=4655312u 1688641479762000000
components,/components/component/properties/property/name=mem-util-dma-utilization,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=6i 1688641479762000000
components,/components/component/properties/property/name=mem-util-pkt-dma-desc-size,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=12582912u 1688641479762000000
components,/components/component/properties/property/name=mem-util-pkt-dma-desc-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=10257712u 1688641479762000000
components,/components/component/properties/property/name=mem-util-pkt-dma-desc-utilization,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=81i 1688641479762000000
components,/components/component/properties/property/name=mem-util-bcm-sdk-size,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=268435456u 1688641479762000000
components,/components/component/properties/property/name=mem-util-bcm-sdk-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=157163104u 1688641479762000000
components,/components/component/properties/property/name=mem-util-bcm-sdk-utilization,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=58i 1688641479762000000
components,/components/component/properties/property/name=mem-util-packet-dma-size,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=113246208u 1688641479762000000
components,/components/component/properties/property/name=mem-util-packet-dma-bytes-allocated,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=56030424u 1688641479762000000
components,/components/component/properties/property/name=mem-util-packet-dma-utilization,name=FPC0:CPU0,path=/components/component/properties,source=127.0.0.1 component/properties/property/state/value=49i 1688641479762000000

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,13 @@
[[inputs.gnmi]]
addresses = ["dummy"]
redial = "10s"
[inputs.gnmi.aliases]
components = "/components"
[[inputs.gnmi.subscription]]
name = "memory"
origin = "openconfig"
path = "/junos/system/linecard/cpu/memory"
subscription_mode = "sample"
sample_interval = "60s"

View file

@ -0,0 +1 @@
interfaces,name=eth42,path=openconfig-interfaces:/interfaces/interface,source=127.0.0.1 descr="eth42",id=42425u,in_pkts=5678u,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,22 @@
[[inputs.gnmi]]
addresses = ["dummy"]
name_override = "gnmi"
redial = "10s"
[[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"
subscription_mode = "sample"
sample_interval = "10s"

View file

@ -0,0 +1 @@
ifdesc,name=FourHundredGigE0/2/0/3,path=openconfig-interfaces:/interfaces/interface/state,source=127.0.0.1 description="REDACTED" 1696324083211000000

View file

@ -0,0 +1,33 @@
[
{
"update": {
"timestamp": "1696324083211000000",
"prefix": {
"origin": "openconfig-interfaces"
},
"update": [
{
"path": {
"elem": [
{
"name": "interfaces"
},
{
"name": "interface",
"key": {
"name": "FourHundredGigE0/2/0/3"
}
},
{
"name": "state"
}
]
},
"val": {
"json_ietf_val": "eyJkZXNjcmlwdGlvbiI6IlJFREFDVEVEIn0="
}
}
]
}
}
]

View file

@ -0,0 +1,13 @@
[[inputs.gnmi]]
addresses = ["dummy"]
name_override = "gnmi"
redial = "10s"
encoding = "json_ietf"
path_guessing_strategy = "common path"
[[inputs.gnmi.subscription]]
name = "ifdesc"
origin = "openconfig-interfaces"
path = '/interfaces/interface[name=FourHundredGigE*]/state/description'
subscription_mode = "sample"
sample_interval = "60s"

View file

@ -0,0 +1 @@
ifcounters,path=oc-if:/interfaces/oc-if:interface/oc-if:state/oc-if:counters,source=127.0.0.1 in_1024_to_1518_octet_pkts=0u,in_128_to_255_octet_pkts=0u,in_1519_to_2047_octet_pkts=0u,in_2048_to_4095_octet_pkts=0u,in_256_to_511_octet_pkts=0u,in_4096_to_9216_octet_pkts=0u,in_512_to_1023_octet_pkts=0u,in_64_octet_pkts=0u,in_65_to_127_octet_pkts=0u,in_broadcast_pkts=0u,in_crc_error_pkts=0u,in_discards=0u,in_discards_octets=0u,in_dropped_octets=0u,in_dropped_pkts=0u,in_errors=0u,in_jabber_pkts=0u,in_multicast_pkts=0u,in_octets=0u,in_oversize_pkts=0u,in_pkts=0u,in_undersize_pkts=0u,in_unicast_pkts=0u,last_clear=1691859140059797458u,link_flap_events=0u,name="\\\"1\\",out_1519_to_2047_octet_pkts=0u,out_2048_to_4095_octet_pkts=0u,out_4096_to_9216_octet_pkts=0u,out_broadcast_pkts=0u,out_errors=0u,out_multicast_pkts=0u,out_octets=0u,out_pkts=0u,out_unicast_pkts=0u 1696617695101000000

View file

@ -0,0 +1,445 @@
[
{
"update": {
"timestamp": "1696617695101000000",
"prefix": {
"elem": [
{
"name": "oc-if:interfaces"
},
{
"name": "oc-if:interface"
},
{
"name": "oc-if:state"
},
{
"name": "oc-if:counters"
}
]
},
"update": [
{
"path": {
"elem": [
{
"name": "in-1024-to-1518-octet-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-128-to-255-octet-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-1519-to-2047-octet-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-2048-to-4095-octet-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-256-to-511-octet-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-4096-to-9216-octet-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-512-to-1023-octet-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-64-octet-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-65-to-127-octet-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-broadcast-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-crc-error-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-discards"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-discards-octets"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-dropped-octets"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-dropped-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-errors"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-jabber-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-multicast-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-octets"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-oversize-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-undersize-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-unicast-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "last-clear"
}
]
},
"val": {
"uintVal": "1691859140059797458"
}
},
{
"path": {
"elem": [
{
"name": "link-flap-events"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "name"
}
]
},
"val": {
"stringVal": "\\\"1\\"
}
},
{
"path": {
"elem": [
{
"name": "out-1519-to-2047-octet-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "out-2048-to-4095-octet-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "out-4096-to-9216-octet-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "out-broadcast-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "out-errors"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "out-multicast-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "out-octets"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "out-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "out-unicast-pkts"
}
]
},
"val": {
"uintVal": "0"
}
}
]
}
}
]

View file

@ -0,0 +1,11 @@
[[inputs.gnmi]]
addresses = ["dummy"]
name_override = "gnmi"
redial = "10s"
[[inputs.gnmi.subscription]]
name = "ifcounters"
origin = "openconfig-interfaces"
path = "/oc-if:interfaces/oc-if:interface/oc-if:state/oc-if:counters"
subscription_mode = "sample"
sample_interval = "30s"

View file

@ -0,0 +1 @@
ifcounters,name=Ethernet35,path=/interfaces/interface/state/counters,source=127.0.0.1 in_broadcast_pkts=0u,in_discards=0u,in_errors=0u,in_fcs_errors=0u,in_multicast_pkts=0u,in_octets=0u,in_pkts=0u,in_unicast_pkts=0u,out_broadcast_pkts=0u,out_discards=0u,out_errors=0u,out_multicast_pkts=0u,out_octets=0u,out_pkts=0u,out_unicast_pkts=0u 1704442117721474264

View file

@ -0,0 +1,208 @@
[
{
"update": {
"timestamp": "1704442117721474264",
"prefix": {
"elem": [
{
"name": "interfaces"
},
{
"name": "interface",
"key": {
"name": "Ethernet35"
}
},
{
"name": "state"
},
{
"name": "counters"
}
]
},
"update": [
{
"path": {
"elem": [
{
"name": "in-broadcast-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-discards"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-errors"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-fcs-errors"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-multicast-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-octets"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "in-unicast-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "out-broadcast-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "out-discards"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "out-errors"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "out-multicast-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "out-octets"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "out-pkts"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "out-unicast-pkts"
}
]
},
"val": {
"uintVal": "0"
}
}
]
}
}
]

View file

@ -0,0 +1,14 @@
[[inputs.gnmi]]
addresses = ["dummy"]
encoding = "json_ietf"
tagexclude = ["path"]
[inputs.gnmi.tags]
test_tag = "test"
[[inputs.gnmi.subscription]]
name = "ifcounters"
origin = "openconfig"
path = "/interfaces/interface/state/counters"
subscription_mode = "sample"
sample_interval = "10s"

View file

@ -0,0 +1,2 @@
interfaces-counter,name=AppGigabitEthernet1/0/1,source=127.0.0.1 discontinuity_time="2023-11-15T05:50:40+00:00" 1708069483623763000
interfaces-counter,name=FortyGigabitEthernet1/1/1,source=127.0.0.1 discontinuity_time="2023-11-15T05:50:40+00:00" 1708069483623763000

View file

@ -0,0 +1,51 @@
[
{
"update": {
"timestamp": "1708069483623763000",
"update": [
{
"path": {
"elem": [
{
"name": "Cisco-IOS-XE-interfaces-oper:interfaces"
},
{
"name": "interface",
"key": {
"name": "AppGigabitEthernet1/0/1"
}
},
{
"name": "statistics"
}
]
},
"val": {
"jsonIetfVal": "eyJkaXNjb250aW51aXR5LXRpbWUiOiIyMDIzLTExLTE1VDA1OjUwOjQwKzAwOjAwIn0K"
}
},
{
"path": {
"elem": [
{
"name": "Cisco-IOS-XE-interfaces-oper:interfaces"
},
{
"name": "interface",
"key": {
"name": "FortyGigabitEthernet1/1/1"
}
},
{
"name": "statistics"
}
]
},
"val": {
"jsonIetfVal": "eyJkaXNjb250aW51aXR5LXRpbWUiOiIyMDIzLTExLTE1VDA1OjUwOjQwKzAwOjAwIn0K"
}
}
]
}
}
]

View file

@ -0,0 +1,9 @@
[[inputs.gnmi]]
addresses = ["dummy"]
[[inputs.gnmi.subscription]]
name = "interfaces-counter"
origin = "rfc7951"
path = "/Cisco-IOS-XE-interfaces-oper:interfaces/interface/statistics"
subscription_mode = "sample"
sample_interval = "5s"

View file

@ -0,0 +1,4 @@
gnmi_sys_memory,path=/system/memory/state,source=127.0.0.1 reserved=6359478272u,used=3479629824u 1709737743568119333
gnmi_sys_memory,path=/system/memory/state,source=127.0.0.1 used=3479527424u 1709737753565697718
gnmi_sys_cpu,index=ALL,path=/system/cpus/cpu/state,source=127.0.0.1 hardware_interrupt/min_time=1709805333568034887u 1709805333566280930
gnmi_sys_cpu,index=ALL,path=/system/cpus/cpu/state,source=127.0.0.1 hardware_interrupt/min_time=1709805343567684412u,idle/avg=89u,idle/instant=90u 1709805343565718902

View file

@ -0,0 +1,182 @@
[
{
"update": {
"timestamp": "1709737743568119333",
"prefix": {
"elem": [
{
"name": "system"
},
{
"name": "memory"
},
{
"name": "state"
}
]
},
"update": [
{
"path": {
"elem": [
{
"name": "reserved"
}
]
},
"val": {
"uintVal": "6359478272"
}
},
{
"path": {
"elem": [
{
"name": "used"
}
]
},
"val": {
"uintVal": "3479629824"
}
}
]
}
},
{
"update": {
"timestamp": "1709737753565697718",
"update": [
{
"path": {
"elem": [
{
"name": "system"
},
{
"name": "memory"
},
{
"name": "state"
},
{
"name": "used"
}
]
},
"val": {
"uintVal": "3479527424"
}
}
]
}
},
{
"update": {
"timestamp": "1709805333566280930",
"update": [
{
"path": {
"elem": [
{
"name": "system"
},
{
"name": "cpus"
},
{
"name": "cpu",
"key": {
"index": "ALL"
}
},
{
"name": "state"
},
{
"name": "hardware-interrupt"
},
{
"name": "min-time"
}
]
},
"val": {
"uintVal": "1709805333568034887"
}
}
]
}
},
{
"update": {
"timestamp": "1709805343565718902",
"prefix": {
"elem": [
{
"name": "system"
},
{
"name": "cpus"
},
{
"name": "cpu",
"key": {
"index": "ALL"
}
},
{
"name": "state"
}
]
},
"update": [
{
"path": {
"elem": [
{
"name": "hardware-interrupt"
},
{
"name": "min-time"
}
]
},
"val": {
"uintVal": "1709805343567684412"
}
},
{
"path": {
"elem": [
{
"name": "idle"
},
{
"name": "avg"
}
]
},
"val": {
"uintVal": "89"
}
},
{
"path": {
"elem": [
{
"name": "idle"
},
{
"name": "instant"
}
]
},
"val": {
"uintVal": "90"
}
}
]
}
}
]

View file

@ -0,0 +1,15 @@
[[inputs.gnmi]]
addresses = ["dummy"]
path_guessing_strategy = "subscription"
[[inputs.gnmi.subscription]]
name = "gnmi_sys_cpu"
path = "/system/cpus/cpu/state"
subscription_mode = "sample"
sample_interval = "10s"
[[inputs.gnmi.subscription]]
name = "gnmi_sys_memory"
path = "/system/memory/state"
subscription_mode = "sample"
sample_interval = "10s"

View file

@ -0,0 +1,4 @@
gnmi_sys_memory,path=/system/memory/state,source=127.0.0.1 /system/memory/state/reserved=6359478272u,/system/memory/state/used=3479629824u 1709737743568119333
gnmi_sys_memory,source=127.0.0.1 /system/memory/state/used=3479527424u 1709737753565697718
gnmi_sys_cpu,index=ALL,source=127.0.0.1 /system/cpus/cpu/state/hardware_interrupt/min_time=1709805333568034887u 1709805333566280930
gnmi_sys_cpu,index=ALL,path=/system/cpus/cpu/state,source=127.0.0.1 /system/cpus/cpu/state/hardware_interrupt/min_time=1709805343567684412u,/system/cpus/cpu/state/idle/avg=89u,/system/cpus/cpu/state/idle/instant=90u 1709805343565718902

View file

@ -0,0 +1,182 @@
[
{
"update": {
"timestamp": "1709737743568119333",
"prefix": {
"elem": [
{
"name": "system"
},
{
"name": "memory"
},
{
"name": "state"
}
]
},
"update": [
{
"path": {
"elem": [
{
"name": "reserved"
}
]
},
"val": {
"uintVal": "6359478272"
}
},
{
"path": {
"elem": [
{
"name": "used"
}
]
},
"val": {
"uintVal": "3479629824"
}
}
]
}
},
{
"update": {
"timestamp": "1709737753565697718",
"update": [
{
"path": {
"elem": [
{
"name": "system"
},
{
"name": "memory"
},
{
"name": "state"
},
{
"name": "used"
}
]
},
"val": {
"uintVal": "3479527424"
}
}
]
}
},
{
"update": {
"timestamp": "1709805333566280930",
"update": [
{
"path": {
"elem": [
{
"name": "system"
},
{
"name": "cpus"
},
{
"name": "cpu",
"key": {
"index": "ALL"
}
},
{
"name": "state"
},
{
"name": "hardware-interrupt"
},
{
"name": "min-time"
}
]
},
"val": {
"uintVal": "1709805333568034887"
}
}
]
}
},
{
"update": {
"timestamp": "1709805343565718902",
"prefix": {
"elem": [
{
"name": "system"
},
{
"name": "cpus"
},
{
"name": "cpu",
"key": {
"index": "ALL"
}
},
{
"name": "state"
}
]
},
"update": [
{
"path": {
"elem": [
{
"name": "hardware-interrupt"
},
{
"name": "min-time"
}
]
},
"val": {
"uintVal": "1709805343567684412"
}
},
{
"path": {
"elem": [
{
"name": "idle"
},
{
"name": "avg"
}
]
},
"val": {
"uintVal": "89"
}
},
{
"path": {
"elem": [
{
"name": "idle"
},
{
"name": "instant"
}
]
},
"val": {
"uintVal": "90"
}
}
]
}
}
]

View file

@ -0,0 +1,15 @@
[[inputs.gnmi]]
addresses = ["dummy"]
canonical_field_names = true
[[inputs.gnmi.subscription]]
name = "gnmi_sys_cpu"
path = "/system/cpus/cpu/state"
subscription_mode = "sample"
sample_interval = "10s"
[[inputs.gnmi.subscription]]
name = "gnmi_sys_memory"
path = "/system/memory/state"
subscription_mode = "sample"
sample_interval = "10s"

View file

@ -0,0 +1,5 @@
psu,name=PowerSupply1/A,path=openconfig:/components/component/power-supply/state,source=127.0.0.1 openconfig_platform_psu:capacity=715,openconfig_platform_psu:enabled=true,openconfig_platform_psu:input_current=0.47099998593330383,openconfig_platform_psu:input_voltage=208.5,openconfig_platform_psu:output_current=1.2029999494552612,openconfig_platform_psu:output_power=68.625,openconfig_platform_psu:output_voltage=56.367000579833984 1711178737105194000
psu,name=PowerSupply1/B,path=openconfig:/components/component/power-supply/state,source=127.0.0.1 openconfig_platform_psu:capacity=715,openconfig_platform_psu:enabled=true,openconfig_platform_psu:input_current=0.3930000066757202,openconfig_platform_psu:input_voltage=209.75,openconfig_platform_psu:output_current=0.9380000233650208,openconfig_platform_psu:output_power=51.875,openconfig_platform_psu:output_voltage=56.367000579833984 1711178737105194000
temp,name=InletTempSensor1,path=openconfig:/components/component/state/temperature,source=127.0.0.1 alarm_severity="openconfig-alarm-types:MINOR",alarm_status=false,alarm_threshold=0,avg=24.000000,instant=35.000000,interval=180000000000u,max=36.000000,min=0.000000 1715838159171548000
temp,name=OutletTempSensor1,path=openconfig:/components/component/state/temperature,source=127.0.0.1 alarm_severity="openconfig-alarm-types:MINOR",alarm_status=false,alarm_threshold=0,avg=29.000000,instant=44.000000,interval=180000000000u,max=44.000000,min=0.000000 1715838159171548000
temp,name=HotSpotTempSensor1,path=openconfig:/components/component/state/temperature,source=127.0.0.1 alarm_severity="openconfig-alarm-types:MINOR",alarm_status=false,alarm_threshold=0,avg=39.000000,instant=58.000000,interval=180000000000u,max=59.000000,min=0.000000 1715838159171548000

View file

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -0,0 +1,2 @@
<!-- markdownlint-disable -->
Files extracted from https://github.com/openconfig/public

View file

@ -0,0 +1,109 @@
module openconfig-alarm-types {
yang-version "1";
// namespace
namespace "http://openconfig.net/yang/alarms/types";
prefix "oc-alarm-types";
// import some basic types
import openconfig-extensions { prefix oc-ext; }
// meta
organization "OpenConfig working group";
contact
"OpenConfig working group
www.openconfig.net";
description
"This module defines operational state data related to alarms
that the device is reporting.
This model reuses some data items defined in the draft IETF
YANG Alarm Module:
https://tools.ietf.org/html/draft-vallin-netmod-alarm-module-02
Portions of this code were derived from the draft IETF YANG Alarm
Module. Please reproduce this note if possible.
IETF code is subject to the following copyright and license:
Copyright (c) IETF Trust and the persons identified as authors of
the code.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, is permitted pursuant to, and subject to the license
terms contained in, the Simplified BSD License set forth in
Section 4.c of the IETF Trust's Legal Provisions Relating
to IETF Documents (http://trustee.ietf.org/license-info).";
oc-ext:openconfig-version "0.2.1";
// OpenConfig specific extensions for module metadata.
oc-ext:regexp-posix;
oc-ext:catalog-organization "openconfig";
oc-ext:origin "openconfig";
// identity statements
identity OPENCONFIG_ALARM_SEVERITY {
description
"Base identity for alarm severity profiles. Derived
identities are based on contents of the draft
IETF YANG Alarm Module";
reference
"IETF YANG Alarm Module: Draft - typedef severity
https://tools.ietf.org/html/draft-vallin-netmod-alarm-module-02";
}
identity UNKNOWN {
base OPENCONFIG_ALARM_SEVERITY;
description
"Indicates that the severity level could not be determined.
This level SHOULD be avoided.";
}
identity MINOR {
base OPENCONFIG_ALARM_SEVERITY;
description
"Indicates the existence of a non-service affecting fault
condition and that corrective action should be taken in
order to prevent a more serious (for example, service
affecting) fault. Such a severity can be reported, for
example, when the detected alarm condition is not currently
degrading the capacity of the resource";
}
identity WARNING {
base OPENCONFIG_ALARM_SEVERITY;
description
"Indicates the detection of a potential or impending service
affecting fault, before any significant effects have been felt.
Action should be taken to further diagnose (if necessary) and
correct the problem in order to prevent it from becoming a more
serious service affecting fault.";
}
identity MAJOR {
base OPENCONFIG_ALARM_SEVERITY;
description
"Indicates that a service affecting condition has developed
and an urgent corrective action is required. Such a severity
can be reported, for example, when there is a severe
degradation in the capability of the resource and its full
capability must be restored.";
}
identity CRITICAL {
base OPENCONFIG_ALARM_SEVERITY;
description
"Indicates that a service affecting condition has occurred
and an immediate corrective action is required. Such a
severity can be reported, for example, when a resource becomes
totally out of service and its capability must be restored.";
}
}

View file

@ -0,0 +1,110 @@
module openconfig-extensions {
yang-version "1";
// namespace
namespace "http://openconfig.net/yang/openconfig-ext";
prefix "oc-ext";
// meta
organization "OpenConfig working group";
contact
"OpenConfig working group
www.openconfig.net";
description
"This module provides extensions to the YANG language to allow
OpenConfig specific functionality and meta-data to be defined.";
oc-ext:openconfig-version "0.5.1";
// extension statements
extension openconfig-version {
argument "semver" {
yin-element false;
}
description
"The OpenConfig version number for the module. This is
expressed as a semantic version number of the form:
x.y.z
where:
* x corresponds to the major version,
* y corresponds to a minor version,
* z corresponds to a patch version.
This version corresponds to the model file within which it is
defined, and does not cover the whole set of OpenConfig models.
Individual YANG modules are versioned independently -- the
semantic version is generally incremented only when there is a
change in the corresponding file. Submodules should always
have the same semantic version as their parent modules.
A major version number of 0 indicates that this model is still
in development (whether within OpenConfig or with industry
partners), and is potentially subject to change.
Following a release of major version 1, all modules will
increment major revision number where backwards incompatible
changes to the model are made.
The minor version is changed when features are added to the
model that do not impact current clients use of the model.
The patch-level version is incremented when non-feature changes
(such as bugfixes or clarifications to human-readable
descriptions that do not impact model functionality) are made
that maintain backwards compatibility.
The version number is stored in the module meta-data.";
}
extension regexp-posix {
description
"This extension indicates that the regular expressions included
within the YANG module specified are conformant with the POSIX
regular expression format rather than the W3C standard that is
specified by RFC6020 and RFC7950.";
}
extension operational {
description
"The operational annotation is specified in the context of a
grouping, leaf, or leaf-list within a YANG module. It indicates
that the nodes within the context are derived state on the device.
OpenConfig data models divide nodes into the following three categories:
- intended configuration - these are leaves within a container named
'config', and are the writable configuration of a target.
- applied configuration - these are leaves within a container named
'state' and are the currently running value of the intended configuration.
- derived state - these are the values within the 'state' container which
are not part of the applied configuration of the device. Typically, they
represent state values reflecting underlying operational counters, or
protocol statuses.";
}
extension catalog-organization {
argument "org" {
yin-element false;
}
description
"This extension specifies the organization name that should be used within
the module catalogue on the device for the specified YANG module. It stores
a pithy string where the YANG organization statement may contain more
details.";
}
extension origin {
argument "origin" {
yin-element false;
}
description
"This extension specifies the name of the origin that the YANG module
falls within. This allows multiple overlapping schema trees to be used
on a single network element without requiring module based prefixing
of paths.";
}
}

View file

@ -0,0 +1,92 @@
module openconfig-platform-psu {
yang-version "1";
// namespace
namespace "http://openconfig.net/yang/platform/psu";
prefix "oc-platform-psu";
// import some basic types
import openconfig-extensions { prefix oc-ext; }
import openconfig-types { prefix oc-types; }
// meta
organization "OpenConfig working group";
contact
"OpenConfig working group
www.openconfig.net";
description
"This module defines a schema for power supply components in
the OpenConfig platform model.";
oc-ext:openconfig-version "0.2.1";
// OpenConfig specific extensions for module metadata.
oc-ext:regexp-posix;
oc-ext:catalog-organization "openconfig";
oc-ext:origin "openconfig";
grouping psu-config {
description
"Configuration data for power supply components";
leaf enabled {
type boolean;
default true;
description
"Adminsitrative control on the on/off state of the power
supply unit.";
}
}
grouping psu-state {
description
"Operational state data for power supply components";
leaf capacity {
type oc-types:ieeefloat32;
units watts;
description
"Maximum power capacity of the power supply.";
}
leaf input-current {
type oc-types:ieeefloat32;
units amps;
description
"The input current draw of the power supply.";
}
leaf input-voltage {
type oc-types:ieeefloat32;
units volts;
description
"Input voltage to the power supply.";
}
leaf output-current {
type oc-types:ieeefloat32;
units amps;
description
"The output current supplied by the power supply.";
}
leaf output-voltage {
type oc-types:ieeefloat32;
units volts;
description
"Output voltage supplied by the power supply.";
}
leaf output-power {
type oc-types:ieeefloat32;
units watts;
description
"Output power supplied by the power supply.";
}
}
}

View file

@ -0,0 +1,80 @@
module openconfig-platform-types {
yang-version "1";
// namespace
namespace "http://openconfig.net/yang/platform-types";
prefix "oc-platform-types";
import openconfig-types { prefix oc-types; }
import openconfig-extensions { prefix oc-ext; }
// meta
organization
"OpenConfig working group";
contact
"OpenConfig working group
www.openconfig.net";
description
"This module defines data types (e.g., YANG identities)
to support the OpenConfig component inventory model.";
oc-ext:openconfig-version "1.6.0";
// OpenConfig specific extensions for module metadata.
oc-ext:regexp-posix;
oc-ext:catalog-organization "openconfig";
oc-ext:origin "openconfig";
// grouping statements
grouping avg-min-max-instant-stats-precision1-celsius {
description
"Common grouping for recording temperature values in
Celsius with 1 decimal precision. Values include the
instantaneous, average, minimum, and maximum statistics";
leaf instant {
type decimal64 {
fraction-digits 1;
}
units celsius;
description
"The instantaneous value of the statistic.";
}
leaf avg {
type decimal64 {
fraction-digits 1;
}
units celsius;
description
"The arithmetic mean value of the statistic over the
sampling period.";
}
leaf min {
type decimal64 {
fraction-digits 1;
}
units celsius;
description
"The minimum value of the statistic over the sampling
period";
}
leaf max {
type decimal64 {
fraction-digits 1;
}
units celsius;
description
"The maximum value of the statistic over the sampling
period";
}
uses oc-types:stat-interval-state;
}
}

View file

@ -0,0 +1,162 @@
module openconfig-platform {
yang-version "1";
// namespace
namespace "http://openconfig.net/yang/platform";
prefix "oc-platform";
import openconfig-platform-types { prefix oc-platform-types; }
import openconfig-extensions { prefix oc-ext; }
import openconfig-alarm-types { prefix oc-alarm-types; }
// meta
organization "OpenConfig working group";
contact
"OpenConfig working group
www.openconfig.net";
description
"This module defines a data model for representing a system
component inventory, which can include hardware or software
elements arranged in an arbitrary structure. The primary
relationship supported by the model is containment, e.g.,
components containing subcomponents.
It is expected that this model reflects every field replacable
unit on the device at a minimum (i.e., additional information
may be supplied about non-replacable components).
Every element in the inventory is termed a 'component' with each
component expected to have a unique name and type, and optionally
a unique system-assigned identifier and FRU number. The
uniqueness is guaranteed by the system within the device.
Components may have properties defined by the system that are
modeled as a list of key-value pairs. These may or may not be
user-configurable. The model provides a flag for the system
to optionally indicate which properties are user configurable.
Each component also has a list of 'subcomponents' which are
references to other components. Appearance in a list of
subcomponents indicates a containment relationship as described
above. For example, a linecard component may have a list of
references to port components that reside on the linecard.
This schema is generic to allow devices to express their own
platform-specific structure. It may be augmented by additional
component type-specific schemas that provide a common structure
for well-known component types. In these cases, the system is
expected to populate the common component schema, and may
optionally also represent the component and its properties in the
generic structure.
The properties for each component may include dynamic values,
e.g., in the 'state' part of the schema. For example, a CPU
component may report its utilization, temperature, or other
physical properties. The intent is to capture all platform-
specific physical data in one location, including inventory
(presence or absence of a component) and state (physical
attributes or status).";
oc-ext:openconfig-version "0.24.0";
// OpenConfig specific extensions for module metadata.
oc-ext:regexp-posix;
oc-ext:catalog-organization "openconfig";
oc-ext:origin "openconfig";
// grouping statements
grouping platform-component-temp-alarm-state {
description
"Temperature alarm data for platform components";
// TODO(aashaikh): consider if these leaves could be in a
// reusable grouping (not temperature-specific); threshold
// may always need to be units specific.
leaf alarm-status {
type boolean;
description
"A value of true indicates the alarm has been raised or
asserted. The value should be false when the alarm is
cleared.";
}
leaf alarm-threshold {
type uint32;
description
"The threshold value that was crossed for this alarm.";
}
leaf alarm-severity {
type identityref {
base oc-alarm-types:OPENCONFIG_ALARM_SEVERITY;
}
description
"The severity of the current alarm.";
}
}
grouping platform-component-temp-state {
description
"Temperature state data for device components";
container temperature {
description
"Temperature in degrees Celsius of the component. Values include
the instantaneous, average, minimum, and maximum statistics. If
avg/min/max statistics are not supported, the target is expected
to just supply the instant value";
uses oc-platform-types:avg-min-max-instant-stats-precision1-celsius;
uses platform-component-temp-alarm-state;
}
}
grouping platform-component-top {
description
"Top-level grouping for components in the device inventory";
container components {
description
"Enclosing container for the components in the system.";
list component {
key "name";
description
"List of components, keyed by component name.";
leaf name {
type leafref {
path "../config/name";
}
description
"References the component name";
}
container state {
config false;
description
"Operational state data for each component";
uses platform-component-temp-state;
}
}
}
}
// data definition statements
uses platform-component-top;
// augments
}

View file

@ -0,0 +1,66 @@
module openconfig-types {
yang-version "1";
namespace "http://openconfig.net/yang/openconfig-types";
prefix "oc-types";
// import statements
import openconfig-extensions { prefix oc-ext; }
// meta
organization
"OpenConfig working group";
contact
"OpenConfig working group
netopenconfig@googlegroups.com";
description
"This module contains a set of general type definitions that
are used across OpenConfig models. It can be imported by modules
that make use of these types.";
oc-ext:openconfig-version "1.0.0";
// OpenConfig specific extensions for module metadata.
oc-ext:regexp-posix;
oc-ext:catalog-organization "openconfig";
oc-ext:origin "openconfig";
typedef stat-interval {
type uint64;
units nanoseconds;
description
"A time interval over which a set of statistics is computed.
A common usage is to report the interval over which
avg/min/max stats are computed and reported.";
}
grouping stat-interval-state {
description
"Reusable leaf definition for stats computation interval";
leaf interval {
type oc-types:stat-interval;
description
"If supported by the system, this reports the time interval
over which the min/max/average statistics are computed by
the system.";
}
}
typedef ieeefloat32 {
type binary {
length "4";
}
description
"An IEEE 32-bit floating point number. The format of this number
is of the form:
1-bit sign
8-bit exponent
23-bit fraction
The floating point value is calculated using:
(-1)**S * 2**(Exponent-127) * (1+Fraction)";
}
}

View file

@ -0,0 +1,141 @@
[
{
"update": {
"timestamp": "1711178737105194000",
"update": [
{
"path": {
"origin": "openconfig",
"elem": [
{
"name": "components"
},
{
"name": "component",
"key": {
"name": "PowerSupply1/A"
}
},
{
"name": "power-supply"
},
{
"name": "state"
}
]
},
"val": {
"jsonIetfVal": "eyJvcGVuY29uZmlnLXBsYXRmb3JtLXBzdTplbmFibGVkIjp0cnVlLCJvcGVuY29uZmlnLXBsYXRmb3JtLXBzdTpjYXBhY2l0eSI6IlJETEFBQT09Iiwib3BlbmNvbmZpZy1wbGF0Zm9ybS1wc3U6aW5wdXQtY3VycmVudCI6IlB2RW02UT09Iiwib3BlbmNvbmZpZy1wbGF0Zm9ybS1wc3U6aW5wdXQtdm9sdGFnZSI6IlExQ0FBQT09Iiwib3BlbmNvbmZpZy1wbGF0Zm9ybS1wc3U6b3V0cHV0LWN1cnJlbnQiOiJQNW43NXc9PSIsIm9wZW5jb25maWctcGxhdGZvcm0tcHN1Om91dHB1dC12b2x0YWdlIjoiUW1GM3p3PT0iLCJvcGVuY29uZmlnLXBsYXRmb3JtLXBzdTpvdXRwdXQtcG93ZXIiOiJRb2xBQUE9PSJ9"
}
},
{
"path": {
"origin": "openconfig",
"elem": [
{
"name": "components"
},
{
"name": "component",
"key": {
"name": "PowerSupply1/B"
}
},
{
"name": "power-supply"
},
{
"name": "state"
}
]
},
"val": {
"jsonIetfVal": "eyJvcGVuY29uZmlnLXBsYXRmb3JtLXBzdTplbmFibGVkIjp0cnVlLCJvcGVuY29uZmlnLXBsYXRmb3JtLXBzdTpjYXBhY2l0eSI6IlJETEFBQT09Iiwib3BlbmNvbmZpZy1wbGF0Zm9ybS1wc3U6aW5wdXQtY3VycmVudCI6IlBzazNUQT09Iiwib3BlbmNvbmZpZy1wbGF0Zm9ybS1wc3U6aW5wdXQtdm9sdGFnZSI6IlExSEFBQT09Iiwib3BlbmNvbmZpZy1wbGF0Zm9ybS1wc3U6b3V0cHV0LWN1cnJlbnQiOiJQM0FneFE9PSIsIm9wZW5jb25maWctcGxhdGZvcm0tcHN1Om91dHB1dC12b2x0YWdlIjoiUW1GM3p3PT0iLCJvcGVuY29uZmlnLXBsYXRmb3JtLXBzdTpvdXRwdXQtcG93ZXIiOiJRaytBQUE9PSJ9"
}
}
]
}
},
{
"update": {
"timestamp": "1715838159171548000",
"update": [
{
"path": {
"origin": "openconfig",
"elem": [
{
"name": "components"
},
{
"name": "component",
"key": {
"name": "InletTempSensor1"
}
},
{
"name": "state"
},
{
"name": "temperature"
}
]
},
"val": {
"jsonIetfVal": "eyJpbnN0YW50IjoiMzUuMDAwMDAwIiwiYXZnIjoiMjQuMDAwMDAwIiwibWluIjoiMC4wMDAwMDAiLCJtYXgiOiIzNi4wMDAwMDAiLCJpbnRlcnZhbCI6IjE4MDAwMDAwMDAwMCIsImFsYXJtLXN0YXR1cyI6ZmFsc2UsImFsYXJtLXRocmVzaG9sZCI6MCwiYWxhcm0tc2V2ZXJpdHkiOiJvcGVuY29uZmlnLWFsYXJtLXR5cGVzOk1JTk9SIn0="
}
},
{
"path": {
"origin": "openconfig",
"elem": [
{
"name": "components"
},
{
"name": "component",
"key": {
"name": "OutletTempSensor1"
}
},
{
"name": "state"
},
{
"name": "temperature"
}
]
},
"val": {
"jsonIetfVal": "eyJpbnN0YW50IjoiNDQuMDAwMDAwIiwiYXZnIjoiMjkuMDAwMDAwIiwibWluIjoiMC4wMDAwMDAiLCJtYXgiOiI0NC4wMDAwMDAiLCJpbnRlcnZhbCI6IjE4MDAwMDAwMDAwMCIsImFsYXJtLXN0YXR1cyI6ZmFsc2UsImFsYXJtLXRocmVzaG9sZCI6MCwiYWxhcm0tc2V2ZXJpdHkiOiJvcGVuY29uZmlnLWFsYXJtLXR5cGVzOk1JTk9SIn0="
}
},
{
"path": {
"origin": "openconfig",
"elem": [
{
"name": "components"
},
{
"name": "component",
"key": {
"name": "HotSpotTempSensor1"
}
},
{
"name": "state"
},
{
"name": "temperature"
}
]
},
"val": {
"jsonIetfVal": "eyJpbnN0YW50IjoiNTguMDAwMDAwIiwiYXZnIjoiMzkuMDAwMDAwIiwibWluIjoiMC4wMDAwMDAiLCJtYXgiOiI1OS4wMDAwMDAiLCJpbnRlcnZhbCI6IjE4MDAwMDAwMDAwMCIsImFsYXJtLXN0YXR1cyI6ZmFsc2UsImFsYXJtLXRocmVzaG9sZCI6MCwiYWxhcm0tc2V2ZXJpdHkiOiJvcGVuY29uZmlnLWFsYXJtLXR5cGVzOk1JTk9SIn0="
}
}
]
}
}
]

View file

@ -0,0 +1,18 @@
[[inputs.gnmi]]
addresses = ["dummy"]
path_guessing_strategy = "subscription"
yang_model_paths = ["testcases/issue_15046/models"]
[[inputs.gnmi.subscription]]
name = "psu"
origin = "openconfig"
path = "/components/component/power-supply/state"
subscription_mode = "sample"
sample_interval = "60s"
[[inputs.gnmi.subscription]]
name = "temp"
origin = "openconfig"
path = "/components/component/state/temperature"
subscription_mode = "sample"
sample_interval = "60s"

View file

@ -0,0 +1 @@
event-stats,path=openconfig-system:/system/openconfig-events:event-stats/state,source=127.0.0.1 state/acked=0u,state/cleared=0u,state/events=4u,state/raised=0u 1718942414831832038

View file

@ -0,0 +1,70 @@
[
{
"update": {
"timestamp": "1718942414831832038",
"prefix": {
"elem": [
{
"name": "openconfig-system:system"
},
{
"name": "openconfig-events:event-stats"
},
{
"name": "state"
}
]
},
"update": [
{
"path": {
"elem": [
{
"name": "acked"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "cleared"
}
]
},
"val": {
"uintVal": "0"
}
},
{
"path": {
"elem": [
{
"name": "events"
}
]
},
"val": {
"uintVal": "4"
}
},
{
"path": {
"elem": [
{
"name": "raised"
}
]
},
"val": {
"uintVal": "0"
}
}
]
}
}
]

View file

@ -0,0 +1,10 @@
[[inputs.gnmi]]
addresses = ["dummy"]
prefix_tag_key_with_path = true
[[inputs.gnmi.subscription]]
name = "event-stats"
origin = "openconfig-system"
path = "/system/event-stats"
subscription_mode = "sample"
sample_interval = "10s"

View file

@ -0,0 +1 @@
ifcounters,path=Ciena:/oc-if:interfaces/oc-if:interface/oc-if:state/oc-if:counters,source=127.0.0.1 in_1024_to_1518_octet_pkts=15680405047u,in_128_to_255_octet_pkts=12809649942u,in_1519_to_2047_octet_pkts=35815850565u,in_2048_to_4095_octet_pkts=0u,in_256_to_511_octet_pkts=5257910993u,in_4096_to_9216_octet_pkts=0u,in_512_to_1023_octet_pkts=6139561818u,in_64_octet_pkts=4u,in_65_to_127_octet_pkts=146456592549u,in_broadcast_pkts=167166u,in_crc_error_pkts=0u,in_discards=236u,in_discards_octets=31492u,in_dropped_octets=31492u,in_dropped_pkts=236u,in_errors=0u,in_jabber_pkts=0u,in_multicast_pkts=76815719u,in_octets=95890972327359u,in_oversize_pkts=0u,in_pkts=222159970919u,in_undersize_pkts=0u,in_unicast_pkts=222082988034u,last_clear=1679547185677412529u,link_flap_events=0u,name="\"1\"",out_1519_to_2047_octet_pkts=211382493634u,out_2048_to_4095_octet_pkts=0u,out_4096_to_9216_octet_pkts=0u,out_broadcast_pkts=2609579674u,out_errors=0u,out_multicast_pkts=332069076u,out_octets=885293268981054u,out_pkts=677379680498u,out_unicast_pkts=674438031748u 1739206587847000000

View file

@ -0,0 +1,481 @@
[
{
"update": {
"timestamp": 1739206587847000000,
"prefix": {
"origin": "Ciena",
"elem": [
{
"name": "oc-if:interfaces"
},
{
"name": "oc-if:interface"
},
{
"name": "oc-if:state"
},
{
"name": "oc-if:counters"
}
]
},
"update": [
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-1024-to-1518-octet-pkts"
}
]
},
"val": {
"uintVal": 15680405047
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-128-to-255-octet-pkts"
}
]
},
"val": {
"uintVal": 12809649942
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-1519-to-2047-octet-pkts"
}
]
},
"val": {
"uintVal": 35815850565
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-2048-to-4095-octet-pkts"
}
]
},
"val": {
"uintVal": 0
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-256-to-511-octet-pkts"
}
]
},
"val": {
"uintVal": 5257910993
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-4096-to-9216-octet-pkts"
}
]
},
"val": {
"uintVal": 0
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-512-to-1023-octet-pkts"
}
]
},
"val": {
"uintVal": 6139561818
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-64-octet-pkts"
}
]
},
"val": {
"uintVal": 4
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-65-to-127-octet-pkts"
}
]
},
"val": {
"uintVal": 146456592549
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-broadcast-pkts"
}
]
},
"val": {
"uintVal": 167166
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-crc-error-pkts"
}
]
},
"val": {
"uintVal": 0
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-discards"
}
]
},
"val": {
"uintVal": 236
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-discards-octets"
}
]
},
"val": {
"uintVal": 31492
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-dropped-octets"
}
]
},
"val": {
"uintVal": 31492
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-dropped-pkts"
}
]
},
"val": {
"uintVal": 236
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-errors"
}
]
},
"val": {
"uintVal": 0
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-jabber-pkts"
}
]
},
"val": {
"uintVal": 0
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-multicast-pkts"
}
]
},
"val": {
"uintVal": 76815719
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-octets"
}
]
},
"val": {
"uintVal": 95890972327359
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-oversize-pkts"
}
]
},
"val": {
"uintVal": 0
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-pkts"
}
]
},
"val": {
"uintVal": 222159970919
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-undersize-pkts"
}
]
},
"val": {
"uintVal": 0
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "in-unicast-pkts"
}
]
},
"val": {
"uintVal": 222082988034
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "last-clear"
}
]
},
"val": {
"uintVal": 1679547185677412529
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "link-flap-events"
}
]
},
"val": {
"uintVal": 0
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "name"
}
]
},
"val": {
"stringVal": "\"1\""
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "out-1519-to-2047-octet-pkts"
}
]
},
"val": {
"uintVal": 211382493634
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "out-2048-to-4095-octet-pkts"
}
]
},
"val": {
"uintVal": 0
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "out-4096-to-9216-octet-pkts"
}
]
},
"val": {
"uintVal": 0
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "out-broadcast-pkts"
}
]
},
"val": {
"uintVal": 2609579674
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "out-errors"
}
]
},
"val": {
"uintVal": 0
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "out-multicast-pkts"
}
]
},
"val": {
"uintVal": 332069076
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "out-octets"
}
]
},
"val": {
"uintVal": 885293268981054
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "out-pkts"
}
]
},
"val": {
"uintVal": 677379680498
}
},
{
"path": {
"origin": "Ciena",
"elem": [
{
"name": "out-unicast-pkts"
}
]
},
"val": {
"uintVal": 674438031748
}
}
]
}
}
]

View file

@ -0,0 +1,10 @@
[[inputs.gnmi]]
addresses = ["dummy"]
enforce_first_namespace_as_origin = false
[[inputs.gnmi.subscription]]
name = "ifcounters"
origin = "Ciena"
path = "/oc-if:interfaces/oc-if:interface/oc-if:state/oc-if:counters"
subscription_mode = "sample"
sample_interval = "30s"

View file

@ -0,0 +1,11 @@
qmon,name=xe-0/0/0:0,path=/junos/system/linecard/qmon-sw,source=127.0.0.1 state/parent_ae_name="" 1739811071353000000
qmon,name=xe-0/0/0:0,path=/junos/system/linecard/qmon-sw,queue_number=0,source=127.0.0.1 egress/bytes=25084650213u,egress/packets=97812973u,egress/peak_buffer_occupancy_bytes=416u,egress/peak_buffer_occupancy_percent=0u,egress/red_drop_bytes_color_0=0u,egress/red_drop_bytes_color_1=0u,egress/red_drop_bytes_color_2=0u,egress/red_drop_bytes_color_3=0u,egress/red_drop_packets_color_0=0u,egress/red_drop_packets_color_1=0u,egress/red_drop_packets_color_2=0u,egress/red_drop_packets_color_3=0u,egress/tail_drop_bytes=0u,egress/tail_drop_packets=0u 1739811071353000000
qmon,name=xe-0/0/0:0,path=/junos/system/linecard/qmon-sw,queue_number=1,source=127.0.0.1 egress/bytes=0u,egress/packets=0u,egress/peak_buffer_occupancy_bytes=0u,egress/peak_buffer_occupancy_percent=0u,egress/red_drop_bytes_color_0=0u,egress/red_drop_bytes_color_1=0u,egress/red_drop_bytes_color_2=0u,egress/red_drop_bytes_color_3=0u,egress/red_drop_packets_color_0=0u,egress/red_drop_packets_color_1=0u,egress/red_drop_packets_color_2=0u,egress/red_drop_packets_color_3=0u,egress/tail_drop_bytes=0u,egress/tail_drop_packets=0u 1739811071353000000
qmon,name=xe-0/0/0:0,path=/junos/system/linecard/qmon-sw,queue_number=2,source=127.0.0.1 egress/bytes=10957969881u,egress/packets=105352268u,egress/peak_buffer_occupancy_bytes=208u,egress/peak_buffer_occupancy_percent=0u,egress/red_drop_bytes_color_0=0u,egress/red_drop_bytes_color_1=0u,egress/red_drop_bytes_color_2=0u,egress/red_drop_bytes_color_3=0u,egress/red_drop_packets_color_0=0u,egress/red_drop_packets_color_1=0u,egress/red_drop_packets_color_2=0u,egress/red_drop_packets_color_3=0u,egress/tail_drop_bytes=0u,egress/tail_drop_packets=0u 1739811071353000000
qmon,name=xe-0/0/0:0,path=/junos/system/linecard/qmon-sw,queue_number=3,source=127.0.0.1 egress/bytes=0u,egress/packets=0u,egress/peak_buffer_occupancy_bytes=0u,egress/peak_buffer_occupancy_percent=0u,egress/red_drop_bytes_color_0=0u,egress/red_drop_bytes_color_1=0u,egress/red_drop_bytes_color_2=0u,egress/red_drop_bytes_color_3=0u,egress/red_drop_packets_color_0=0u,egress/red_drop_packets_color_1=0u,egress/red_drop_packets_color_2=0u,egress/red_drop_packets_color_3=0u,egress/tail_drop_bytes=0u,egress/tail_drop_packets=0u 1739811071353000000
qmon,name=xe-0/0/0:0,path=/junos/system/linecard/qmon-sw,queue_number=4,source=127.0.0.1 egress/bytes=0u,egress/packets=0u,egress/peak_buffer_occupancy_bytes=0u,egress/peak_buffer_occupancy_percent=0u,egress/red_drop_bytes_color_0=0u,egress/red_drop_bytes_color_1=0u,egress/red_drop_bytes_color_2=0u,egress/red_drop_bytes_color_3=0u,egress/red_drop_packets_color_0=0u,egress/red_drop_packets_color_1=0u,egress/red_drop_packets_color_2=0u,egress/red_drop_packets_color_3=0u,egress/tail_drop_bytes=0u,egress/tail_drop_packets=0u 1739811071353000000
qmon,name=xe-0/0/0:0,path=/junos/system/linecard/qmon-sw,queue_number=5,source=127.0.0.1 egress/bytes=1020800306u,egress/packets=12027619u,egress/peak_buffer_occupancy_bytes=0u,egress/peak_buffer_occupancy_percent=0u,egress/red_drop_bytes_color_0=0u,egress/red_drop_bytes_color_1=0u,egress/red_drop_bytes_color_2=0u,egress/red_drop_bytes_color_3=0u,egress/red_drop_packets_color_0=0u,egress/red_drop_packets_color_1=0u,egress/red_drop_packets_color_2=0u,egress/red_drop_packets_color_3=0u,egress/tail_drop_bytes=0u,egress/tail_drop_packets=0u 1739811071353000000
qmon,name=xe-0/0/0:0,path=/junos/system/linecard/qmon-sw,queue_number=6,source=127.0.0.1 egress/bytes=1257881347u,egress/packets=4773346u,egress/peak_buffer_occupancy_bytes=624u,egress/peak_buffer_occupancy_percent=0u,egress/red_drop_bytes_color_0=0u,egress/red_drop_bytes_color_1=0u,egress/red_drop_bytes_color_2=0u,egress/red_drop_bytes_color_3=0u,egress/red_drop_packets_color_0=0u,egress/red_drop_packets_color_1=0u,egress/red_drop_packets_color_2=0u,egress/red_drop_packets_color_3=0u,egress/tail_drop_bytes=0u,egress/tail_drop_packets=0u 1739811071353000000
qmon,name=xe-0/0/0:0,path=/junos/system/linecard/qmon-sw,queue_number=7,source=127.0.0.1 egress/bytes=0u,egress/packets=0u,egress/peak_buffer_occupancy_bytes=0u,egress/peak_buffer_occupancy_percent=0u,egress/red_drop_bytes_color_0=0u,egress/red_drop_bytes_color_1=0u,egress/red_drop_bytes_color_2=0u,egress/red_drop_bytes_color_3=0u,egress/red_drop_packets_color_0=0u,egress/red_drop_packets_color_1=0u,egress/red_drop_packets_color_2=0u,egress/red_drop_packets_color_3=0u,egress/tail_drop_bytes=0u,egress/tail_drop_packets=0u 1739811071353000000
qmon,name=xe-0/0/0:0,path=/junos/system/linecard/qmon-sw,queue_number=8,source=127.0.0.1 egress/bytes=8898987190u,egress/packets=75415151u,egress/peak_buffer_occupancy_bytes=208u,egress/peak_buffer_occupancy_percent=0u,egress/red_drop_bytes_color_0=0u,egress/red_drop_bytes_color_1=0u,egress/red_drop_bytes_color_2=0u,egress/red_drop_bytes_color_3=0u,egress/red_drop_packets_color_0=0u,egress/red_drop_packets_color_1=0u,egress/red_drop_packets_color_2=0u,egress/red_drop_packets_color_3=0u,egress/tail_drop_bytes=0u,egress/tail_drop_packets=0u 1739811071353000000
qmon,name=xe-0/0/0:0,path=/junos/system/linecard/qmon-sw,queue_number=9,source=127.0.0.1 egress/bytes=16919364168u,egress/packets=157255632u,egress/peak_buffer_occupancy_bytes=208u,egress/peak_buffer_occupancy_percent=0u,egress/red_drop_bytes_color_0=0u,egress/red_drop_bytes_color_1=0u,egress/red_drop_bytes_color_2=0u,egress/red_drop_bytes_color_3=0u,egress/red_drop_packets_color_0=0u,egress/red_drop_packets_color_1=0u,egress/red_drop_packets_color_2=0u,egress/red_drop_packets_color_3=0u,egress/tail_drop_bytes=0u,egress/tail_drop_packets=0u 1739811071353000000

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,9 @@
[[inputs.gnmi]]
addresses = ["dummy"]
[[inputs.gnmi.subscription]]
name = "qmon"
origin = "openconfig"
path = "/junos/system/linecard/qmon-sw"
subscription_mode = "sample"
sample_interval = "60s"

View file

@ -0,0 +1,5 @@
interfaces_logical_status,descr/description=Loopback,index=0,name=lo0,path=/interfaces/interface/subinterfaces/subinterface,source=127.0.0.1 oper_status="UP" 1674081667238697959
interfaces_logical_status,descr/description=Local:Mgmt,index=312,name=irb,path=/interfaces/interface/subinterfaces/subinterface,source=127.0.0.1 oper_status="UP" 1674081667241404442
interfaces_logical_status,descr/description=Core:GRE:abc-def-dmn1-staging:{GRE_Tunnel},index=2,name=gr-0/0/0,path=/interfaces/interface/subinterfaces/subinterface,source=127.0.0.1 oper_status="UP" 1674081667243155079
interfaces_logical_status,descr/description=Core:PacketFabric:abc-def-dmn1-staging:{PF-BC-DAL-SFO-12345},index=1410,name=xe-0/1/1,path=/interfaces/interface/subinterfaces/subinterface,source=127.0.0.1 oper_status="UP" 1674081667250570407
interfaces_logical_status,descr/description=Core:PacketFabric:uvw-xyz-dmn1-staging:{PF-BC-CHI-SFO-67890},index=16386,name=xe-0/1/5,path=/interfaces/interface/subinterfaces/subinterface,source=127.0.0.1 oper_status="LOWER_LAYER_DOWN" 1674081667251795605

View file

@ -0,0 +1,13 @@
[
{"update":{"timestamp":"1674081667224189253", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"lo0"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"0"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"description"}]}, "val":{"stringVal":"Loopback"}}]}},
{"update":{"timestamp":"1674081667226968153", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"irb"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"312"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"description"}]}, "val":{"stringVal":"Local:Mgmt"}}]}},
{"update":{"timestamp":"1674081667228936729", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"gr-0/0/0"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"3"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"description"}]}, "val":{"stringVal":"Core:GRE:abc-def-dmn1-staging:{GRE_Tunnel}"}}]}},
{"update":{"timestamp":"1674081667236178737", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"xe-0/1/1"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"1410"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"description"}]}, "val":{"stringVal":"Core:PacketFabric:abc-def-dmn1-staging:{PF-BC-DAL-SFO-12345}"}}]}},
{"update":{"timestamp":"1674081667236377628", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"xe-0/1/5"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"1412"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"description"}]}, "val":{"stringVal":"Core:PacketFabric:uvw-xyz-dmn1-staging:{PF-BC-CHI-SFO-67890}"}}]}},
{"update":{"timestamp":"1674081667238697959", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"lo0"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"0"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"oper-status"}]}, "val":{"stringVal":"UP"}}]}},
{"update":{"timestamp":"1674081667241404442", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"irb"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"312"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"oper-status"}]}, "val":{"stringVal":"UP"}}]}},
{"update":{"timestamp":"1674081667243155079", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"gr-0/0/0"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"2"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"oper-status"}]}, "val":{"stringVal":"UP"}}]}},
{"update":{"timestamp":"1674081667250570407", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"xe-0/1/1"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"1410"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"oper-status"}]}, "val":{"stringVal":"UP"}}]}},
{"update":{"timestamp":"1674081667251795605", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"xe-0/1/5"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"16386"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"oper-status"}]}, "val":{"stringVal":"LOWER_LAYER_DOWN"}}]}},
{"syncResponse":true}
]

View file

@ -0,0 +1,15 @@
[[inputs.gnmi]]
addresses = ["dummy"]
redial = "10s"
[[inputs.gnmi.tag_subscription]]
name = "descr"
origin = "openconfig"
path = "/interfaces/interface/subinterfaces/subinterface/state/description"
subscription_mode = "on_change"
[[inputs.gnmi.subscription]]
name = "interfaces_logical_status"
origin = "openconfig"
path = "/interfaces/interface/subinterfaces/subinterface/state/oper-status"
subscription_mode = "on_change"

View file

@ -0,0 +1,5 @@
interfaces_logical_status,descr/description=Loopback,index=0,name=lo0,path=/interfaces/interface/subinterfaces/subinterface,source=127.0.0.1 oper_status="UP" 1674081667238697959
interfaces_logical_status,descr/description=Local:Mgmt,index=312,name=irb,path=/interfaces/interface/subinterfaces/subinterface,source=127.0.0.1 oper_status="UP" 1674081667241404442
interfaces_logical_status,descr/description=Core:GRE:abc-def-dmn1-staging:{GRE_Tunnel},index=2,name=gr-0/0/0,path=/interfaces/interface/subinterfaces/subinterface,source=127.0.0.1 oper_status="UP" 1674081667243155079
interfaces_logical_status,descr/description=Core:PacketFabric:abc-def-dmn1-staging:{PF-BC-DAL-SFO-12345},index=1410,name=xe-0/1/1,path=/interfaces/interface/subinterfaces/subinterface,source=127.0.0.1 oper_status="UP" 1674081667250570407
interfaces_logical_status,descr/description=Core:PacketFabric:uvw-xyz-dmn1-staging:{PF-BC-CHI-SFO-67890},index=16386,name=xe-0/1/5,path=/interfaces/interface/subinterfaces/subinterface,source=127.0.0.1 oper_status="LOWER_LAYER_DOWN" 1674081667251795605

View file

@ -0,0 +1,13 @@
[
{"update":{"timestamp":"1674081667224189253", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"lo0"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"0"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"description"}]}, "val":{"stringVal":"Loopback"}}]}},
{"update":{"timestamp":"1674081667226968153", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"irb"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"312"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"description"}]}, "val":{"stringVal":"Local:Mgmt"}}]}},
{"update":{"timestamp":"1674081667228936729", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"gr-0/0/0"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"3"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"description"}]}, "val":{"stringVal":"Core:GRE:abc-def-dmn1-staging:{GRE_Tunnel}"}}]}},
{"update":{"timestamp":"1674081667236178737", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"xe-0/1/1"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"1410"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"description"}]}, "val":{"stringVal":"Core:PacketFabric:abc-def-dmn1-staging:{PF-BC-DAL-SFO-12345}"}}]}},
{"update":{"timestamp":"1674081667236377628", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"xe-0/1/5"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"1412"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"description"}]}, "val":{"stringVal":"Core:PacketFabric:uvw-xyz-dmn1-staging:{PF-BC-CHI-SFO-67890}"}}]}},
{"update":{"timestamp":"1674081667238697959", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"lo0"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"0"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"oper-status"}]}, "val":{"stringVal":"UP"}}]}},
{"update":{"timestamp":"1674081667241404442", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"irb"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"312"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"oper-status"}]}, "val":{"stringVal":"UP"}}]}},
{"update":{"timestamp":"1674081667243155079", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"gr-0/0/0"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"2"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"oper-status"}]}, "val":{"stringVal":"UP"}}]}},
{"update":{"timestamp":"1674081667250570407", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"xe-0/1/1"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"1410"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"oper-status"}]}, "val":{"stringVal":"UP"}}]}},
{"update":{"timestamp":"1674081667251795605", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"xe-0/1/5"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"16386"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"oper-status"}]}, "val":{"stringVal":"LOWER_LAYER_DOWN"}}]}},
{"syncResponse":true}
]

View file

@ -0,0 +1,16 @@
[[inputs.gnmi]]
addresses = ["dummy"]
redial = "10s"
[[inputs.gnmi.subscription]]
name = "descr"
origin = "openconfig"
path = "/interfaces/interface/subinterfaces/subinterface/state/description"
subscription_mode = "on_change"
tag_only = true
[[inputs.gnmi.subscription]]
name = "interfaces_logical_status"
origin = "openconfig"
path = "/interfaces/interface/subinterfaces/subinterface/state/oper-status"
subscription_mode = "on_change"

View file

@ -0,0 +1,3 @@
interfaces_logical_status,descr/description=Core:PacketFabric:abc-def-dmn1-staging:{PF-BC-DAL-SFO-12345},index=1410,name=xe-0/1/1,path=/interfaces/interface/subinterfaces/subinterface,source=127.0.0.1 oper_status="UP" 1674081667250570407
interfaces_logical_status,descr/description=Core:PacketFabric:uvw-xyz-dmn1-staging:{PF-BC-CHI-SFO-67890},index=1412,name=xe-0/1/1,path=/interfaces/interface/subinterfaces/subinterface,source=127.0.0.1 oper_status="UP" 1674081667250784367
interfaces_logical_status,index=32767,name=xe-0/1/1,path=/interfaces/interface/subinterfaces/subinterface,source=127.0.0.1 oper_status="UP" 1674081667250994907

View file

@ -0,0 +1,9 @@
[
{"update":{"timestamp":"1674081667236178737", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"xe-0/1/1"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"1410"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"description"}]}, "val":{"stringVal":"Core:PacketFabric:abc-def-dmn1-staging:{PF-BC-DAL-SFO-12345}"}}]}},
{"update":{"timestamp":"1674081667236377628", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"xe-0/1/1"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"1412"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"description"}]}, "val":{"stringVal":"Core:PacketFabric:uvw-xyz-dmn1-staging:{PF-BC-CHI-SFO-67890}"}}]}},
{"update":{"timestamp":"1674081667236582084", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"xe-0/1/1"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"32767"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"description"}]}, "val":{"stringVal":""}}]}},
{"update":{"timestamp":"1674081667250570407", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"xe-0/1/1"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"1410"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"oper-status"}]}, "val":{"stringVal":"UP"}}]}},
{"update":{"timestamp":"1674081667250784367", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"xe-0/1/1"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"1412"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"oper-status"}]}, "val":{"stringVal":"UP"}}]}},
{"update":{"timestamp":"1674081667250994907", "prefix":{"elem":[{"name":"interfaces"}, {"name":"interface", "key":{"name":"xe-0/1/1"}}, {"name":"subinterfaces"}, {"name":"subinterface", "key":{"index":"32767"}}]}, "update":[{"path":{"elem":[{"name":"state"}, {"name":"oper-status"}]}, "val":{"stringVal":"UP"}}]}},
{"syncResponse":true}
]

View file

@ -0,0 +1,16 @@
[[inputs.gnmi]]
addresses = ["dummy"]
redial = "10s"
[[inputs.gnmi.tag_subscription]]
name = "descr"
origin = "openconfig"
path = "/interfaces/interface/subinterfaces/subinterface/state/description"
subscription_mode = "on_change"
elements = ["interface", "subinterface"]
[[inputs.gnmi.subscription]]
name = "interfaces_logical_status"
origin = "openconfig"
path = "/interfaces/interface/subinterfaces/subinterface/state/oper-status"
subscription_mode = "on_change"

View file

@ -0,0 +1,166 @@
package gnmi
import (
"encoding/json"
"fmt"
"strconv"
"strings"
"github.com/openconfig/gnmi/proto/gnmi"
"github.com/openconfig/gnmi/value"
)
type keyValuePair struct {
key []string
value interface{}
}
type updateField struct {
path *pathInfo
value interface{}
}
func (h *handler) newFieldsFromUpdate(path *pathInfo, update *gnmi.Update) ([]updateField, error) {
if update.Val == nil || update.Val.Value == nil {
return []updateField{{path: path}}, nil
}
// Apply some special handling for special types
switch v := update.Val.Value.(type) {
case *gnmi.TypedValue_AsciiVal: // not handled in ToScalar
return []updateField{{path, v.AsciiVal}}, nil
case *gnmi.TypedValue_JsonVal: // requires special path handling
return h.processJSON(path, v.JsonVal)
case *gnmi.TypedValue_JsonIetfVal: // requires special path handling
return h.processJSONIETF(path, v.JsonIetfVal)
}
// Convert the protobuf "oneof" data to a Golang type.
nativeType, err := value.ToScalar(update.Val)
if err != nil {
return nil, err
}
return []updateField{{path, nativeType}}, nil
}
func (h *handler) processJSON(path *pathInfo, data []byte) ([]updateField, error) {
var nested interface{}
if err := json.Unmarshal(data, &nested); err != nil {
return nil, fmt.Errorf("failed to parse JSON value: %w", err)
}
// Flatten the JSON data to get a key-value map
entries := flatten(nested)
// Create an update-field with the complete path for all entries
fields := make([]updateField, 0, len(entries))
for _, entry := range entries {
p := path.appendSegments(entry.key...)
if h.enforceFirstNamespaceAsOrigin {
p.enforceFirstNamespaceAsOrigin()
}
fields = append(fields, updateField{
path: p,
value: entry.value,
})
}
return fields, nil
}
func (h *handler) processJSONIETF(path *pathInfo, data []byte) ([]updateField, error) {
var nested interface{}
if err := json.Unmarshal(data, &nested); err != nil {
return nil, fmt.Errorf("failed to parse JSON value: %w", err)
}
// Flatten the JSON data to get a key-value map
entries := flatten(nested)
// Lookup the data in the YANG model if any
if h.decoder != nil {
for i, e := range entries {
var namespace, identifier string
for _, k := range e.key {
if n, _, found := strings.Cut(k, ":"); found {
namespace = n
}
}
// IETF nodes referencing YANG entries require a namespace
if namespace == "" {
continue
}
if a, b, found := strings.Cut(e.key[len(e.key)-1], ":"); !found {
identifier = a
} else {
identifier = b
}
if decoded, err := h.decoder.DecodeLeafElement(namespace, identifier, e.value); err != nil {
h.log.Debugf("Decoding %s:%s failed: %v", namespace, identifier, err)
} else {
entries[i].value = decoded
}
}
}
fields := make([]updateField, 0, len(entries))
for _, entry := range entries {
p := path.appendSegments(entry.key...)
if h.enforceFirstNamespaceAsOrigin {
p.enforceFirstNamespaceAsOrigin()
}
// Try to lookup the full path to decode the field according to the
// YANG model if any
if h.decoder != nil {
origin, fieldPath := p.path()
if decoded, err := h.decoder.DecodePathElement(origin, fieldPath, entry.value); err != nil {
h.log.Debugf("Decoding %s failed: %v", p, err)
} else {
entry.value = decoded
}
}
// Create an update-field with the complete path for all entries
fields = append(fields, updateField{
path: p,
value: entry.value,
})
}
return fields, nil
}
func flatten(nested interface{}) []keyValuePair {
var values []keyValuePair
switch n := nested.(type) {
case map[string]interface{}:
for k, child := range n {
for _, c := range flatten(child) {
values = append(values, keyValuePair{
key: append([]string{k}, c.key...),
value: c.value,
})
}
}
case []interface{}:
for i, child := range n {
k := strconv.Itoa(i)
for _, c := range flatten(child) {
values = append(values, keyValuePair{
key: append([]string{k}, c.key...),
value: c.value,
})
}
}
default:
values = append(values, keyValuePair{value: n})
}
return values
}