-
Notifications
You must be signed in to change notification settings - Fork 1
/
namer.go
104 lines (87 loc) · 2.18 KB
/
namer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package statsd
import (
"fmt"
"regexp"
"strings"
)
type namer struct {
namespace string
subsystem string
name string
nameFormat string
labelNames map[string]struct{}
}
func (n *namer) validateKey(name string) {
if _, ok := n.labelNames[name]; !ok {
panic("invalid label name: " + name)
}
}
func (n *namer) fullyQualifiedName() string {
switch {
case n.namespace != "" && n.subsystem != "":
return strings.Join([]string{n.namespace, n.subsystem, n.name}, ".")
case n.namespace != "":
return strings.Join([]string{n.namespace, n.name}, ".")
case n.subsystem != "":
return strings.Join([]string{n.subsystem, n.name}, ".")
default:
return n.name
}
}
func (n *namer) labelsToMap(labelValues []string) map[string]string {
labels := map[string]string{}
for i := 0; i < len(labelValues); i += 2 {
key := labelValues[i]
n.validateKey(key)
if i == len(labelValues)-1 {
labels[key] = "unknown"
} else {
labels[key] = labelValues[i+1]
}
}
return labels
}
var formatRegexp = regexp.MustCompile(`%{([#?[:alnum:]_]+)}`)
var invalidLabelValueRegexp = regexp.MustCompile(`[.|:\s]`)
func (n *namer) Format(labelValues ...string) string {
labels := n.labelsToMap(labelValues)
cursor := 0
var segments []string
matches := formatRegexp.FindAllStringSubmatchIndex(n.nameFormat, -1)
for _, m := range matches {
start, end := m[0], m[1]
labelStart, labelEnd := m[2], m[3]
if start > cursor {
segments = append(segments, n.nameFormat[cursor:start])
}
key := n.nameFormat[labelStart:labelEnd]
var value string
switch key {
case "#namespace":
value = n.namespace
case "#subsystem":
value = n.subsystem
case "#name":
value = n.name
case "#fqname":
value = n.fullyQualifiedName()
default:
var ok bool
value, ok = labels[key]
if !ok {
panic(fmt.Sprintf("invalid label in name format: %s", key))
}
value = invalidLabelValueRegexp.ReplaceAllString(value, "_")
}
segments = append(segments, value)
cursor = end
}
if cursor != len(n.nameFormat) {
segments = append(segments, n.nameFormat[cursor:])
}
return strings.Join(segments, "")
}