Add prometheus_client service output module, update prometheus client
- Adds a client implementation using the prometheus go_client library
that exposes metrics.
- Adds a new type of output "ServiceOutput" which follows inline with
the "ServicePlugin", adding a Stop and Start method for the service
This change also requires the newer prometheus/client_golang code, so
the prometheus plugin needed to be changed.
Added the following to Godep:
- bitbucket.org/ww/goautoneg (in github.com/common/expfmt/encode.go)
- prometheus/common/expfmt (in plugins/prometheus.go)
- github.com/prometheus/common/model (in plugins/prometheus.go)
- github.com/prometheus/procfs (in github.com/client_golang/prometheus)
- github.com/beorn7/perks/quantile (in github.com/client_golang/prometheus)
X-Github-Meta: closes #306
This commit is contained in:
committed by
Cameron Sparr
parent
7cc60dfb8f
commit
4449f7f2fb
109
outputs/prometheus_client/prometheus_client.go
Normal file
109
outputs/prometheus_client/prometheus_client.go
Normal file
@@ -0,0 +1,109 @@
|
||||
package prometheus_client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/influxdb/influxdb/client/v2"
|
||||
"github.com/influxdb/telegraf/outputs"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type PrometheusClient struct {
|
||||
Listen string
|
||||
server *http.Server
|
||||
metrics map[string]*prometheus.UntypedVec
|
||||
}
|
||||
|
||||
var sampleConfig = `
|
||||
# Address to listen on
|
||||
# listen = ":9126"
|
||||
`
|
||||
|
||||
func (p *PrometheusClient) Start() error {
|
||||
if p.Listen == "" {
|
||||
p.Listen = ":9126"
|
||||
}
|
||||
http.Handle("/metrics", prometheus.Handler())
|
||||
server := &http.Server{
|
||||
Addr: p.Listen,
|
||||
Handler: prometheus.Handler(),
|
||||
}
|
||||
p.server = server
|
||||
p.metrics = make(map[string]*prometheus.UntypedVec)
|
||||
go p.server.ListenAndServe()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PrometheusClient) Stop() {
|
||||
// TODO: Use a listener for http.Server that counts active connections
|
||||
// that can be stopped and closed gracefully
|
||||
}
|
||||
|
||||
func (p *PrometheusClient) Connect() error {
|
||||
// This service output does not need to make any further connections
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PrometheusClient) Close() error {
|
||||
// This service output does not need to close any of its connections
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PrometheusClient) SampleConfig() string {
|
||||
return sampleConfig
|
||||
}
|
||||
|
||||
func (p *PrometheusClient) Description() string {
|
||||
return "Configuration for the Prometheus client to spawn"
|
||||
}
|
||||
|
||||
func (p *PrometheusClient) Write(points []*client.Point) error {
|
||||
if len(points) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, point := range points {
|
||||
var labels []string
|
||||
name := point.Name()
|
||||
key := name
|
||||
|
||||
for k, _ := range point.Tags() {
|
||||
if len(k) > 0 {
|
||||
labels = append(labels, k)
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := p.metrics[key]; !ok {
|
||||
p.metrics[key] = prometheus.NewUntypedVec(
|
||||
prometheus.UntypedOpts{
|
||||
Name: key,
|
||||
Help: fmt.Sprintf("Telegraf collected point '%s'", name),
|
||||
},
|
||||
labels,
|
||||
)
|
||||
prometheus.MustRegister(p.metrics[key])
|
||||
}
|
||||
|
||||
l := prometheus.Labels{}
|
||||
for tk, tv := range point.Tags() {
|
||||
l[tk] = tv
|
||||
}
|
||||
|
||||
for _, val := range point.Fields() {
|
||||
switch val.(type) {
|
||||
case int64:
|
||||
ival := val.(int64)
|
||||
p.metrics[key].With(l).Set(float64(ival))
|
||||
case float64:
|
||||
p.metrics[key].With(l).Set(val.(float64))
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
outputs.Add("prometheus_client", func() outputs.Output {
|
||||
return &PrometheusClient{}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user