Merge pull request #315 from glightfoot/signalfx

[268] Support SignalFx Tags
This commit is contained in:
Matthias Rampke 2020-06-26 17:08:49 +02:00 committed by GitHub
commit 36de8c9e12
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 153 additions and 1 deletions

View file

@ -23,6 +23,7 @@ import (
"github.com/go-kit/kit/log" "github.com/go-kit/kit/log"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
dto "github.com/prometheus/client_model/go" dto "github.com/prometheus/client_model/go"
"github.com/prometheus/statsd_exporter/pkg/clock" "github.com/prometheus/statsd_exporter/pkg/clock"
"github.com/prometheus/statsd_exporter/pkg/event" "github.com/prometheus/statsd_exporter/pkg/event"
"github.com/prometheus/statsd_exporter/pkg/exporter" "github.com/prometheus/statsd_exporter/pkg/exporter"
@ -169,6 +170,76 @@ func TestHandlePacket(t *testing.T) {
CLabels: map[string]string{"tag1": "bar", "tag2": "baz"}, CLabels: map[string]string{"tag1": "bar", "tag2": "baz"},
}, },
}, },
}, {
name: "SignalFx tag extension",
in: "foo.[tag1=bar,tag2=baz]test:100|c",
out: event.Events{
&event.CounterEvent{
CMetricName: "foo.test",
CValue: 100,
CLabels: map[string]string{"tag1": "bar", "tag2": "baz"},
},
},
}, {
name: "SignalFx tag extension, tags at end of name",
in: "foo.test[tag1=bar,tag2=baz]:100|c",
out: event.Events{
&event.CounterEvent{
CMetricName: "foo.test",
CValue: 100,
CLabels: map[string]string{"tag1": "bar", "tag2": "baz"},
},
},
}, {
name: "SignalFx tag extension, tags at beginning of name",
in: "[tag1=bar,tag2=baz]foo.test:100|c",
out: event.Events{
&event.CounterEvent{
CMetricName: "foo.test",
CValue: 100,
CLabels: map[string]string{"tag1": "bar", "tag2": "baz"},
},
},
}, {
name: "SignalFx tag extension, no tags",
in: "foo.[]test:100|c",
out: event.Events{
&event.CounterEvent{
CMetricName: "foo.test",
CValue: 100,
CLabels: map[string]string{},
},
},
}, {
name: "SignalFx tag extension, non-kv tags",
in: "foo.[tag1,tag2]test:100|c",
out: event.Events{
&event.CounterEvent{
CMetricName: "foo.test",
CValue: 100,
CLabels: map[string]string{},
},
},
}, {
name: "SignalFx tag extension, missing closing bracket",
in: "[tag1=bar,tag2=bazfoo.test:100|c",
out: event.Events{
&event.CounterEvent{
CMetricName: "[tag1=bar,tag2=bazfoo.test",
CValue: 100,
CLabels: map[string]string{},
},
},
}, {
name: "SignalFx tag extension, missing opening bracket",
in: "tag1=bar,tag2=baz]foo.test:100|c",
out: event.Events{
&event.CounterEvent{
CMetricName: "tag1=bar,tag2=baz]foo.test",
CValue: 100,
CLabels: map[string]string{},
},
},
}, { }, {
name: "influxdb tag extension with tag keys unsupported by prometheus", name: "influxdb tag extension with tag keys unsupported by prometheus",
in: "foo,09digits=0,tag.with.dots=1:100|c", in: "foo,09digits=0,tag.with.dots=1:100|c",
@ -253,6 +324,10 @@ func TestHandlePacket(t *testing.T) {
name: "librato/dogstatsd mixed tag styles without sampling", name: "librato/dogstatsd mixed tag styles without sampling",
in: "foo#tag1=foo,tag3=bing:100|c|#tag1:bar,#tag2:baz", in: "foo#tag1=foo,tag3=bing:100|c|#tag1:bar,#tag2:baz",
out: event.Events{}, out: event.Events{},
}, {
name: "signalfx/dogstatsd mixed tag styles without sampling",
in: "foo[tag1=foo,tag3=bing]:100|c|#tag1:bar,#tag2:baz",
out: event.Events{},
}, { }, {
name: "influxdb/dogstatsd mixed tag styles without sampling", name: "influxdb/dogstatsd mixed tag styles without sampling",
in: "foo,tag1=foo,tag3=bing:100|c|#tag1:bar,#tag2:baz", in: "foo,tag1=foo,tag3=bing:100|c|#tag1:bar,#tag2:baz",

View file

@ -35,6 +35,7 @@ func benchmarkUDPListener(times int, b *testing.B) {
"foo6:100|c|#09digits:0,tag.with.dots:1", "foo6:100|c|#09digits:0,tag.with.dots:1",
"foo10:100|c|@0.1|#tag1:bar,#tag2:baz", "foo10:100|c|@0.1|#tag1:bar,#tag2:baz",
"foo11:100|c|@0.1|#tag1:foo:bar", "foo11:100|c|@0.1|#tag1:foo:bar",
"foo.[foo=bar,dim=val]test:1|g",
"foo15:200|ms:300|ms:5|c|@0.1:6|g\nfoo15a:1|c:5|ms", "foo15:200|ms:300|ms:5|c|@0.1:6|g\nfoo15a:1|c:5|ms",
"some_very_useful_metrics_with_quite_a_log_name:13|c", "some_very_useful_metrics_with_quite_a_log_name:13|c",
} }

57
line_benchmark_test.go Normal file
View file

@ -0,0 +1,57 @@
// Copyright 2020 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"testing"
"github.com/go-kit/kit/log"
"github.com/prometheus/statsd_exporter/pkg/line"
)
func benchmarkLineToEvents(times int, b *testing.B) {
input := []string{
"foo1:2|c",
"foo2:3|g",
"foo3:200|ms",
"foo4:100|c|#tag1:bar,tag2:baz",
"foo5:100|c|#tag1:bar,#tag2:baz",
"foo6:100|c|#09digits:0,tag.with.dots:1",
"foo10:100|c|@0.1|#tag1:bar,#tag2:baz",
"foo11:100|c|@0.1|#tag1:foo:bar",
"foo.[foo=bar,dim=val]test:1|g",
"foo15:200|ms:300|ms:5|c|@0.1:6|g\nfoo15a:1|c:5|ms",
"some_very_useful_metrics_with_quite_a_log_name:13|c",
}
logger := log.NewNopLogger()
for n := 0; n < b.N; n++ {
for i := 0; i < times; i++ {
for _, l := range input {
line.LineToEvents(l, *sampleErrors, samplesReceived, tagErrors, tagsReceived, logger)
}
}
}
}
func BenchmarkLineToEvents1(b *testing.B) {
benchmarkLineToEvents(1, b)
}
func BenchmarkLineToEvents5(b *testing.B) {
benchmarkLineToEvents(5, b)
}
func BenchmarkLineToEvents50(b *testing.B) {
benchmarkLineToEvents(50, b)
}

