Skip to content

Commit

Permalink
[AlibabaCloudLogService] sanitize labels for metrics (#3454)
Browse files Browse the repository at this point in the history
* sanitize metric labels for AlibabaCloudLogService metrics (#3429)

* add new lines at end of file

* refine code

* refine code as review comments
  • Loading branch information
shabicheng authored Jun 1, 2021
1 parent 0bedbca commit 72257a4
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,13 @@ func (kv *KeyValues) Swap(i, j int) {
kv.keyValues[i], kv.keyValues[j] = kv.keyValues[j], kv.keyValues[i]
}
func (kv *KeyValues) Less(i, j int) bool { return kv.keyValues[i].Key < kv.keyValues[j].Key }
func (kv *KeyValues) Sort() { sort.Sort(kv) }

func (kv *KeyValues) Sort() {
sort.Sort(kv)
}

func (kv *KeyValues) Replace(key, value string) {
key = sanitize(key)
findIndex := sort.Search(len(kv.keyValues), func(index int) bool {
return kv.keyValues[index].Key >= key
})
Expand All @@ -64,14 +68,12 @@ func (kv *KeyValues) Replace(key, value string) {

func (kv *KeyValues) AppendMap(mapVal map[string]string) {
for key, value := range mapVal {
kv.keyValues = append(kv.keyValues, KeyValue{
Key: key,
Value: value,
})
kv.Append(key, value)
}
}

func (kv *KeyValues) Append(key, value string) {
key = sanitize(key)
kv.keyValues = append(kv.keyValues, KeyValue{
key,
value,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,16 @@ func TestMetricCornerCases(t *testing.T) {
})
assert.Equal(t, label.String(), "a#$#b")
}

func TestMetricLabelSanitize(t *testing.T) {
var label KeyValues
label.Append("_test", "key_test")
label.Append("0test", "key_0test")
label.AppendMap(map[string]string{
"test_normal": "test_normal",
"0test": "key_0test",
})
assert.Equal(t, label.String(), "key_test#$#key_test|key_0test#$#key_0test|test_normal#$#test_normal|key_0test#$#key_0test")
label.Sort()
assert.Equal(t, label.String(), "key_0test#$#key_0test|key_0test#$#key_0test|key_test#$#key_test|test_normal#$#test_normal")
}
52 changes: 52 additions & 0 deletions exporter/alibabacloudlogserviceexporter/sanitize.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright 2020, OpenTelemetry 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 alibabacloudlogserviceexporter

import (
"strings"
"unicode"
)

// The code for sanitize is mostly copied from:
// https://github.com/open-telemetry/opentelemetry-collector/blob/2e84285efc665798d76773b9901727e8836e9d8f/exporter/prometheusexporter/sanitize.go

// sanitize replaces non-alphanumeric characters with underscores in s.
func sanitize(s string) string {
if len(s) == 0 {
return s
}

// Note: No length limit for label keys because Prometheus doesn't
// define a length limit, thus we should NOT be truncating label keys.
// See https://github.com/orijtech/prometheus-go-metrics-exporter/issues/4.

s = strings.Map(sanitizeRune, s)
if unicode.IsDigit(rune(s[0])) {
s = "key_" + s
}
if s[0] == '_' {
s = "key" + s
}
return s
}

// converts anything that is not a letter or digit to an underscore
func sanitizeRune(r rune) rune {
if unicode.IsLetter(r) || unicode.IsDigit(r) {
return r
}
// Everything else turns into an underscore
return '_'
}
32 changes: 32 additions & 0 deletions exporter/alibabacloudlogserviceexporter/sanitize_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2020, OpenTelemetry 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 alibabacloudlogserviceexporter

import (
"testing"

"github.com/stretchr/testify/require"
)

// The code for sanitize is mostly copied from:
// https://github.com/open-telemetry/opentelemetry-collector/blob/2e84285efc665798d76773b9901727e8836e9d8f/exporter/prometheusexporter/sanitize_test.go

func TestSanitize(t *testing.T) {
require.Equal(t, "", sanitize(""), "")
require.Equal(t, "key_test", sanitize("_test"))
require.Equal(t, "key_0test", sanitize("0test"))
require.Equal(t, "test", sanitize("test"))
require.Equal(t, "test__", sanitize("test_/"))
}

0 comments on commit 72257a4

Please sign in to comment.