fix(outputs.nebius_cloud_monitoring): Replace reserved label names (#13597)
Co-authored-by: Thomas Casteleyn <thomas.casteleyn@me.com>
This commit is contained in:
parent
8cde34bfeb
commit
36709713e1
|
|
@ -34,3 +34,55 @@ Folder ID from instance metadata. In this plugin we use [Google Cloud notation]
|
|||
This internal metadata endpoint is only accessible for VMs from the cloud.
|
||||
|
||||
[Google Cloud notation]: https://nebius.com/il/docs/compute/operations/vm-info/get-info#gce-metadata
|
||||
|
||||
### Reserved Labels
|
||||
|
||||
Nebius Monitoring backend using json format to receive the metrics:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "metric_name",
|
||||
"labels": {
|
||||
"key": "value",
|
||||
"foo": "bar"
|
||||
},
|
||||
"ts": "2023-06-06T11:10:50Z",
|
||||
"value": 0
|
||||
}
|
||||
```
|
||||
|
||||
But key of label cannot be `name` because it's reserved for `metric_name`.
|
||||
|
||||
So this payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "systemd_units_load_code",
|
||||
"labels": {
|
||||
"active": "active",
|
||||
"host": "vm",
|
||||
"load": "loaded",
|
||||
"name": "accounts-daemon.service",
|
||||
"sub": "running"
|
||||
},
|
||||
"ts": "2023-06-06T11:10:50Z",
|
||||
"value": 0
|
||||
}
|
||||
```
|
||||
|
||||
will be replaced with:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "systemd_units_load_code",
|
||||
"labels": {
|
||||
"active": "active",
|
||||
"host": "vm",
|
||||
"load": "loaded",
|
||||
"_name": "accounts-daemon.service",
|
||||
"sub": "running"
|
||||
},
|
||||
"ts": "2023-06-06T11:10:50Z",
|
||||
"value": 0
|
||||
}
|
||||
```
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ func (a *NebiusCloudMonitoring) Write(metrics []telegraf.Metric) error {
|
|||
nebiusCloudMonitoringMetrics,
|
||||
nebiusCloudMonitoringMetric{
|
||||
Name: m.Name() + "_" + field.Key,
|
||||
Labels: m.Tags(),
|
||||
Labels: replaceReservedTagNames(m.Tags()),
|
||||
TS: m.Time().Format(time.RFC3339),
|
||||
Value: value,
|
||||
},
|
||||
|
|
@ -242,3 +242,15 @@ func init() {
|
|||
return &NebiusCloudMonitoring{}
|
||||
})
|
||||
}
|
||||
|
||||
func replaceReservedTagNames(tagNames map[string]string) map[string]string {
|
||||
newTags := make(map[string]string, len(tagNames))
|
||||
for tagName, tagValue := range tagNames {
|
||||
if tagName == "name" {
|
||||
newTags["_name"] = tagValue
|
||||
} else {
|
||||
newTags[tagName] = tagValue
|
||||
}
|
||||
}
|
||||
return newTags
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,6 +119,31 @@ func TestWrite(t *testing.T) {
|
|||
w.WriteHeader(http.StatusOK)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "label with name 'name' is replaced with '_name'",
|
||||
plugin: &NebiusCloudMonitoring{},
|
||||
metrics: []telegraf.Metric{
|
||||
testutil.MustMetric(
|
||||
"cluster",
|
||||
map[string]string{
|
||||
"name": "accounts-daemon.service",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"value": 9226,
|
||||
},
|
||||
time.Unix(0, 0),
|
||||
),
|
||||
},
|
||||
handler: func(t *testing.T, w http.ResponseWriter, r *http.Request) {
|
||||
message, err := readBody(r)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, message.Metrics, 1)
|
||||
require.Equal(t, "cluster_value", message.Metrics[0].Name)
|
||||
require.Contains(t, message.Metrics[0].Labels, "_name")
|
||||
require.Equal(t, float64(9226), message.Metrics[0].Value)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
|
@ -137,3 +162,37 @@ func TestWrite(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestReplaceReservedTagNames(t *testing.T) {
|
||||
tagMap := map[string]string{
|
||||
"name": "value",
|
||||
"other": "value",
|
||||
}
|
||||
wantTagMap := map[string]string{
|
||||
"_name": "value",
|
||||
"other": "value",
|
||||
}
|
||||
|
||||
type args struct {
|
||||
tagNames map[string]string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want map[string]string
|
||||
}{
|
||||
{
|
||||
name: "tagReplacement",
|
||||
args: args{
|
||||
tagNames: tagMap,
|
||||
},
|
||||
want: wantTagMap,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := replaceReservedTagNames(tt.args.tagNames)
|
||||
require.EqualValues(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue