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

GROUNDWORK-3736 Threshold on MRTG graph #366

Closed
wants to merge 4 commits into from
Closed
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
86 changes: 39 additions & 47 deletions connectors/snmp/clients/nediClient.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ type Device struct {
Name string
IP string
Community string
LastOK float64
LastOK int64
}

type Monitoring struct {
Name string
IP string
Device string
LastOK float64
LastOK int64
}

type Interface struct {
Expand Down Expand Up @@ -75,19 +75,18 @@ func (client *NediClient) GetDevices() ([]Device, error) {

path, err := client.getConnectionString(tableDevices, "", "")
if err != nil {
log.Err(err).Msg("could not get NeDi connection string")
return nil, errors.New("failed to get NeDi connection string")
msg := "could not get NeDi connection string"
log.Err(err).Msg(msg)
return nil, errors.New(msg)
}

log.Debug().Msgf("performing NeDi Get Devices request: %s", *path)
r, err := executeGet(*path)
if err != nil {
log.Err(err).
Str("request", *path).
Msg("could not execute NeDi request")
return nil, errors.New("failed to execute NeDi request")
msg := "could not execute NeDi request"
log.Err(err).Str("request", *path).Msg(msg)
return nil, errors.New(msg)
}
log.Debug().Bytes("response", r).Msg("NeDi Get Devices response")
log.Debug().Str("request", *path).Bytes("response", r).Msg("NeDi Get Devices")

return parseDevices(r, monitored)
}
Expand All @@ -100,19 +99,18 @@ func (client *NediClient) GetDeviceInterfaces(device string) ([]Interface, error
query := colDevice + " = " + device
path, err := client.getConnectionString(tableInterfaces, query, "")
if err != nil {
log.Err(err).Msg("could not get NeDi connection string")
return nil, errors.New("failed to get NeDi connection string")
msg := "could not get NeDi connection string"
log.Err(err).Msg(msg)
return nil, errors.New(msg)
}

log.Debug().Msgf("performing NeDi Get Interfaces request: %s", *path)
r, err := executeGet(*path)
if err != nil {
log.Err(err).
Str("request", *path).
Msg("could not execute NeDi request")
return nil, errors.New("failed to execute NeDi request")
msg := "could not execute NeDi request"
log.Err(err).Str("request", *path).Msg(msg)
return nil, errors.New(msg)
}
log.Debug().Bytes("response", r).Msg("NeDi Get Interfaces response")
log.Debug().Str("request", *path).Bytes("response", r).Msg("NeDi Get Interfaces")

return parseInterfaces(r), nil
}
Expand Down Expand Up @@ -149,7 +147,7 @@ func parseDevices(bytes []byte, monitored map[string]Monitoring) ([]Device, erro
case string:
device.Name = name
default:
log.Warn().Msgf("skipping device '%s:%v' of unsupported type %T",
log.Warn().Msgf("skipping device by name '%s:%v' of unsupported type %T",
colDevice, name, name)
continue
}
Expand All @@ -162,7 +160,7 @@ func parseDevices(bytes []byte, monitored map[string]Monitoring) ([]Device, erro

ipVal, err := getInt(ip)
if err != nil {
log.Warn().Msgf("skipping device '%s:%s:%v' of unsupported type %T",
log.Warn().Msgf("skipping device by ip '%s:%s:%v' of unsupported type %T",
device.Name, colDevIP, ip, ip)
continue
}
Expand All @@ -172,7 +170,7 @@ func parseDevices(bytes []byte, monitored map[string]Monitoring) ([]Device, erro
case string:
device.Community = community
default:
log.Warn().Msgf("skipping device '%s:%s:%v' of unsupported type %T",
log.Warn().Msgf("skipping device by community '%s:%s:%v' of unsupported type %T",
device.Name, colReadComm, community, community)
continue
}
Expand All @@ -196,7 +194,7 @@ func parseInterfaces(response []byte) []Interface {
case string:
iFace.Name = name
default:
log.Warn().Msgf("skipping interface '%s:%v' of unsupported type %T",
log.Warn().Msgf("skipping interface by name '%s:%v' of unsupported type %T",
colIfName, name, name)
continue
}
Expand All @@ -205,7 +203,7 @@ func parseInterfaces(response []byte) []Interface {
case string:
iFace.Device = device
default:
log.Warn().Msgf("skipping interface '%s:%s:%v' of unsupported type %T",
log.Warn().Msgf("skipping interface by device '%s:%s:%v' of unsupported type %T",
iFace.Name, colDevice, device, device)
continue
}
Expand All @@ -214,13 +212,13 @@ func parseInterfaces(response []byte) []Interface {
if statVal, err := getInt(status); err == nil {
iFace.Status = statVal
} else {
log.Warn().Msgf("skipping interface '%s:%s:%v' of unsupported type %T",
log.Warn().Msgf("skipping interface by status '%s:%s:%v' of unsupported type %T",
iFace.Name, colIfStat, status, status)
}

idxVal, err := getInt(index)
if err != nil {
log.Warn().Msgf("skipping interface '%s:%s:%v' of unsupported type %T",
log.Warn().Msgf("skipping interface by index '%s:%s:%v' of unsupported type %T",
iFace.Name, colIfIndex, index, index)
continue
}
Expand All @@ -232,46 +230,41 @@ func parseInterfaces(response []byte) []Interface {
}

func parseResponse(bytes []byte) []map[string]interface{} {
log.Debug().
Bytes("response", bytes).
Msg("parsing NeDi response")

var response []interface{}
if err := json.Unmarshal(bytes, &response); err != nil {
log.Err(err).Bytes("response", bytes).Msg("could not parse NeDi response")
return nil
}

var res []map[string]interface{}
dbg := log.Debug().Bytes("response", bytes)
res := make([]map[string]interface{}, 0, len(response)-1)
skip := 0
for i, r := range response {
log.Debug().
Interface("obj", r).
Msg("parsing NeDi response object")
if i == 0 {
log.Debug().Msg("skipping system information")
// log.Debug().Msg("skipping system information")
continue
}
switch r := r.(type) {
case map[string]interface{}:
res = append(res, r)
default:
log.Warn().
Interface("obj", r).
Msgf("skipping response object of unsupported type %T", r)
skip++
continue
}
}
log.Debug().
Interface("res", res).
Msg("parsing NeDi response completed")
if skip > 0 {
dbg.Int("skipped parts of unsupported type", skip)
}
dbg.Interface("res", res).
Msg("parsing NeDi response")

return res
}

func executeGet(url string) ([]byte, error) {
s, r, err := clients.SendRequest(http.MethodGet, url, nil, nil, nil)
if err != nil || s != 200 || r == nil {
log.Error().
Err(err).
log.Err(err).
Int("status", s).
Bytes("response", r).
Msg("could not send request")
Expand Down Expand Up @@ -312,26 +305,25 @@ func int2ip(val int) string {
func (client *NediClient) getMonitoredDevices() (map[string]Monitoring, error) {
path, err := client.getConnectionString(tableMonitoring, "", "")
if err != nil {
msg := "failed to get NeDi monitoring connection string"
msg := "could not get NeDi monitoring connection string"
log.Err(err).Msg(msg)
return nil, errors.New(msg)
}

log.Debug().Msgf("performing NeDi Get Monitoring request: %s", *path)
response, err := executeGet(*path)
if err != nil {
msg := "could not execute NeDi monitoring request"
log.Err(err).Msg(msg)
log.Err(err).Str("request", *path).Msg(msg)
return nil, errors.New(msg)
}
log.Debug().Bytes("response", response).Msg("NeDi Get Monitoring response")
log.Debug().Str("request", *path).Bytes("response", response).Msg("NeDi Get Monitoring response")

monitors := make(map[string]Monitoring)
for _, fields := range parseResponse(response) {
var monitor Monitoring
monitor.Name = fields[colName].(string)
monitor.Device = fields[colDevice].(string)
monitor.LastOK = fields[colLastOK].(float64)
monitor.LastOK = int64(fields[colLastOK].(float64))

ip := fields[colMonIP]
ipVal, err := getInt(ip)
Expand Down
43 changes: 19 additions & 24 deletions connectors/snmp/clients/snmpClient.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package clients

import (
"errors"
"fmt"
"strings"
"time"

Expand Down Expand Up @@ -107,27 +108,26 @@ func (client *SnmpClient) GetSnmpData(mibs []string, target string, secData *uti
return nil, errors.New("no metrics (mibs) provided")
}

log.Info().Msgf("------ starting SNMP metric gathering for target '%s'", target)
log.Debug().Msgf("------ starting SNMP metric gathering for target '%s'", target)
goSnmp, err := setup(target, secData)
if err != nil {
log.Err(err).Msg("SNMP setup failed")
return nil, errors.New("SNMP setup failed")
return nil, fmt.Errorf("SNMP setup failed: %w", err)
}

err = goSnmp.Connect()
if err != nil {
if err := goSnmp.Connect(); err != nil {
log.Err(err).Msg("SNMP connect failed")
return nil, errors.New("SNMP connect failed")
return nil, fmt.Errorf("SNMP connect failed: %w", err)
}
defer goSnmp.Conn.Close()

var data []SnmpMetricData
for _, mib := range mibs {
mibData, e := getSnmpData(mib, goSnmp) // go get the snmp
if e != nil {
// reconnect in case of error
goSnmp.Conn.Close()
err = goSnmp.Connect()
if err != nil {
if err := goSnmp.Connect(); err != nil {
log.Err(err).Msg("SNMP connect failed")
}
log.Err(e).Msgf("could not get data for target '%s' + mib '%s'", target, mib)
Expand All @@ -137,7 +137,7 @@ func (client *SnmpClient) GetSnmpData(mibs []string, target string, secData *uti
data = append(data, *mibData)
}
}
log.Info().Msgf("------ completed for target '%s'", target)
log.Debug().Msgf("------ completed for target '%s'", target)
return data, nil
}

Expand All @@ -150,11 +150,9 @@ func setup(target string, secData *utils.SecurityData) (*snmp.GoSNMP, error) {
}

func setupV2c(target string, community *utils.SecurityData) (*snmp.GoSNMP, error) {
err := validate(target, community)

if err != nil {
if err := validate(target, community); err != nil {
log.Err(err).Msg("could not setup snmp v2c")
return nil, errors.New("validation failed")
return nil, fmt.Errorf("validation failed: %w", err)
}

return &snmp.GoSNMP{
Expand All @@ -169,10 +167,9 @@ func setupV2c(target string, community *utils.SecurityData) (*snmp.GoSNMP, error
}

func setupV3(target string, community *utils.SecurityData) (*snmp.GoSNMP, error) {
err := validate(target, community)
if err != nil {
if err := validate(target, community); err != nil {
log.Err(err).Msg("could not setup snmp v3")
return nil, errors.New("validation failed")
return nil, fmt.Errorf("validation failed: %w", err)
}

var msgFlags snmp.SnmpV3MsgFlags
Expand Down Expand Up @@ -261,7 +258,7 @@ func getSnmpData(mib string, goSnmp *snmp.GoSNMP) (*SnmpMetricData, error) {
return nil, errors.New("missing mib")
}

log.Info().Msgf("-- start getting MIB: %s", mib)
log.Debug().Msgf("-- start getting MIB: %s", mib)

snmpMetric := AvailableMetrics[mib]
if snmpMetric == nil {
Expand All @@ -280,19 +277,17 @@ func getSnmpData(mib string, goSnmp *snmp.GoSNMP) (*SnmpMetricData, error) {
data.SnmpMetric = *snmpMetric

walkHandler := func(dataUnit snmp.SnmpPDU) error {
log.Info().Msgf("-- walk Handler: data unit name: '%s', value: '%s'",
dataUnit.Name, dataUnit.Value)
var val SnmpValue
val.Name = dataUnit.Name
dbg := log.Debug().Interface("SnmpPDU", dataUnit)
val := SnmpValue{Name: dataUnit.Name}
switch v := dataUnit.Value.(type) {
case uint:
val.Value = int64(v)
log.Info().Msgf("*** parsed value for %s: %d", val.Name, val.Value)
dbg.Interface("val", val).Msg("walkHandler: parsed")
case uint64:
val.Value = int64(v)
log.Info().Msgf("*** parsed value for %s: %d", val.Name, val.Value)
dbg.Interface("val", val).Msg("walkHandler: parsed")
default:
log.Warn().Msgf("value '%s' of unsupported type for %s", v, dataUnit.Name)
dbg.Msgf("walkHandler: unsupported type %T", v)
}
data.Values = append(data.Values, val)
return nil
Expand All @@ -303,7 +298,7 @@ func getSnmpData(mib string, goSnmp *snmp.GoSNMP) (*SnmpMetricData, error) {
if err != nil {
return nil, err
} else {
log.Info().Msgf("-- end getting MIB: %s", mib)
log.Debug().Msgf("-- end getting MIB: %s", mib)
}

return &data, nil
Expand Down
4 changes: 4 additions & 0 deletions connectors/snmp/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ func configHandler(data []byte) {
if err == nil {
cfgChksum = chk
}

/* Force sending inventory */
invChksum = nil

/* Restart periodic loop */
cancel()
ctxCancel, cancel = context.WithCancel(context.Background())
Expand Down
Loading
Loading