Skip to content

Commit

Permalink
feat: filter out labels based on configuration
Browse files Browse the repository at this point in the history
Filter out labels that the Prometheus notifier sends based on
configuration. Atm the only label supported by this is "display_name".

https://issues.redhat.com/browse/HMS-3264

Signed-off-by: Petr Vobornik <[email protected]>
  • Loading branch information
pvoborni committed Dec 18, 2023
1 parent 5c2ce20 commit 1a948ff
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 4 deletions.
29 changes: 27 additions & 2 deletions notify/prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func prometheusRemoteWrite(httpClient *http.Client, cfg *config.Config, httpRequ

func newPrometheusRequest(hostinfo *hostinfo.HostInfo, cfg *config.Config, samples []prompb.Sample) (
*http.Request, error) {
writeRequest := hostInfo2WriteRequest(hostinfo, samples)
writeRequest := hostInfo2WriteRequest(hostinfo, samples, getLabelsToFilterOut(cfg))
logger.Debugf("WriteRequest: %s", writeRequest)
compressedData, err := writeRequest2Payload(writeRequest)
if err != nil {
Expand All @@ -142,6 +142,14 @@ func newPrometheusRequest(hostinfo *hostinfo.HostInfo, cfg *config.Config, sampl
return req, nil
}

func getLabelsToFilterOut(cfg *config.Config) []string {
labelsToFilterOut := make([]string, 0)
if cfg.SendHostname == config.SendHostnameNo {
labelsToFilterOut = append(labelsToFilterOut, "display_name")
}
return labelsToFilterOut
}

func filterEmptyLabels(labels []prompb.Label) []prompb.Label {
var result []prompb.Label
for _, label := range labels {
Expand All @@ -152,7 +160,23 @@ func filterEmptyLabels(labels []prompb.Label) []prompb.Label {
return result
}

func hostInfo2WriteRequest(hostinfo *hostinfo.HostInfo, samples []prompb.Sample) *prompb.WriteRequest {
func filterOutLabelsByName(labels []prompb.Label, toFilterOut []string) []prompb.Label {
labelSet := make(map[string]bool)
for _, label := range toFilterOut {
labelSet[label] = true
}

var result []prompb.Label
for _, label := range labels {
if !labelSet[label.Name] {
result = append(result, label)
}
}

return result
}

func hostInfo2WriteRequest(hostinfo *hostinfo.HostInfo, samples []prompb.Sample, labelsToFilterOut []string) *prompb.WriteRequest {
// Labels must be sorted by name
labels := []prompb.Label{
{
Expand Down Expand Up @@ -210,6 +234,7 @@ func hostInfo2WriteRequest(hostinfo *hostinfo.HostInfo, samples []prompb.Sample)
}

labels = filterEmptyLabels(labels)
labels = filterOutLabelsByName(labels, labelsToFilterOut)

writeRequest := &prompb.WriteRequest{
Timeseries: []prompb.TimeSeries{
Expand Down
102 changes: 100 additions & 2 deletions notify/prometheus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ func TestLabels(t *testing.T) {
// With full host info
hi := createHostInfo()
createRequestAndCheckLabels(t, samples, hi)
writeRequest := hostInfo2WriteRequest(hi, samples)
writeRequest := hostInfo2WriteRequest(hi, samples, []string{})
checkLabelsPresence(t, writeRequest.Timeseries[0].Labels, []string{
"__name__",
"_id",
Expand Down Expand Up @@ -321,8 +321,95 @@ func TestLabels(t *testing.T) {
createRequestAndCheckLabels(t, samples, hi)
}

func TestLableFiltering(t *testing.T) {
// given
samples := createSamples()
hi := createHostInfo()

// when
writeRequest := hostInfo2WriteRequest(hi, samples, []string{"display_name", "socket_count"})

// then
checkLablesNotPresent(t, writeRequest.Timeseries[0].Labels, []string{"display_name", "socket_count"})
}

func TestFilterOutLabelsByName(t *testing.T) {
// given
labels := []prompb.Label{
{Name: "__name__", Value: "system_cpu_logical_count"},
{Name: "_id", Value: "test"},
{Name: "billing_marketplace", Value: "test"},
}

// when
filtered := filterOutLabelsByName(labels, []string{"_id"})

// then
if len(filtered) != 2 {
t.Fatalf("Expected 2 labels, got %d", len(filtered))
}
if filtered[0].Name != "__name__" || filtered[1].Name != "billing_marketplace" {
t.Fatalf("Expected labels to be filtered out")
}
}

type GetLabelsToFilterOutTestCase struct {
name string
cfg *config.Config
expected []string
}

func TestGetLabelsToFilterOut(t *testing.T) {

testCases := []GetLabelsToFilterOutTestCase{
{
name: "No labels to filter out - Default",
cfg: &config.Config{},
expected: []string{},
},
{
name: "Filter out display name, send_hostname set to no",
cfg: &config.Config{
SendHostname: config.SendHostnameNo,
},
expected: []string{"display_name"},
},
{
name: "Nothing to filter out, send_hostname set to yes",
cfg: &config.Config{
SendHostname: config.SendHostnameYes,
},
expected: []string{},
},
{
name: "Nothing to filter out, send_hostname set unexpected value",
cfg: &config.Config{
SendHostname: "unexpected",
},
expected: []string{},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// when
labels := getLabelsToFilterOut(tc.cfg)

// then
if len(labels) != len(tc.expected) {
t.Fatalf("Expected %d labels, got %d: %s", len(tc.expected), len(labels), labels)
}
for i := range labels {
if labels[i] != tc.expected[i] {
t.Fatalf("Expected labels to be equal")
}
}
})
}
}

func createRequestAndCheckLabels(t *testing.T, samples []prompb.Sample, hostinfo *hostinfo.HostInfo) {
writeRequest := hostInfo2WriteRequest(hostinfo, samples)
writeRequest := hostInfo2WriteRequest(hostinfo, samples, []string{})
for _, ts := range writeRequest.Timeseries {
checkLabels(t, ts.Labels)
}
Expand Down Expand Up @@ -468,6 +555,17 @@ func checkLabelsPresence(t *testing.T, labels []prompb.Label, expected_names []s
}
}

func checkLablesNotPresent(t *testing.T, labels []prompb.Label, expected_missing []string) {
t.Helper()
for _, name := range expected_missing {
for _, label := range labels {
if label.Name == name {
t.Fatalf("Expected %s label to be missing", name)
}
}
}
}

// Data init functions

// Test uses tlsInsecureSkipVerify = true, e.g. for mock server with self-signed certificate
Expand Down

0 comments on commit 1a948ff

Please sign in to comment.