Просмотр исходного кода

add support for deltas in histogram and summaries

bergquist 8 лет назад
Родитель
Сommit
fca80ff525

+ 45 - 7
pkg/metrics/graphitepublisher/graphite.go → pkg/metrics/graphitebridge/graphite.go

@@ -13,7 +13,7 @@
 
 
 // Package graphite provides a bridge to push Prometheus metrics to a Graphite
 // Package graphite provides a bridge to push Prometheus metrics to a Graphite
 // server.
 // server.
-package graphitepublisher
+package graphitebridge
 
 
 import (
 import (
 	"bufio"
 	"bufio"
@@ -275,14 +275,40 @@ func writeMetric(buf *bufio.Writer, m model.Metric, mf *dto.MetricFamily) error
 		}
 		}
 	}
 	}
 
 
-	if mf.GetType() == dto.MetricType_COUNTER {
-		// Adding the `.count` suffix makes it possible to configure
-		// `sum` as rollup strategy for counters
+	if err = addExtentionConventionForRollups(buf, mf, m); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func addExtentionConventionForRollups(buf *bufio.Writer, mf *dto.MetricFamily, m model.Metric) error {
+	// Adding `.count` `.sum` suffix makes it possible to configure
+	// different rollup strategies based on metric type
+
+	mfType := mf.GetType()
+	var err error
+	if mfType == dto.MetricType_COUNTER {
 		if _, err = fmt.Fprint(buf, ".count"); err != nil {
 		if _, err = fmt.Fprint(buf, ".count"); err != nil {
 			return err
 			return err
 		}
 		}
 	}
 	}
 
 
+	if mfType == dto.MetricType_SUMMARY || mfType == dto.MetricType_HISTOGRAM {
+		if strings.HasSuffix(string(m[model.MetricNameLabel]), "_count") {
+			if _, err = fmt.Fprint(buf, ".count"); err != nil {
+				return err
+			}
+		}
+	}
+	if mfType == dto.MetricType_HISTOGRAM {
+		if strings.HasSuffix(string(m[model.MetricNameLabel]), "_sum") {
+			if _, err = fmt.Fprint(buf, ".sum"); err != nil {
+				return err
+			}
+		}
+	}
+
 	return nil
 	return nil
 }
 }
 
 
