Skip to content
This repository has been archived by the owner on Jan 10, 2023. It is now read-only.

Commit

Permalink
sanitize label values for invalid utf-8
Browse files Browse the repository at this point in the history
  • Loading branch information
tivvit committed May 20, 2020
1 parent 6cb4313 commit bc6cb05
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 3 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ require (
github.com/prometheus/procfs v0.0.0-20190519111021-9935e8e0588d // indirect
github.com/yuin/gopher-lua v0.0.0-20181214045814-db9ae37725ec // indirect
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 // indirect
golang.org/x/text v0.3.0
)
21 changes: 20 additions & 1 deletion metric.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"log"
"strconv"
"strings"
"unicode/utf8"

"github.com/prometheus/client_golang/prometheus"
)
Expand Down Expand Up @@ -45,6 +46,10 @@ func infoCollect(
) []prometheus.Metric {
var res []prometheus.Metric
stats := parseInfo(info)
validLabelValues := make([]string, len(labelValues))
for pos, lv := range labelValues {
validLabelValues[pos] = sanitizeLabelValue(lv)
}
for key, m := range metrics {
v, ok := stats[key]
if !ok {
Expand All @@ -58,12 +63,26 @@ func infoCollect(
}
res = append(
res,
prometheus.MustNewConstMetric(m.desc, m.typ, f, labelValues...),
prometheus.MustNewConstMetric(m.desc, m.typ, f, validLabelValues...),
)
}
return res
}

func sanitizeLabelValue(lv string) string {
if utf8.ValidString(lv) {
return lv
}
fixUtf := func(r rune) rune {
if r == utf8.RuneError {
return 65533
}
return r
}

return strings.Map(fixUtf, lv)
}

func parseInfo(s string) map[string]string {
r := map[string]string{}
for _, l := range strings.Split(s, ";") {
Expand Down
37 changes: 35 additions & 2 deletions metric_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func TestInfoCollect(t *testing.T) {
payload string
field string
metric cmetric
labels []string
want string
}
for n, c := range []cas{
Expand Down Expand Up @@ -103,9 +104,41 @@ func TestInfoCollect(t *testing.T) {
},
want: `gauge:<value:1 > `,
},
{
payload: "counter-1=3.14:gauge-1=6.12:flag=true:counter-2=6.66",
field: "flag",
metric: cmetric{
typ: prometheus.GaugeValue,
desc: prometheus.NewDesc(
"c1",
"My second flag",
[]string{"namespace", "set"},
nil,
),
},
//labels: []string{"ns", ""},
labels: []string{"ns", "\xC0"},
want: `label:<name:"namespace" value:"ns" > label:<name:"set" value:"\357\277\275" > gauge:<value:1 > `,
},
{
payload: "counter-1=3.14:gauge-1=6.12:flag=true:counter-2=6.66",
field: "flag",
metric: cmetric{
typ: prometheus.GaugeValue,
desc: prometheus.NewDesc(
"c1",
"My second flag",
[]string{"namespace", "set"},
nil,
),
},
//labels: []string{"ns", ""},
labels: []string{"ns", "ӕ"},
want: `label:<name:"namespace" value:"ns" > label:<name:"set" value:"\323\225" > gauge:<value:1 > `,
},
} {
metrics := cmetrics{c.field: c.metric}
ms := infoCollect(metrics, c.payload)
ms := infoCollect(metrics, c.payload, c.labels...)

if have, want := len(ms), 1; have != want {
t.Fatalf("have %d, want %d", have, want)
Expand All @@ -117,4 +150,4 @@ func TestInfoCollect(t *testing.T) {
t.Errorf("case %d: have %q, want %q", n, have, want)
}
}
}
}

0 comments on commit bc6cb05

Please sign in to comment.