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

Fixes snmp sender #298

Merged
merged 8 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
91 changes: 49 additions & 42 deletions sender/snmp.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ type SNMP struct {
g *gosnmp.GoSNMP
}

/*
* SNMP trap sender
*/
func (x *SNMP) init() {
var version gosnmp.SnmpVersion
if x.Version == "2c" {
Expand Down Expand Up @@ -60,52 +63,56 @@ func (x *SNMP) Send(c *skogul.Container) error {
return x.err
}

pdutypes := []gosnmp.SnmpPDU{}

for _, m := range c.Metrics {
for j, i := range m.Data {
var pdutype gosnmp.SnmpPDU

pduName := fmt.Sprintf("%s", x.Oidmap[j])

switch reflect.TypeOf(i).Kind() {
case reflect.String:
pdutype = gosnmp.SnmpPDU{
Value: i,
Name: pduName,
Type: gosnmp.OctetString,
}
case reflect.Bool:
pdutype = gosnmp.SnmpPDU{
Value: i,
Name: pduName,
Type: gosnmp.Boolean,
}
case reflect.Int:
pdutype = gosnmp.SnmpPDU{
Value: i,
Name: pduName,
Type: gosnmp.Integer,
}
default:
pdutypes := []gosnmp.SnmpPDU{
{
Value: ".1.3.6.1.4.1.12748.2023.0.888",
Name: ".1.3.6.1.6.3.1.1.4.1.0",
Type: gosnmp.ObjectIdentifier,
KristianLyng marked this conversation as resolved.
Show resolved Hide resolved
},
}

m := c.Metrics[0]

for j, i := range m.Data {
var pdutype gosnmp.SnmpPDU

pduName := fmt.Sprintf("%s", x.Oidmap[j])

switch reflect.TypeOf(i).Kind() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't realize this the last time I approved this, but this really doesn't require reflection.

You can write (copied from marshal.go as an example):

        switch value := v.(type) {
        case float64:
                d.Duration = time.Duration(value)
                return nil
        case string:
                var err error
                d.Duration, err = time.ParseDuration(value)
                if err != nil {
                        return err
                }
                return nil
        default:
                return errors.New("invalid duration")
        }

Reflection is considerably slower, which probably isn't noticeable in an SNMP trap sender, but should, in general, be avoided in busy loops.

case reflect.String:
pdutype = gosnmp.SnmpPDU{
Value: i,
Name: pduName,
Type: gosnmp.OctetString,
}
case reflect.Bool:
pdutype = gosnmp.SnmpPDU{
Value: i,
Name: pduName,
Type: gosnmp.Boolean,
}
pdutypes = append(pdutypes, pdutype)

trap := gosnmp.SnmpTrap{}
trap.Variables = pdutypes
trap.IsInform = false
trap.Enterprise = "no"
trap.AgentAddress = "localhost"
trap.GenericTrap = 1
trap.SpecificTrap = 1
_, err := x.g.SendTrap(trap)

if err != nil {
x.err = err
case reflect.Float64:
k := int(i.(float64))
pdutype = gosnmp.SnmpPDU{
Value: k,
Name: pduName,
Type: gosnmp.Integer,
}
default:
}
pdutypes = append(pdutypes, pdutype)
}

trap := gosnmp.SnmpTrap{}
trap.Variables = pdutypes
trap.IsInform = false
trap.Enterprise = "no"
trap.AgentAddress = "localhost"
_, err := x.g.SendTrap(trap)

if err != nil {
x.err = err
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure you want to do this? This will DISABLE the entire sender on the first mal-formed or failing snmp trap. The pattern of using x.err is mainly meant to remember that initialization (x.init()) failed after sync.Once has run.

}

return nil
return x.err
}
81 changes: 31 additions & 50 deletions sender/snmp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,60 +16,41 @@ import (

func TestSnmpSenderTest(t *testing.T) {
t.Skip()
c, _ := loadJsonFile(t, "ble ble")
c, _ := loadJsonFile(t, "")

sconf := fmt.Sprintln(`
{
"receivers": {
"http": {
"type": "http",
"address": "localhost:1337",
"handlers": {
"/": "h"
{
"receivers": {
"http": {
"type": "http",
"address": ":11111",
"handlers": {
"/": "h"
}
}
}
},
"transformers": {
"flatten_data": {
"type": "data",
"flattenSeparator": "drop",
"flatten": [
[
"kek"
]
]
},
"remove_data": {
"type": "data",
"remove": [
"kek"
]
}
},
"handlers": {
"h": {
"parser": "skogul",
"transformers": [
"now",
"flatten_data",
"remove_data"
],
"sender": "snmp"
}
},
"senders": {
"snmp": {
"type": "snmp",
"port": 7331,
"community": "xxx",
"version": "2c",
"target": "localhost",
"oidmap": {
"kek": "1.3.3.7",
"transformers": {},
"handlers": {
"h": {
"parser": "skogul",
"transformers": [
"now"
],
"sender": "print"
}
}
}
}`)
},
"senders": {
"snmp": {
"type": "snmp",
"port": 1337,
"community": "public",
"version": "2c",
"target": "localhost",
"oidmap": {}
}
}
}
`)

conf, err := config.Bytes([]byte(sconf))

Expand All @@ -91,7 +72,7 @@ func TestSnmpSenderTest(t *testing.T) {
}

go httpRcv.Start()
time.Sleep(time.Duration(20 * time.Millisecond))
time.Sleep(time.Duration(5 * time.Second))

err = snmpSender.Send(c)

Expand Down
Loading