bosun.org@v0.0.0-20210513094433-e25bc3e69a1f/cmd/scollector/collectors/snmp_fortinet.go (about)

     1  package collectors
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"time"
     7  
     8  	"bosun.org/cmd/scollector/conf"
     9  	"bosun.org/metadata"
    10  	"bosun.org/opentsdb"
    11  )
    12  
    13  const (
    14  	fortinetBaseOID        = ".1.3.6.1.4.1.12356"
    15  	fortinetCPU            = ".101.4.4.2.1.3"
    16  	fortinetMemTotal       = ".101.4.1.5.0"
    17  	fortinetMemPercentUsed = ".101.4.1.4.0"
    18  )
    19  
    20  // SNMPFortinet registers a SNMP Fortinet collector for the given community and host.
    21  func SNMPFortinet(cfg conf.SNMP) {
    22  	cpuIntegrators := make(map[string]tsIntegrator)
    23  	mib := conf.MIB{
    24  		BaseOid: "1.3.6.1.4.1.12356.101",
    25  		Metrics: []conf.MIBMetric{
    26  			{Metric: "fortinet.disk.used", Oid: ".4.1.6.0", Unit: "MiB", RateType: "gauge", Description: "Disk space used", FallbackOid: "", Tags: "", Scale: 0},
    27  			{Metric: "fortinet.disk.total", Oid: ".4.1.7.0", Unit: "MiB", RateType: "gauge", Description: "Disk space total", FallbackOid: "", Tags: "", Scale: 0},
    28  			{Metric: "fortinet.session.count", Oid: ".11.2.2.1.1.1", Unit: "sessions", RateType: "gauge", Description: "Total number of current sessions being tracked", FallbackOid: "", Tags: "", Scale: 0},
    29  			{Metric: "fortinet.vpn.tunnel_up_count", Oid: ".12.1.1.0", Unit: "tunnel count", RateType: "gauge", Description: "Total number of up VPN tunnels", FallbackOid: "", Tags: "", Scale: 0},
    30  		},
    31  		Trees: []conf.MIBTree{
    32  			{
    33  				BaseOid: ".4.3.2.1",
    34  				Tags:    []conf.MIBTag{{Key: "name", Oid: ".2"}},
    35  				Metrics: []conf.MIBMetric{
    36  					{Metric: "fortinet.hardware.sensor.value", Oid: ".3", Unit: "", RateType: "gauge", Description: "Fortinet hardware sensor values (units vary)", FallbackOid: "", Tags: "", Scale: 0},
    37  					{Metric: "fortinet.hardware.sensor.alarm", Oid: ".4", Unit: "", RateType: "gauge", Description: "Fortinet hardware sensor alarm state (1=alarm)", FallbackOid: "", Tags: "", Scale: 0},
    38  				},
    39  			},
    40  			{
    41  				BaseOid: ".13.2.1.1",
    42  				Tags:    []conf.MIBTag{{Key: "name", Oid: ".11"}},
    43  				Metrics: []conf.MIBMetric{
    44  					{Metric: "fortinet.ha.sync_state", Oid: ".12", Unit: "", RateType: "gauge", Description: "Fortinet HA state (0 = unsynced)", FallbackOid: "", Tags: "", Scale: 0},
    45  				}},
    46  			{
    47  				BaseOid: ".12.2.2.1", Tags: []conf.MIBTag{{Key: "name", Oid: ".2"}},
    48  				Metrics: []conf.MIBMetric{
    49  					{Metric: "fortinet.vpn.state", Oid: ".20", Unit: "", RateType: "gauge", Description: "VPN tunnel state (1=down, 2=up)", FallbackOid: "", Tags: "", Scale: 0},
    50  				},
    51  			},
    52  		},
    53  	}
    54  	collectors = append(collectors,
    55  		&IntervalCollector{
    56  			F: func() (opentsdb.MultiDataPoint, error) {
    57  				return GenericSnmp(cfg, mib)
    58  			},
    59  			Interval: time.Second * 30,
    60  			name:     fmt.Sprintf("snmp-fortinet-%s", cfg.Host),
    61  		},
    62  		&IntervalCollector{
    63  			F: func() (opentsdb.MultiDataPoint, error) {
    64  				return c_fortinet_os(cfg.Host, cfg.Community, cpuIntegrators)
    65  			},
    66  			Interval: time.Second * 30,
    67  			name:     fmt.Sprintf("snmp-fortinet-os-%s", cfg.Host),
    68  		},
    69  		&IntervalCollector{
    70  			F: func() (opentsdb.MultiDataPoint, error) {
    71  				return c_fortinet_meta(cfg.Host, cfg.Community)
    72  			},
    73  			Interval: time.Minute * 5,
    74  			name:     fmt.Sprintf("snmp-fortinet-meta-%s", cfg.Host),
    75  		},
    76  	)
    77  }
    78  
    79  func c_fortinet_os(host, community string, cpuIntegrators map[string]tsIntegrator) (opentsdb.MultiDataPoint, error) {
    80  	var md opentsdb.MultiDataPoint
    81  	ts := opentsdb.TagSet{"host": host}
    82  	// CPU
    83  	cpuRaw, err := snmp_subtree(host, community, fortinetBaseOID+fortinetCPU)
    84  	if err != nil {
    85  		return md, err
    86  	}
    87  	coreCount := len(cpuRaw)
    88  	var totalPercent int
    89  	for id, v := range cpuRaw {
    90  		cpuVal, err := strconv.Atoi(fmt.Sprintf("%v", v))
    91  		if err != nil {
    92  			return md, fmt.Errorf("couldn't convert cpu value to int for fortinet cpu utilization on host %v: %v", host, err)
    93  		}
    94  		ts := ts.Copy().Merge(opentsdb.TagSet{"processor": id})
    95  		Add(&md, "fortinet.cpu.percent_used", cpuVal, ts, metadata.Gauge, metadata.Pct, "")
    96  		totalPercent += cpuVal
    97  	}
    98  	if _, ok := cpuIntegrators[host]; !ok {
    99  		cpuIntegrators[host] = getTsIntegrator()
   100  	}
   101  	Add(&md, osCPU, cpuIntegrators[host](time.Now().Unix(), float64(totalPercent)/float64(coreCount)), opentsdb.TagSet{"host": host}, metadata.Counter, metadata.Pct, "")
   102  
   103  	// Memory
   104  	memTotal, err := snmp_oid(host, community, fortinetBaseOID+fortinetMemTotal)
   105  	if err != nil {
   106  		return md, fmt.Errorf("failed to get total memory for fortinet host %v: %v", host, err)
   107  	}
   108  	memTotalBytes := memTotal.Int64() * 2 << 9 // KiB to Bytes
   109  	Add(&md, "fortinet.mem.total", memTotal, ts, metadata.Gauge, metadata.KBytes, "The total memory in kilobytes.")
   110  	Add(&md, osMemTotal, memTotalBytes, ts, metadata.Gauge, metadata.Bytes, osMemTotalDesc)
   111  	memPctUsed, err := snmp_oid(host, community, fortinetBaseOID+fortinetMemPercentUsed)
   112  	if err != nil {
   113  		return md, fmt.Errorf("failed to get percent of memory used for fortinet host %v: %v", host, err)
   114  	}
   115  	Add(&md, "fortinet.mem.percent_used", memPctUsed, ts, metadata.Gauge, metadata.Pct, "The percent of memory used.")
   116  	memPctUsedFloat := float64(memPctUsed.Int64()) / 100
   117  	memPctFree := 100 - memPctUsed.Int64()
   118  	Add(&md, osMemPctFree, memPctFree, ts, metadata.Gauge, metadata.Pct, osMemPctFreeDesc)
   119  	memFree := float64(memTotalBytes) * (float64(1) - memPctUsedFloat)
   120  	Add(&md, osMemFree, int64(memFree), ts, metadata.Gauge, metadata.Bytes, osMemFreeDesc)
   121  	Add(&md, osMemUsed, int64(float64(memTotalBytes)-memFree), ts, metadata.Gauge, metadata.Bytes, osMemUsedDesc)
   122  
   123  	return md, nil
   124  }
   125  
   126  const (
   127  	fortinetVersion = ".101.4.1.1.0"
   128  	fortinetSerial  = ".100.1.1.1.0"
   129  )
   130  
   131  func c_fortinet_meta(host, community string) (opentsdb.MultiDataPoint, error) {
   132  	var md opentsdb.MultiDataPoint
   133  	ts := opentsdb.TagSet{"host": host}
   134  	serial, err := snmpOidString(host, community, fortinetBaseOID+fortinetSerial)
   135  	if err != nil {
   136  		return md, fmt.Errorf("failed to get serial for host %v: %v", host, err)
   137  	}
   138  	metadata.AddMeta("", ts, "serialNumber", serial, false)
   139  	version, err := snmpOidString(host, community, fortinetBaseOID+fortinetVersion)
   140  	if err != nil {
   141  		return md, fmt.Errorf("failed to get serial for host %v: %v", host, err)
   142  	}
   143  	if version == "" {
   144  		return md, fmt.Errorf("got empty os version string for host %v", host)
   145  	}
   146  	// Fortinet could come from the manufactor oid, but since this is a fortinet
   147  	// only collector saving the extra poll call
   148  	metadata.AddMeta("", ts, "versionCaption", fmt.Sprintf("Fortinet: %v", version), false)
   149  	return md, nil
   150  }