View file

@ -21,8 +21,8 @@ import (
"github.com/go-kit/kit/log" "github.com/go-kit/kit/log"
"github.com/go-kit/kit/log/level" "github.com/go-kit/kit/log/level"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/statsd_exporter/pkg/event" "github.com/prometheus/statsd_exporter/pkg/event"
"github.com/prometheus/statsd_exporter/pkg/mapper" "github.com/prometheus/statsd_exporter/pkg/mapper"
) )
@ -132,6 +132,25 @@ func ParseDogStatsDTags(component string, labels map[string]string, tagErrors pr
} }
func parseNameAndTags(name string, labels map[string]string, tagErrors prometheus.Counter, logger log.Logger) string { func parseNameAndTags(name string, labels map[string]string, tagErrors prometheus.Counter, logger log.Logger) string {
// check for SignalFx tags first
// `[` delimits start of tags by SignalFx
// `]` delimits end of tags by SignalFx
// https://docs.signalfx.com/en/latest/integrations/agent/monitors/collectd-statsd.html
startIdx := strings.IndexRune(name, '[')
endIdx := strings.IndexRune(name, ']')
switch {
case startIdx != -1 && endIdx != -1:
// good signalfx tags
parseNameTags(name[startIdx+1:endIdx], labels, tagErrors, logger)
return name[:startIdx] + name[endIdx+1:]
case (startIdx != -1) != (endIdx != -1):
// only one bracket, return unparsed
level.Debug(logger).Log("msg", "invalid SignalFx tags, not parsing", "metric", name)
tagErrors.Inc()
return name
}
for i, c := range name { for i, c := range name {
// `#` delimits start of tags by Librato // `#` delimits start of tags by Librato
// https://www.librato.com/docs/kb/collect/collection_agents/stastd/#stat-level-tags // https://www.librato.com/docs/kb/collect/collection_agents/stastd/#stat-level-tags