Skip to content

Commit

Permalink
GROUNDWORK-3736 extend SNMP NonMibMetrics
Browse files Browse the repository at this point in the history
  • Loading branch information
Pavlo Sumkin committed Nov 28, 2024
1 parent 2b3e108 commit 44ebc31
Showing 1 changed file with 65 additions and 78 deletions.
143 changes: 65 additions & 78 deletions connectors/snmp/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type InterfaceMetric struct {
Key string
Mib string
Value int64
ts int64
}

func (state *MonitoringState) Init() {
Expand Down Expand Up @@ -79,56 +80,73 @@ func (device *DeviceExt) retrieveMonitoredServices(metricDefinitions map[string]
}

timestamp := transit.NewTimestamp()
ts := timestamp.Unix()
for _, iFace := range device.Interfaces {
var bytesInPrev, bytesOutPrev, bytesInX64Prev, bytesOutX64Prev int64 = -1, -1, -1, -1
if val, ok := previousValueCache.Get(fmt.Sprintf("%s:%s:%s", device.Name, iFace.Name, clients.IfInOctets)); ok {
bytesInPrev = val.(int64)
}
if val, ok := previousValueCache.Get(fmt.Sprintf("%s:%s:%s", device.Name, iFace.Name, clients.IfOutOctets)); ok {
bytesOutPrev = val.(int64)
}
if val, ok := previousValueCache.Get(fmt.Sprintf("%s:%s:%s", device.Name, iFace.Name, clients.IfHCInOctets)); ok {
bytesInX64Prev = val.(int64)
}
if val, ok := previousValueCache.Get(fmt.Sprintf("%s:%s:%s", device.Name, iFace.Name, clients.IfHCOutOctets)); ok {
bytesOutX64Prev = val.(int64)
}

var metricsBuilder []connectors.MetricBuilder
for mib, metric := range iFace.Metrics {
if metricDefinition, has := metricDefinitions[metric.Mib]; has {
unitType := transit.UnitCounter

metricBuilder := connectors.MetricBuilder{
Name: metric.Key,
CustomName: metricDefinition.CustomName,
ComputeType: metricDefinition.ComputeType,
Expression: metricDefinition.Expression,
UnitType: unitType,
Warning: metricDefinition.WarningThreshold,
Critical: metricDefinition.CriticalThreshold,
StartTimestamp: timestamp,
EndTimestamp: timestamp,
Graphed: metricDefinition.Graphed,

Value: nil,
}

ck := fmt.Sprintf("%s:%s:%s", device.Name, iFace.Name, mib)
isDelta, isPreviousPresent, valueToSet := calculateValue(metricDefinition.MetricType, unitType,
ck, metric.Value)
for key := range clients.NonMibMetrics {
if metricDefinition, has := metricDefinitions[key]; has {
metricBuilder := makeMetricBuilder(metricDefinition, key, timestamp)

switch key {
case clients.BytesPerSecondIn:
if prev, ok := previousValueCache.Get(makeCK(device.Name, iFace.Name, clients.IfInOctets)); ok {
v := (iFace.Metrics[clients.IfInOctets].Value - prev.(InterfaceMetric).Value) / (ts - prev.(InterfaceMetric).ts)
metricBuilder.Value = v
metricsBuilder = append(metricsBuilder, metricBuilder)
metricBuilder.Name = "bitsPerSecondIn"
metricBuilder.Value = v * 8
metricsBuilder = append(metricsBuilder, metricBuilder)
}
if prev, ok := previousValueCache.Get(makeCK(device.Name, iFace.Name, clients.IfHCInOctets)); ok {
v := (iFace.Metrics[clients.IfHCInOctets].Value - prev.(InterfaceMetric).Value) / (ts - prev.(InterfaceMetric).ts)
metricBuilder.Name = "bytesPerSecondHCIn"
metricBuilder.Value = v
metricsBuilder = append(metricsBuilder, metricBuilder)
metricBuilder.Name = "bitsPerSecondHCIn"
metricBuilder.Value = v * 8
metricsBuilder = append(metricsBuilder, metricBuilder)
}

switch mib {
case clients.IfInOctets, clients.IfOutOctets, clients.IfHCInOctets, clients.IfHCOutOctets:
valueToSet = valueToSet * 8
case clients.BytesPerSecondOut:
if prev, ok := previousValueCache.Get(makeCK(device.Name, iFace.Name, clients.IfOutOctets)); ok {
v := (iFace.Metrics[clients.IfOutOctets].Value - prev.(InterfaceMetric).Value) / (ts - prev.(InterfaceMetric).ts)
metricBuilder.Value = v
metricsBuilder = append(metricsBuilder, metricBuilder)
metricBuilder.Name = "bitsPerSecondOut"
metricBuilder.Value = v * 8
metricsBuilder = append(metricsBuilder, metricBuilder)
}
if prev, ok := previousValueCache.Get(makeCK(device.Name, iFace.Name, clients.IfHCOutOctets)); ok {
v := (iFace.Metrics[clients.IfHCOutOctets].Value - prev.(InterfaceMetric).Value) / (ts - prev.(InterfaceMetric).ts)
metricBuilder.Name = "bytesPerSecondHCOut"
metricBuilder.Value = v
metricsBuilder = append(metricsBuilder, metricBuilder)
metricBuilder.Name = "bitsPerSecondHCOut"
metricBuilder.Value = v * 8
metricsBuilder = append(metricsBuilder, metricBuilder)
}
}
}
}

if !isDelta || (isDelta && isPreviousPresent) {
metricBuilder.Value = valueToSet
for mib, metric := range iFace.Metrics {
if metricDefinition, has := metricDefinitions[metric.Mib]; has {
metricBuilder := makeMetricBuilder(metricDefinition, metric.Key, timestamp)

ck := makeCK(device.Name, iFace.Name, mib)
if isDelta(metricDefinition.MetricType) {
if prev, ok := previousValueCache.Get(ck); ok {
metricBuilder.Value = metric.Value - prev.(InterfaceMetric).Value
metricsBuilder = append(metricsBuilder, metricBuilder)
}
} else {
metricBuilder.Value = metric.Value
metricsBuilder = append(metricsBuilder, metricBuilder)
}

previousValueCache.SetDefault(ck, metric.Value)
metric.ts = ts
previousValueCache.SetDefault(ck, metric)

// log.Debug().
// Interface("_ck", ck).
Expand All @@ -140,21 +158,6 @@ func (device *DeviceExt) retrieveMonitoredServices(metricDefinitions map[string]
}
}

for key := range clients.NonMibMetrics {
if metricDefinition, has := metricDefinitions[key]; has {
switch key {
case clients.BytesPerSecondIn:
metricBuilder := calculateBytesPerSecond(key, metricDefinition,
iFace.Metrics[clients.IfInOctets].Value*8, iFace.Metrics[clients.IfHCInOctets].Value*8, bytesInPrev, bytesInX64Prev, timestamp)
metricsBuilder = append(metricsBuilder, metricBuilder)
case clients.BytesPerSecondOut:
metricBuilder := calculateBytesPerSecond(key, metricDefinition,
iFace.Metrics[clients.IfOutOctets].Value*8, iFace.Metrics[clients.IfHCOutOctets].Value*8, bytesOutPrev, bytesOutX64Prev, timestamp)
metricsBuilder = append(metricsBuilder, metricBuilder)
}
}
}

mService, err := connectors.BuildServiceForMetrics(iFace.Name, device.Name, metricsBuilder)
if err != nil {
log.Err(err).Msgf("could not create monitored service '%s:%s'", device.Name, iFace.Name)
Expand Down Expand Up @@ -191,29 +194,15 @@ func calculateHostStatus(lastOk float64) transit.MonitorStatus {
return transit.HostUnreachable
}

func calculateValue(metricKind transit.MetricKind, unitType transit.UnitType,
ck string, currentValue int64) (bool, bool, int64) {
if strings.EqualFold(string(metricKind), string(transit.Delta)) {
if previousValue, present := previousValueCache.Get(ck); present {
switch unitType {
case transit.UnitCounter:
currentValue = currentValue - previousValue.(int64)
}
return true, true, currentValue
}
return true, false, currentValue
}
return false, false, currentValue
func isDelta(k transit.MetricKind) bool {
return strings.EqualFold(string(k), string(transit.Delta))
}

func calculateBytesPerSecond(metricName string, metricDefinition transit.MetricDefinition, current, currentX64, previous,
previousX64 int64, timestamp *transit.Timestamp) connectors.MetricBuilder {
seconds := int(connectors.CheckInterval.Seconds())
result := (current - previous) / int64(seconds)
if currentX64 > 0 && previousX64 > 0 {
result = (currentX64 - previousX64) / int64(seconds)
}
func makeCK(deviceName, iFaceName, mib string) string {
return fmt.Sprintf("%s:%s:%s", deviceName, iFaceName, mib)
}

func makeMetricBuilder(metricDefinition transit.MetricDefinition, metricName string, timestamp *transit.Timestamp) connectors.MetricBuilder {
return connectors.MetricBuilder{
Name: metricName,
CustomName: metricDefinition.CustomName,
Expand All @@ -225,7 +214,5 @@ func calculateBytesPerSecond(metricName string, metricDefinition transit.MetricD
StartTimestamp: timestamp,
EndTimestamp: timestamp,
Graphed: metricDefinition.Graphed,

Value: result,
}
}

0 comments on commit 44ebc31

Please sign in to comment.