1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-02-03 13:11:53 +02:00

Make the default label encoding unique (#508)

* Make the default label encoding unique

* More tests

* Cleanup
This commit is contained in:
Joshua MacDonald 2020-03-04 14:19:25 -08:00 committed by GitHub
parent ffdbc05665
commit 148c9ce5ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 2 deletions

View File

@ -189,6 +189,29 @@ func TestSDKLabelEncoder(t *testing.T) {
func TestDefaultLabelEncoder(t *testing.T) {
encoder := sdk.NewDefaultLabelEncoder()
encoded := encoder.Encode([]core.KeyValue{key.String("A", "B"), key.String("C", "D")})
require.Equal(t, `A=B,C=D`, encoded)
encoded = encoder.Encode([]core.KeyValue{key.String("A", "B,c=d"), key.String(`C\`, "D")})
require.Equal(t, `A=B\,c\=d,C\\=D`, encoded)
encoded = encoder.Encode([]core.KeyValue{key.String(`\`, `=`), key.String(`,`, `\`)})
require.Equal(t, `\\=\=,\,=\\`, encoded)
// Note: the label encoder does not sort or de-dup values,
// that is done in Labels(...).
encoded = encoder.Encode([]core.KeyValue{
key.Int("I", 1),
key.Uint("U", 1),
key.Int32("I32", 1),
key.Uint32("U32", 1),
key.Int64("I64", 1),
key.Uint64("U64", 1),
key.Float64("F64", 1),
key.Float64("F64", 1),
key.String("S", "1"),
key.Bool("B", true),
})
require.Equal(t, "I=1,U=1,I32=1,U32=1,I64=1,U64=1,F64=1,F64=1,S=1,B=true", encoded)
}

View File

@ -22,6 +22,13 @@ import (
export "go.opentelemetry.io/otel/sdk/export/metric"
)
// escapeChar is used to ensure uniqueness of the label encoding where
// keys or values contain either '=' or ','. Since there is no parser
// needed for this encoding and its only requirement is to be unique,
// this choice is arbitrary. Users will see these in some exporters
// (e.g., stdout), so the backslash ('\') is used a conventional choice.
const escapeChar = '\\'
type defaultLabelEncoder struct {
// pool is a pool of labelset builders. The buffers in this
// pool grow to a size that most label encodings will not
@ -54,9 +61,25 @@ func (d *defaultLabelEncoder) Encode(labels []core.KeyValue) string {
if i > 0 {
_, _ = buf.WriteRune(',')
}
_, _ = buf.WriteString(string(kv.Key))
copyAndEscape(buf, string(kv.Key))
_, _ = buf.WriteRune('=')
_, _ = buf.WriteString(kv.Value.Emit())
if kv.Value.Type() == core.STRING {
copyAndEscape(buf, kv.Value.AsString())
} else {
_, _ = buf.WriteString(kv.Value.Emit())
}
}
return buf.String()
}
func copyAndEscape(buf *bytes.Buffer, val string) {
for _, ch := range val {
switch ch {
case '=', ',', escapeChar:
buf.WriteRune(escapeChar)
}
buf.WriteRune(ch)
}
}