Skip to content

Commit

Permalink
Fixes negative gauge in Promtail.
Browse files Browse the repository at this point in the history
Fixes grafana#3281

Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com>
  • Loading branch information
cyriltovena committed Jul 8, 2021
1 parent 39ac2e5 commit 89a38bd
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 8 deletions.
11 changes: 5 additions & 6 deletions clients/pkg/logentry/stages/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func validateMetricsConfig(cfg MetricsConfig) error {
return errors.New(ErrEmptyMetricsStageConfig)
}
for name, config := range cfg {
//If the source is not defined, default to the metric name
// If the source is not defined, default to the metric name
if config.Source == nil {
cp := cfg[name]
nm := name
Expand Down Expand Up @@ -201,7 +201,7 @@ func (m *metricStage) recordCounter(name string, counter *metric.Counters, label
counter.With(labels).Inc()
case metric.CounterAdd:
f, err := getFloat(v)
if err != nil || f < 0 {
if err != nil {
if Debug {
level.Debug(m.logger).Log("msg", "failed to convert extracted value to positive float", "metric", name, "err", err)
}
Expand Down Expand Up @@ -232,7 +232,7 @@ func (m *metricStage) recordGauge(name string, gauge *metric.Gauges, labels mode
switch gauge.Cfg.Action {
case metric.GaugeSet:
f, err := getFloat(v)
if err != nil || f < 0 {
if err != nil {
if Debug {
level.Debug(m.logger).Log("msg", "failed to convert extracted value to positive float", "metric", name, "err", err)
}
Expand All @@ -245,7 +245,7 @@ func (m *metricStage) recordGauge(name string, gauge *metric.Gauges, labels mode
gauge.With(labels).Dec()
case metric.GaugeAdd:
f, err := getFloat(v)
if err != nil || f < 0 {
if err != nil {
if Debug {
level.Debug(m.logger).Log("msg", "failed to convert extracted value to positive float", "metric", name, "err", err)
}
Expand All @@ -254,7 +254,7 @@ func (m *metricStage) recordGauge(name string, gauge *metric.Gauges, labels mode
gauge.With(labels).Add(f)
case metric.GaugeSub:
f, err := getFloat(v)
if err != nil || f < 0 {
if err != nil {
if Debug {
level.Debug(m.logger).Log("msg", "failed to convert extracted value to positive float", "metric", name, "err", err)
}
Expand Down Expand Up @@ -293,7 +293,6 @@ func (m *metricStage) recordHistogram(name string, histogram *metric.Histograms,

// getFloat will take the provided value and return a float64 if possible
func getFloat(unk interface{}) (float64, error) {

switch i := unk.(type) {
case float64:
return i, nil
Expand Down
42 changes: 40 additions & 2 deletions clients/pkg/logentry/stages/metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ var testMetricLogLine1 = `
"level" : "WARN"
}
`

var testMetricLogLine2 = `
{
"time":"2012-11-01T22:08:41+00:00",
Expand All @@ -78,6 +79,7 @@ var testMetricLogLine2 = `
"level" : "WARN"
}
`

var testMetricLogLineWithMissingKey = `
{
"time":"2012-11-01T22:08:41+00:00",
Expand Down Expand Up @@ -125,6 +127,40 @@ func TestMetricsPipeline(t *testing.T) {
}
}

func TestNegativeGauge(t *testing.T) {
registry := prometheus.NewRegistry()
testConfig := `
pipeline_stages:
- regex:
expression: 'vehicule=(?P<vehicule>\d+) longitude=(?P<longitude>[-]?\d+\.\d+) latitude=(?P<latitude>\d+\.\d+)'
- labels:
vehicule:
- metrics:
longitude:
type: Gauge
description: "longitude GPS vehicule"
source: longitude
config:
match_all: true
action: set
`
pl, err := NewPipeline(util_log.Logger, loadConfig(testConfig), nil, registry)
if err != nil {
t.Fatal(err)
}

<-pl.Run(withInboundEntries(newEntry(nil, model.LabelSet{"test": "app"}, `#<13>Jan 28 14:25:52 vehicule=1 longitude=-10.1234 latitude=15.1234`, time.Now())))
if err := testutil.GatherAndCompare(registry,
strings.NewReader(`
# HELP promtail_custom_longitude longitude GPS vehicule
# TYPE promtail_custom_longitude gauge
promtail_custom_longitude{test="app",vehicule="1"} -10.1234
`)); err != nil {
t.Fatalf("mismatch metrics: %v", err)
}
}

func TestPipelineWithMissingKey_Metrics(t *testing.T) {
var buf bytes.Buffer
w := log.NewSyncWriter(&buf)
Expand Down Expand Up @@ -267,8 +303,10 @@ func TestDefaultIdleDuration(t *testing.T) {
assert.Equal(t, int64(5*time.Minute.Seconds()), ms.(*stageProcessor).Processor.(*metricStage).cfg["total_keys"].maxIdleSec)
}

var labelFoo = model.LabelSet(map[model.LabelName]model.LabelValue{"foo": "bar", "bar": "foo"})
var labelFu = model.LabelSet(map[model.LabelName]model.LabelValue{"fu": "baz", "baz": "fu"})
var (
labelFoo = model.LabelSet(map[model.LabelName]model.LabelValue{"foo": "bar", "bar": "foo"})
labelFu = model.LabelSet(map[model.LabelName]model.LabelValue{"fu": "baz", "baz": "fu"})
)

func TestMetricStage_Process(t *testing.T) {
jsonConfig := JSONConfig{
Expand Down

0 comments on commit 89a38bd

Please sign in to comment.