Skip to content

Commit

Permalink
GROUNDWORK-3736 improve SNMP logging
Browse files Browse the repository at this point in the history
  • Loading branch information
Pavlo Sumkin committed Nov 29, 2024
1 parent 3988fb1 commit 13d4c89
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 68 deletions.
80 changes: 36 additions & 44 deletions connectors/snmp/clients/nediClient.go
Original file line number Diff line number Diff line change
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,19 +305,18 @@ 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) {
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

0 comments on commit 13d4c89

Please sign in to comment.