package main import ( "path" "time" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/common/log" "github.com/soundcloud/ipmi_exporter/freeipmi" ) const ( namespace = "ipmi" targetLocal = "" ) type collector interface { Name() CollectorName Cmd() string Args() []string Collect(output freeipmi.Result, ch chan<- prometheus.Metric, target ipmiTarget) (int, error) } type metaCollector struct { target string module string config *SafeConfig } type ipmiTarget struct { host string config IPMIConfig } var ( upDesc = prometheus.NewDesc( prometheus.BuildFQName(namespace, "", "up"), "'1' if a scrape of the IPMI device was successful, '0' otherwise.", []string{"collector"}, nil, ) durationDesc = prometheus.NewDesc( prometheus.BuildFQName(namespace, "scrape_duration", "seconds"), "Returns how long the scrape took to complete in seconds.", nil, nil, ) ) // Describe implements Prometheus.Collector. func (c metaCollector) Describe(ch chan<- *prometheus.Desc) { // all metrics are described ad-hoc } func markCollectorUp(ch chan<- prometheus.Metric, name string, up int) { ch <- prometheus.MustNewConstMetric( upDesc, prometheus.GaugeValue, float64(up), name, ) } // Collect implements Prometheus.Collector. func (c metaCollector) Collect(ch chan<- prometheus.Metric) { start := time.Now() defer func() { duration := time.Since(start).Seconds() log.Debugf("Scrape of target %s took %f seconds.", targetName(c.target), duration) ch <- prometheus.MustNewConstMetric( durationDesc, prometheus.GaugeValue, duration, ) }() config := c.config.ConfigForTarget(c.target, c.module) target := ipmiTarget{ host: c.target, config: config, } for _, collector := range config.GetCollectors() { var up int log.Debugf("Running collector: %s", collector.Name()) fqcmd := path.Join(*executablesPath, collector.Cmd()) args := collector.Args() cfg := config.GetFreeipmiConfig() result := freeipmi.Execute(fqcmd, args, cfg, target.host, log.Base()) up, _ = collector.Collect(result, ch, target) markCollectorUp(ch, string(collector.Name()), up) } } func targetName(target string) string { if target == targetLocal { return "[local]" } return target }