-
Notifications
You must be signed in to change notification settings - Fork 485
/
snmp.go
127 lines (111 loc) · 3.67 KB
/
snmp.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package snmp_exporter
import (
"fmt"
"net/http"
"time"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/prometheus/snmp_exporter/collector"
snmp_config "github.com/prometheus/snmp_exporter/config"
)
const (
namespace = "snmp"
// This is the default value for snmp.module-concurrency in snmp_exporter.
// For now we set to 1 as we don't support multi-module handling.
// More info: https://github.com/prometheus/snmp_exporter#multi-module-handling
concurrency = 1
)
type snmpHandler struct {
cfg *Config
snmpCfg *snmp_config.Config
log log.Logger
}
func Handler(w http.ResponseWriter, r *http.Request, logger log.Logger, snmpCfg *snmp_config.Config,
targets []SNMPTarget, wParams map[string]snmp_config.WalkParams) {
query := r.URL.Query()
snmpTargets := make(map[string]SNMPTarget)
for _, target := range targets {
snmpTargets[target.Name] = target
}
var target string
targetName := query.Get("target")
if len(query["target"]) != 1 || targetName == "" {
http.Error(w, "'target' parameter must be specified once", http.StatusBadRequest)
return
}
t, ok := snmpTargets[targetName]
if ok {
target = t.Target
} else {
target = targetName
}
moduleName := query.Get("module")
if len(query["module"]) > 1 {
http.Error(w, "'module' parameter must only be specified once", http.StatusBadRequest)
return
}
if moduleName == "" {
moduleName = "if_mib"
}
authName := query.Get("auth")
if len(query["auth"]) > 1 {
http.Error(w, "'auth' parameter must only be specified once", http.StatusBadRequest)
return
}
if authName == "" {
authName = "public_v2"
}
module, ok := (*snmpCfg).Modules[moduleName]
if !ok {
http.Error(w, fmt.Sprintf("Unknown module '%s'", moduleName), http.StatusBadRequest)
return
}
auth, ok := (*snmpCfg).Auths[authName]
if !ok {
http.Error(w, fmt.Sprintf("Unknown auth '%s'", authName), http.StatusBadRequest)
return
}
// override module connection details with custom walk params if provided
walkParams := query.Get("walk_params")
if len(query["walk_params"]) > 1 {
http.Error(w, "'walk_params' parameter must only be specified once", http.StatusBadRequest)
return
}
if walkParams != "" {
zeroRetries := 0
if wp, ok := wParams[walkParams]; ok {
if wp.MaxRepetitions != 0 {
module.WalkParams.MaxRepetitions = wp.MaxRepetitions
}
if wp.Retries != nil && wp.Retries != &zeroRetries {
module.WalkParams.Retries = wp.Retries
}
if wp.Timeout != 0 {
module.WalkParams.Timeout = wp.Timeout
}
} else {
http.Error(w, fmt.Sprintf("Unknown walk_params '%s'", walkParams), http.StatusBadRequest)
return
}
logger = log.With(logger, "module", moduleName, "target", target, "walk_params", walkParams)
} else {
logger = log.With(logger, "module", moduleName, "target", target)
}
var nmodules []*collector.NamedModule
nmodules = append(nmodules, collector.NewNamedModule(moduleName, module))
level.Debug(logger).Log("msg", "Starting scrape")
start := time.Now()
registry := prometheus.NewRegistry()
c := collector.New(r.Context(), target, authName, auth, nmodules, logger, NewSNMPMetrics(registry), concurrency)
registry.MustRegister(c)
// Delegate http serving to Prometheus client library, which will call collector.Collect.
h := promhttp.HandlerFor(registry, promhttp.HandlerOpts{})
h.ServeHTTP(w, r)
duration := time.Since(start).Seconds()
level.Debug(logger).Log("msg", "Finished scrape", "duration_seconds", duration)
}
func (sh snmpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
Handler(w, r, sh.log, sh.snmpCfg, sh.cfg.SnmpTargets, sh.cfg.WalkParams)
}