117 lines
2.4 KiB
Go

package plugin
import (
"context"
"golang.zabbix.com/sdk/errs"
"golang.zabbix.com/sdk/metric"
"golang.zabbix.com/sdk/plugin"
"golang.zabbix.com/sdk/plugin/container"
"golang.zabbix.com/sdk/zbxerr"
"onvif-agent/config"
"time"
)
var Name = config.Conf.Integrations.ZabbixAgent.Plugin.Name
type metricKey string
type metricBinding struct {
metric *metric.Metric
handler HandlerFunc
}
type zabbixAgentPlugin struct {
plugin.Base
metrics map[metricKey]*metricBinding
}
// Launch launches the plugin. Blocks until plugin execution has finished.
func Launch() error {
p := &zabbixAgentPlugin{}
err := p.registerMetrics()
if err != nil {
return err
}
h, err := container.NewHandler(Name)
if err != nil {
return errs.Wrap(err, "failed to create new handler")
}
p.Logger = &h
err = h.Execute()
if err != nil {
return errs.Wrap(err, "failed to execute plugin handler")
}
return nil
}
// Export collects all the metrics.
func (p *zabbixAgentPlugin) Export(key string, rawParams []string, _ plugin.ContextProvider) (any, error) {
b, ok := p.metrics[metricKey(key)]
if !ok {
return nil, errs.Wrapf(zbxerr.ErrorUnsupportedMetric, "unknown metric %q", key)
}
metricParams, extraParams, _, err := b.metric.EvalParams(rawParams, nil)
if err != nil {
return nil, errs.Wrap(err, "failed to evaluate metric parameters")
}
ctx, cancel := context.WithTimeout(
context.Background(),
30*time.Second, // TODO: make configurable
)
defer cancel()
res, err := b.handler(ctx, metricParams, extraParams...)
if err != nil {
return nil, errs.Wrap(err, "failed to execute handler")
}
return res, nil
}
func (p *zabbixAgentPlugin) registerMetrics() error {
h := NewHandler()
p.metrics = map[metricKey]*metricBinding{
"onvif.version": {
metric: metric.New(
"ONVIF plugin version",
nil,
false,
),
handler: h.GetPluginVersion,
},
"onvif.client": {
metric: metric.New(
"ONVIF client",
[]*metric.Param{
metric.NewParam("method", "HTTP request method."),
metric.NewParam("url", "HTTP request URL."),
metric.NewParam("body", "HTTP request body."),
},
false,
),
handler: h.HTTPClient,
},
}
metricSet := metric.MetricSet{}
for k, m := range p.metrics {
metricSet[string(k)] = m.metric
}
err := plugin.RegisterMetrics(p, Name, metricSet.List()...)
if err != nil {
return errs.Wrap(err, "failed to register metrics")
}
return nil
}