prometheus_client, implement Collector interface

closes #1334
This commit is contained in:
Cameron Sparr 2016-07-10 14:47:47 +01:00
parent 5f0a63f554
commit 6efe91ea9c
2 changed files with 38 additions and 33 deletions

View File

@ -44,6 +44,7 @@ should now look like:
- [#1378](https://github.com/influxdata/telegraf/issues/1378): Trim BOM from config file for Windows support. - [#1378](https://github.com/influxdata/telegraf/issues/1378): Trim BOM from config file for Windows support.
- [#1339](https://github.com/influxdata/telegraf/issues/1339): Prometheus client output panic on service reload. - [#1339](https://github.com/influxdata/telegraf/issues/1339): Prometheus client output panic on service reload.
- [#1461](https://github.com/influxdata/telegraf/pull/1461): Prometheus parser, protobuf format header fix. - [#1461](https://github.com/influxdata/telegraf/pull/1461): Prometheus parser, protobuf format header fix.
- [#1334](https://github.com/influxdata/telegraf/issues/1334): Prometheus output, metric refresh and caching fixes.
## v1.0 beta 2 [2016-06-21] ## v1.0 beta 2 [2016-06-21]

View File

@ -6,6 +6,7 @@ import (
"net/http" "net/http"
"regexp" "regexp"
"strings" "strings"
"sync"
"github.com/influxdata/telegraf" "github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/plugins/outputs" "github.com/influxdata/telegraf/plugins/outputs"
@ -26,6 +27,10 @@ var (
type PrometheusClient struct { type PrometheusClient struct {
Listen string Listen string
metrics map[string]prometheus.Metric
sync.Mutex
} }
var sampleConfig = ` var sampleConfig = `
@ -34,6 +39,7 @@ var sampleConfig = `
` `
func (p *PrometheusClient) Start() error { func (p *PrometheusClient) Start() error {
prometheus.MustRegister(p)
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
// recovering from panic here because there is no way to stop a // recovering from panic here because there is no way to stop a
@ -78,7 +84,27 @@ func (p *PrometheusClient) Description() string {
return "Configuration for the Prometheus client to spawn" return "Configuration for the Prometheus client to spawn"
} }
// Implements prometheus.Collector
func (p *PrometheusClient) Describe(ch chan<- *prometheus.Desc) {
prometheus.NewGauge(prometheus.GaugeOpts{Name: "Dummy", Help: "Dummy"}).Describe(ch)
}
// Implements prometheus.Collector
func (p *PrometheusClient) Collect(ch chan<- prometheus.Metric) {
p.Lock()
defer p.Unlock()
for _, m := range p.metrics {
ch <- m
}
}
func (p *PrometheusClient) Write(metrics []telegraf.Metric) error { func (p *PrometheusClient) Write(metrics []telegraf.Metric) error {
p.Lock()
defer p.Unlock()
p.metrics = make(map[string]prometheus.Metric)
if len(metrics) == 0 { if len(metrics) == 0 {
return nil return nil
} }
@ -124,45 +150,23 @@ func (p *PrometheusClient) Write(metrics []telegraf.Metric) error {
continue continue
} }
mVec := prometheus.NewUntypedVec( desc := prometheus.NewDesc(mname, "Telegraf collected metric", nil, l)
prometheus.UntypedOpts{ var metric prometheus.Metric
Name: mname, var err error
Help: "Telegraf collected metric",
},
labels,
)
collector, err := prometheus.RegisterOrGet(mVec)
if err != nil {
log.Printf("prometheus_client: Metric failed to register with prometheus, %s", err)
continue
}
mVec, ok := collector.(*prometheus.UntypedVec)
if !ok {
continue
}
switch val := val.(type) { switch val := val.(type) {
case int64: case int64:
m, err := mVec.GetMetricWith(l) metric, err = prometheus.NewConstMetric(desc, prometheus.UntypedValue, float64(val))
if err != nil {
log.Printf("ERROR Getting metric in Prometheus output, "+
"key: %s, labels: %v,\nerr: %s\n",
mname, l, err.Error())
continue
}
m.Set(float64(val))
case float64: case float64:
m, err := mVec.GetMetricWith(l) metric, err = prometheus.NewConstMetric(desc, prometheus.UntypedValue, val)
if err != nil {
log.Printf("ERROR Getting metric in Prometheus output, "+
"key: %s, labels: %v,\nerr: %s\n",
mname, l, err.Error())
continue
}
m.Set(val)
default: default:
continue continue
} }
if err != nil {
log.Printf("ERROR creating prometheus metric, "+
"key: %s, labels: %v,\nerr: %s\n",
mname, l, err.Error())
}
p.metrics[desc.String()] = metric
} }
} }
return nil return nil