@@ -318,19 +344,31 @@ func replaceInvalidRune(c rune) rune {
 }
 }
 
 
 func (b *Bridge) replaceCounterWithDelta(mf *dto.MetricFamily, metric model.Metric, value model.SampleValue) float64 {
 func (b *Bridge) replaceCounterWithDelta(mf *dto.MetricFamily, metric model.Metric, value model.SampleValue) float64 {
-	if mf.GetType() != dto.MetricType_COUNTER {
+	if !b.countersAsDetlas {
 		return float64(value)
 		return float64(value)
 	}
 	}
 
 
-	if !b.countersAsDetlas {
-		return float64(value)
+	mfType := mf.GetType()
+	if mfType == dto.MetricType_COUNTER {
+		return b.returnDelta(metric, value)
 	}
 	}
 
 
+	if mfType == dto.MetricType_SUMMARY {
+		if strings.HasSuffix(string(metric[model.MetricNameLabel]), "_count") {
+			return b.returnDelta(metric, value)
+		}
+	}
+
+	return float64(value)
+
 	//println("use delta for", metric[model.MetricNameLabel], mf.GetType().String())
 	//println("use delta for", metric[model.MetricNameLabel], mf.GetType().String())
 
 
 	//TODO(bergquist): turn _count in summery into delta
 	//TODO(bergquist): turn _count in summery into delta
 	//TODO(bergquist): turn _count in histogram into delta
 	//TODO(bergquist): turn _count in histogram into delta
 
 
+}
+
+func (b *Bridge) returnDelta(metric model.Metric, value model.SampleValue) float64 {
 	key := metric.Fingerprint()
 	key := metric.Fingerprint()
 	_, exists := b.lastValue[key]
 	_, exists := b.lastValue[key]
 	if !exists {
 	if !exists {

+ 7 - 7
pkg/metrics/graphitepublisher/graphite_test.go → pkg/metrics/graphitebridge/graphite_test.go

@@ -1,4 +1,4 @@
-package graphitepublisher
+package graphitebridge
 
 
 import (
 import (
 	"bufio"
 	"bufio"
@@ -142,12 +142,12 @@ func TestWriteSummary(t *testing.T) {
 prefix.name.constname.constvalue.labelname.val1.quantile.0_9 30 1477043
 prefix.name.constname.constvalue.labelname.val1.quantile.0_9 30 1477043
 prefix.name.constname.constvalue.labelname.val1.quantile.0_99 30 1477043
 prefix.name.constname.constvalue.labelname.val1.quantile.0_99 30 1477043
 prefix.name_sum.constname.constvalue.labelname.val1 60 1477043
 prefix.name_sum.constname.constvalue.labelname.val1 60 1477043
-prefix.name_count.constname.constvalue.labelname.val1 3 1477043
+prefix.name_count.constname.constvalue.labelname.val1.count 3 1477043
 prefix.name.constname.constvalue.labelname.val2.quantile.0_5 30 1477043
 prefix.name.constname.constvalue.labelname.val2.quantile.0_5 30 1477043
 prefix.name.constname.constvalue.labelname.val2.quantile.0_9 40 1477043
 prefix.name.constname.constvalue.labelname.val2.quantile.0_9 40 1477043
 prefix.name.constname.constvalue.labelname.val2.quantile.0_99 40 1477043
 prefix.name.constname.constvalue.labelname.val2.quantile.0_99 40 1477043
 prefix.name_sum.constname.constvalue.labelname.val2 90 1477043
 prefix.name_sum.constname.constvalue.labelname.val2 90 1477043
-prefix.name_count.constname.constvalue.labelname.val2 3 1477043
+prefix.name_count.constname.constvalue.labelname.val2.count 3 1477043
 `
 `
 
 
 	if got := buf.String(); want != got {
 	if got := buf.String(); want != got {
@@ -201,15 +201,15 @@ func TestWriteHistogram(t *testing.T) {
 prefix.name_bucket.constname.constvalue.labelname.val1.le.0_02 0 1477043
 prefix.name_bucket.constname.constvalue.labelname.val1.le.0_02 0 1477043
 prefix.name_bucket.constname.constvalue.labelname.val1.le.0_05 0 1477043
 prefix.name_bucket.constname.constvalue.labelname.val1.le.0_05 0 1477043
 prefix.name_bucket.constname.constvalue.labelname.val1.le.0_1 0 1477043
 prefix.name_bucket.constname.constvalue.labelname.val1.le.0_1 0 1477043
-prefix.name_sum.constname.constvalue.labelname.val1 60 1477043
-prefix.name_count.constname.constvalue.labelname.val1 3 1477043
+prefix.name_sum.constname.constvalue.labelname.val1.sum 60 1477043
+prefix.name_count.constname.constvalue.labelname.val1.count 3 1477043
 prefix.name_bucket.constname.constvalue.labelname.val1.le._Inf 3 1477043
 prefix.name_bucket.constname.constvalue.labelname.val1.le._Inf 3 1477043
 prefix.name_bucket.constname.constvalue.labelname.val2.le.0_01 0 1477043
 prefix.name_bucket.constname.constvalue.labelname.val2.le.0_01 0 1477043
 prefix.name_bucket.constname.constvalue.labelname.val2.le.0_02 0 1477043
 prefix.name_bucket.constname.constvalue.labelname.val2.le.0_02 0 1477043
 prefix.name_bucket.constname.constvalue.labelname.val2.le.0_05 0 1477043
 prefix.name_bucket.constname.constvalue.labelname.val2.le.0_05 0 1477043
 prefix.name_bucket.constname.constvalue.labelname.val2.le.0_1 0 1477043
 prefix.name_bucket.constname.constvalue.labelname.val2.le.0_1 0 1477043
-prefix.name_sum.constname.constvalue.labelname.val2 90 1477043
-prefix.name_count.constname.constvalue.labelname.val2 3 1477043
+prefix.name_sum.constname.constvalue.labelname.val2.sum 90 1477043
+prefix.name_count.constname.constvalue.labelname.val2.count 3 1477043
 prefix.name_bucket.constname.constvalue.labelname.val2.le._Inf 3 1477043
 prefix.name_bucket.constname.constvalue.labelname.val2.le._Inf 3 1477043
 `
 `
 	if got := buf.String(); want != got {
 	if got := buf.String(); want != got {

+ 2 - 2
pkg/metrics/publish.go

@@ -4,7 +4,7 @@ import (
 	"context"
 	"context"
 
 
 	"github.com/grafana/grafana/pkg/log"
 	"github.com/grafana/grafana/pkg/log"
-	"github.com/grafana/grafana/pkg/metrics/graphitepublisher"
+	"github.com/grafana/grafana/pkg/metrics/graphitebridge"
 )
 )
 
 
 var metricsLogger log.Logger = log.New("metrics")
 var metricsLogger log.Logger = log.New("metrics")
@@ -22,7 +22,7 @@ func Init(settings *MetricSettings) {
 	initMetricVars(settings)
 	initMetricVars(settings)
 
 
 	if settings.GraphiteBridgeConfig != nil {
 	if settings.GraphiteBridgeConfig != nil {
-		bridge, err := graphitepublisher.NewBridge(settings.GraphiteBridgeConfig)
+		bridge, err := graphitebridge.NewBridge(settings.GraphiteBridgeConfig)
 		if err != nil {
 		if err != nil {
 			metricsLogger.Error("failed to create graphite bridge", "error", err)
 			metricsLogger.Error("failed to create graphite bridge", "error", err)
 		} else {
 		} else {

+ 5 - 5
pkg/metrics/settings.go

@@ -4,7 +4,7 @@ import (
 	"strings"
 	"strings"
 	"time"
 	"time"
 
 
-	"github.com/grafana/grafana/pkg/metrics/graphitepublisher"
+	"github.com/grafana/grafana/pkg/metrics/graphitebridge"
 	"github.com/grafana/grafana/pkg/setting"
 	"github.com/grafana/grafana/pkg/setting"
 	"github.com/prometheus/client_golang/prometheus"
 	"github.com/prometheus/client_golang/prometheus"
 	ini "gopkg.in/ini.v1"
 	ini "gopkg.in/ini.v1"
@@ -13,7 +13,7 @@ import (
 type MetricSettings struct {
 type MetricSettings struct {
 	Enabled              bool
 	Enabled              bool
 	IntervalSeconds      int64
 	IntervalSeconds      int64
-	GraphiteBridgeConfig *graphitepublisher.Config
+	GraphiteBridgeConfig *graphitebridge.Config
 }
 }
 
 
 func ReadSettings(file *ini.File) *MetricSettings {
 func ReadSettings(file *ini.File) *MetricSettings {
@@ -45,7 +45,7 @@ func ReadSettings(file *ini.File) *MetricSettings {
 	return settings
 	return settings
 }
 }
 
 
-func parseGraphiteSettings(settings *MetricSettings, file *ini.File) (*graphitepublisher.Config, error) {
+func parseGraphiteSettings(settings *MetricSettings, file *ini.File) (*graphitebridge.Config, error) {
 	graphiteSection, err := setting.Cfg.GetSection("metrics.graphite")
 	graphiteSection, err := setting.Cfg.GetSection("metrics.graphite")
 	if err != nil {
 	if err != nil {
 		return nil, nil
 		return nil, nil
@@ -56,7 +56,7 @@ func parseGraphiteSettings(settings *MetricSettings, file *ini.File) (*graphitep
 		return nil, nil
 		return nil, nil
 	}
 	}
 
 
-	cfg := &graphitepublisher.Config{
+	cfg := &graphitebridge.Config{
 		URL:             address,
 		URL:             address,
 		Prefix:          graphiteSection.Key("prefix").MustString("prod.grafana.%(instance_name)s"),
 		Prefix:          graphiteSection.Key("prefix").MustString("prod.grafana.%(instance_name)s"),
 		CountersAsDelta: true,
 		CountersAsDelta: true,
@@ -64,7 +64,7 @@ func parseGraphiteSettings(settings *MetricSettings, file *ini.File) (*graphitep
 		Interval:        time.Duration(settings.IntervalSeconds) * time.Second,
 		Interval:        time.Duration(settings.IntervalSeconds) * time.Second,
 		Timeout:         10 * time.Second,
 		Timeout:         10 * time.Second,
 		Logger:          &logWrapper{logger: metricsLogger},
 		Logger:          &logWrapper{logger: metricsLogger},
-		ErrorHandling:   graphitepublisher.ContinueOnError,
+		ErrorHandling:   graphitebridge.ContinueOnError,
 	}
 	}
 
 
 	safeInstanceName := strings.Replace(setting.InstanceName, ".", "_", -1)
 	safeInstanceName := strings.Replace(setting.InstanceName, ".", "_", -1)