mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
add support for deltas in histogram and summaries
This commit is contained in:
parent
2de94d6548
commit
fca80ff525
@ -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 {
|
if err = addExtentionConventionForRollups(buf, mf, m); err != nil {
|
||||||
// Adding the `.count` suffix makes it possible to configure
|
return err
|
||||||
// `sum` as rollup strategy for counters
|
}
|
||||||
|
|
||||||
|
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 {
|
|
||||||
return float64(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !b.countersAsDetlas {
|
if !b.countersAsDetlas {
|
||||||
return float64(value)
|
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 {
|
@ -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_sum.constname.constvalue.labelname.val1.sum 60 1477043
|
||||||
prefix.name_count.constname.constvalue.labelname.val1 3 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_sum.constname.constvalue.labelname.val2.sum 90 1477043
|
||||||
prefix.name_count.constname.constvalue.labelname.val2 3 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 {
|
@ -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 {
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user