Fix prometheus passthrough for existing value types (#3351)

This commit is contained in:
Daniel Nelson
2017-10-18 14:51:08 -07:00
committed by GitHub
parent 9b59cdd10e
commit 6e5915c59f
4 changed files with 120 additions and 21 deletions

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"log"
"net/http"
"os"
"regexp"
"sort"
"strings"
@@ -15,6 +16,7 @@ import (
"github.com/influxdata/telegraf/internal"
"github.com/influxdata/telegraf/plugins/outputs"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var invalidNameCharRE = regexp.MustCompile(`[^a-zA-Z0-9_]`)
@@ -46,6 +48,7 @@ type PrometheusClient struct {
Listen string
ExpirationInterval internal.Duration `toml:"expiration_interval"`
Path string `toml:"path"`
CollectorsExclude []string `toml:"collectors_exclude"`
server *http.Server
@@ -62,11 +65,26 @@ var sampleConfig = `
## Interval to expire metrics and not deliver to prometheus, 0 == no expiration
# expiration_interval = "60s"
## Collectors to enable, valid entries are "gocollector" and "process".
## If unset, both are enabled.
collectors_exclude = ["gocollector", "process"]
`
func (p *PrometheusClient) Start() error {
prometheus.Register(p)
for _, collector := range p.CollectorsExclude {
switch collector {
case "gocollector":
prometheus.Unregister(prometheus.NewGoCollector())
case "process":
prometheus.Unregister(prometheus.NewProcessCollector(os.Getpid(), ""))
default:
return fmt.Errorf("unrecognized collector %s", collector)
}
}
if p.Listen == "" {
p.Listen = "localhost:9273"
}
@@ -76,7 +94,9 @@ func (p *PrometheusClient) Start() error {
}
mux := http.NewServeMux()
mux.Handle(p.Path, prometheus.Handler())
mux.Handle(p.Path, promhttp.HandlerFor(
prometheus.DefaultGatherer,
promhttp.HandlerOpts{ErrorHandling: promhttp.ContinueOnError}))
p.server = &http.Server{
Addr: p.Listen,
@@ -243,10 +263,22 @@ func (p *PrometheusClient) Write(metrics []telegraf.Metric) error {
// Special handling of value field; supports passthrough from
// the prometheus input.
var mname string
if fn == "value" {
mname = sanitize(point.Name())
} else {
mname = sanitize(fmt.Sprintf("%s_%s", point.Name(), fn))
switch point.Type() {
case telegraf.Counter:
if fn == "counter" {
mname = sanitize(point.Name())
}
case telegraf.Gauge:
if fn == "gauge" {
mname = sanitize(point.Name())
}
}
if mname == "" {
if fn == "value" {
mname = sanitize(point.Name())
} else {
mname = sanitize(fmt.Sprintf("%s_%s", point.Name(), fn))
}
}
var fam *MetricFamily