Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/ocprometheus: Allow decoding enumerated values #65

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions cmd/ocprometheus/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

This is a client for the OpenConfig gRPC interface that pushes telemetry to
Prometheus. Numerical and boolean (converted to 1 for true and 0 for false) are
supported. Non-numerical data isn't supported by Prometheus and is silently
dropped. Arrays (even with numeric values) are not yet supported.
supported. String values can be inserted as a label using the `valuelabel` option
with the numeric value of the metric specified using the `defaultvalue` option.
For enumerated string values, the option `decodeenum` can be used to transform
each string value into a numeric value. Other non-numerical data isn't supported
by Prometheus and is silently dropped. Arrays (even with numeric values) are not
yet supported.

This tool requires a config file to specify how to map the path of the
notificatons coming out of the OpenConfig gRPC interface onto Prometheus
Expand Down
29 changes: 28 additions & 1 deletion cmd/ocprometheus/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type labelledMetric struct {
labels []string
defaultValue float64
stringMetric bool
decodeEnum map[string]float64
}

type collector struct {
Expand Down Expand Up @@ -113,6 +114,18 @@ func (c *collector) update(addr string, message proto.Message) {
c.m.Lock()
// Use the cached labels and descriptor if available
if m, ok := c.metrics[src]; ok {
if m.decodeEnum != nil {
// decode the string value according to the enum lookup
decodedVal, enumExists := m.decodeEnum[strVal]
if enumExists {
strUpdate = false
floatVal = decodedVal
} else {
glog.V(8).Infof("Failed to decode enum value %+v of update %v at %s:%s",
value, update, device, path)
}
}

if strUpdate {
// Skip string updates for non string metrics
if !m.stringMetric {
Expand All @@ -139,7 +152,20 @@ func (c *collector) update(addr string, message proto.Message) {
continue
}

if metric.stringMetric {
enumDecoded := false
if metric.decodeEnum != nil {
// Decode the string value according to the enum lookup
decodedVal, enumExists := metric.decodeEnum[strVal]
if enumExists {
floatVal = decodedVal
enumDecoded = true
} else {
glog.V(8).Infof("Failed to decode enum value %+v of update %v at %s:%s",
value, update, device, path)
}
}

if metric.stringMetric && !enumDecoded {
if !strUpdate {
// A float was parsed from the update, yet metric expects a string.
// Store the float as a string.
Expand All @@ -159,6 +185,7 @@ func (c *collector) update(addr string, message proto.Message) {
labels: metric.labels,
defaultValue: metric.defaultValue,
stringMetric: metric.stringMetric,
decodeEnum: metric.decodeEnum,
}
c.m.Unlock()
}
Expand Down
6 changes: 5 additions & 1 deletion cmd/ocprometheus/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ type MetricDef struct {
// Label to store string values
ValueLabel string

// Map decoding enumeration values to numeric values
DecodeEnum map[string]float64

// Default value to display for string values
DefaultValue float64

Expand All @@ -67,6 +70,7 @@ type metricValues struct {
labels []string
defaultValue float64
stringMetric bool
decodeEnum map[string]float64
}

// Parses the config and creates the descriptors for each path and device.
Expand Down Expand Up @@ -128,7 +132,7 @@ func (c *Config) getMetricValues(s source) *metricValues {
desc = def.desc
}
return &metricValues{desc: desc, labels: groups[1:], defaultValue: def.DefaultValue,
stringMetric: def.stringMetric}
stringMetric: def.stringMetric, decodeEnum: def.DecodeEnum}
}
}

Expand Down
139 changes: 139 additions & 0 deletions cmd/ocprometheus/sample_configs/enum_decoding-7280.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# Per-device labels. Optional
# Exactly the same set of labels must be specified for each device.
# If device address is *, the labels apply to all devices not listed explicitly.
# If any explicit device if listed below, then you need to specify all devices you're subscribed to,
# or have a wildcard entry. Otherwise, updates from non-listed devices will be ignored.
#deviceLabels:
# 10.1.1.1:
# lab1: val1
# lab2: val2
# '*':
# lab1: val3
# lab2: val4

# Subscriptions to OpenConfig paths.
subscriptions:
- eos_native:/Smash/counters/ethIntf
- eos_native:/Smash/interface/counter/lag/current/counter
- eos_native:/Sysdb/environment/archer/cooling/status
- eos_native:/Sysdb/environment/archer/power/status
- eos_native:/Sysdb/environment/archer/temperature/status
- eos_native:/Sysdb/hardware/archer/xcvr/status
- eos_native:/Sysdb/interface/config/eth
- eos_native:/Kernel/proc
- eos_native:/Sysdb/connectivityMonitor
- /interfaces/interface

# Prometheus metrics configuration.
# If you use named capture groups in the path, they will be extracted into labels with the same name.
# All fields are mandatory.
metrics:
- name: interfaceDescription
path: /Sysdb/interface/config/eth/phy/slice/1/intfConfig/(?P<interface>Ethernet.+)/description
help: Description
valuelabel: description
defaultvalue: 15
- name: intfCounter
path: /Smash/counters/ethIntf/SandCounters/current/(counter)/(?P<intf>.+)/statistics/(?P<direction>(?:in|out))(?P<type>(?:Octets|Errors|Discards))
help: Per-Interface Bytes/Errors/Discards Counters
- name: intfLagCounter
path: /Smash/interface/counter/lag/current/(counter)/(?P<intf>.+)/statistics/(?P<direction>(?:in|out))(Octets|Errors|Discards)
help: Per-Lag Bytes/Errors/Discards Counters
- name: intfPktCounter
path: /Smash/counters/ethIntf/SandCounters/current/counter/(?P<intf>.+)/statistics/(?P<direction>(?:in|out))(?P<type>(?:Ucast|Multicast|Broadcast))Pkt
help: Per-Interface Unicast/Multicast/Broadcast Packer Counters
- name: intfLagPktCounter
path: /Smash/interface/counter/lag/current/(counter)/(?P<intf>.+)/statistics/(?P<direction>(?:in|out))(?P<type>(?:Ucast|Multicast|Broadcast))(Pkt)
help: Per-Lag Unicast/Multicast/Broadcast Packer Counters
- name: intfPfcClassCounter
path: /Smash/counters/ethIntf/SandCounters/current/(counter)/(?P<intf>.+)/ethStatistics/(?P<direction>(?:in|out))(PfcClassFrames)
help: Per-Interface Input/Output PFC Frames Counters
- name: tempSensor
path: /Sysdb/environment/archer/temperature/status/(?P<sensor>.+)/((?:maxT|t)emperature)/value
help: Temperature and Maximum Temperature
- name: tempSensorAlert
path: /Sysdb/environment/archer/temperature/status/(?P<sensor>.+)/(alertRaisedCount)
help: Temperature Alerts Counter
- name: currentSensor
path: /Sysdb/environment/archer/power/status/currentSensor/(?P<sensor>.+)/(current)
help: Current Levels
- name: powerSensor
path: /Sysdb/environment/archer/power/status/powerSupply/(?P<sensor>.+)/(?P<pwrdir>(?:input|output))Power
help: Input/Output Power Levels
- name: voltageSensor
path: /Sysdb/environment/archer/power/status/voltageSensor/(?:cell/.+|system)/(?P<sensor>VoltageSensor.+)/(voltage)/value
help: Voltage Levels
- name: railCurrentSensor
path: /Sysdb/environment/archer/power/status/voltageSensor/(?:cell/.+|system)/(?P<sensor>VoltageSensor.+)/(current)/value
help: Rail Current Levels
- name: fanSpeed
path: /Sysdb/environment/archer/(cooling)/status/(?P<fan>.+)/speed/value
help: Fan Speed
- name: qsfpModularRxPower
path: /Sysdb/hardware/archer/(xcvr)/status/slice/(?P<linecard>.+)/(?P<intf>.+)/domRegisterData/lane(?P<lane>\d)(OpticalRxPower)
help: qsfpModularRxPower
- name: qsfpFixedRxPower
path: /Sysdb/hardware/archer/(xcvr)/status/all/(?P<intf>.+)/domRegisterData/lane(?P<lane>\d)(OpticalRxPower)
help: qsfpFixedRxPower
- name: qsfpModularTxPower
path: /Sysdb/hardware/archer/(xcvr)/status/slice/(?P<linecard>.+)/(?P<intf>.+)/domRegisterData/lane(?P<lane>\d)(OpticalTxPower)
help: qsfpModularTxPower
- name: qsfpFixedTxPower
path: /Sysdb/hardware/archer/(xcvr)/status/all/(?P<intf>.+)/domRegisterData/lane(?P<lane>\d)(OpticalTxPower)
help: qsfpFixedTxPower
- name: sfpModularTemperature
path: /Sysdb/hardware/archer/(xcvr)/status/slice/(?P<linecard>.+)/(?P<intf>.+)/lastDomUpdateTime/(temperature)
help: sfpModularTemperature
- name: sfpFixedTemperature
path: /Sysdb/hardware/archer/(xcvr)/status/all/(?P<intf>.+)/lastDomUpdateTime/(temperature)
help: sfpFixedTemperature
- name: sfpFixedRxTxPower
path: /Sysdb/hardware/archer/xcvr/status/all/(?P<intf>.+)/lastDomUpdateTime/(?P<powerdirection>(?:rx|tx))(Power)
help: sfpFixedRxTxPower
- name: kernelprocrss
path: /Kernel/proc/stat/(?P<pid>.+)/rss
help: KernelProcRSS
- name: kernelproc
path: /Kernel/proc/stat/(?P<pid>.+)/comm
help: KernelProcStat
valuelabel: command
defaultvalue: 1
- name: memoryinfo
path: /Kernel/proc/meminfo/(?P<usageType>(?:memAvailable|memFree|memTotal|buffers|cached))
help: memory info
- name: cputotal
path: /Kernel/proc/cpu/utilization/total/(?P<usageType>(?:idle|nice|system|user|util))
help: CPUtotal
- name: connectivityMonitor
path: /Sysdb/connectivityMonitor/status/hostStatus/(?P<originhost>.+)/defaultStats/(?P<traceType>(?:jitter|latency|packetLoss|httpResponseTime))
- name: inputBinCtr
path: /Smash/counters/ethIntf/SandCounters/current/(counter)/(?P<intf>.+)/ethStatistics/(?P<type>(?:in1024To1522OctetFrames|in128To255OctetFrames|in256To511OctetFrames|in512To1023OctetFrames|in64OctetFrames|in65To127OctetFrames))
- name: interfaceLinkStatus
path: /Sysdb/interface/status/eth/phy/slice/1/intfStatus/(?P<intf>.+)/linkStatus$
help: LinkStatus
valuelabel: linkStatus
defaultvalue: 4
- name: interfaceOperStatus
path: /Sysdb/interface/status/eth/phy/slice/1/intfStatus/(?P<intr>.+)/operStatus$
help: OperStatus
valuelabel: operStatus
defaultvalue: 2
- name: interfaceSpeed
path: /interfaces/interface\[name=(?P<intf>[^\]]+)\]/ethernet/state/port-speed
decodeenum:
# G M K
"openconfig-if-ethernet:SPEED_10MB": 10000000
"openconfig-if-ethernet:SPEED_100MB": 100000000
"openconfig-if-ethernet:SPEED_1GB": 1000000000
"openconfig-if-ethernet:SPEED_2500MB": 2500000000
"openconfig-if-ethernet:SPEED_5GB": 5000000000
"openconfig-if-ethernet:SPEED_10GB": 10000000000
"openconfig-if-ethernet:SPEED_25GB": 25000000000
"openconfig-if-ethernet:SPEED_40GB": 40000000000
"openconfig-if-ethernet:SPEED_50GB": 50000000000
"openconfig-if-ethernet:SPEED_100GB": 100000000000
"openconfig-if-ethernet:SPEED_200GB": 200000000000
"openconfig-if-ethernet:SPEED_400GB": 400000000000
"openconfig-if-ethernet:SPEED_600GB": 600000000000
"openconfig-if-ethernet:SPEED_800GB": 800000000000
"openconfig-if-ethernet:SPEED_UNKNOWN": 0