Skip to content

Commit

Permalink
Agent Management: Introduce support for external labels in logs (#5786)
Browse files Browse the repository at this point in the history
- We currently support remotely managing external labels for metrics.
    This change adds support for logs as well.
  - Note: this change only applies to static mode.
  • Loading branch information
jcreixell authored Nov 16, 2023
1 parent ea7b005 commit 3831214
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ Main (unreleased)
- `otelcol.processor.filter` - filters OTLP telemetry data using OpenTelemetry
Transformation Language (OTTL). (@hainenber)

- Agent Management: Introduce support for remotely managed external labels for logs. (@jcreixell)

### Enhancements

- The `loki.write` WAL now has snappy compression enabled by default. (@thepalbi)
Expand Down
33 changes: 32 additions & 1 deletion pkg/config/agent_management_remote_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"time"

"github.com/grafana/agent/pkg/metrics/instance"
"github.com/prometheus/common/model"
"github.com/prometheus/prometheus/model/labels"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -199,19 +200,40 @@ server:
metrics:
global:
external_labels:
foo: bar`
foo: bar
logs:
global:
clients:
- external_labels:
foo: bar
`
rc := RemoteConfig{
BaseConfig: BaseConfigContent(baseConfig),
Snippets: allSnippets,
}
c, err := rc.BuildAgentConfig()
require.NoError(t, err)
require.Equal(t, 1, len(c.Logs.Configs))
require.Equal(t, 1, len(c.Logs.Global.ClientConfigs))
require.Equal(t, c.Logs.Global.ClientConfigs[0].ExternalLabels.LabelSet, model.LabelSet{"foo": "bar"})
require.Equal(t, 1, len(c.Metrics.Global.Prometheus.ExternalLabels))
require.Contains(t, c.Metrics.Global.Prometheus.ExternalLabels, labels.Label{Name: "foo", Value: "bar"})
})

t.Run("external labels provided", func(t *testing.T) {
baseConfig := `
server:
log_level: debug
metrics:
global:
remote_write:
- url: http://localhost:9090/api/prom/push
logs:
global:
clients:
- url: http://localhost:3100/loki/api/v1/push
`

rc := RemoteConfig{
BaseConfig: BaseConfigContent(baseConfig),
Snippets: allSnippets,
Expand All @@ -225,6 +247,8 @@ metrics:
require.NoError(t, err)
require.Equal(t, 1, len(c.Logs.Configs))
require.Equal(t, 1, len(c.Metrics.Configs))
require.Equal(t, 1, len(c.Logs.Global.ClientConfigs))
require.Equal(t, c.Logs.Global.ClientConfigs[0].ExternalLabels.LabelSet, model.LabelSet{"foo": "bar"})
require.Contains(t, c.Metrics.Global.Prometheus.ExternalLabels, labels.Label{Name: "foo", Value: "bar"})
})

Expand All @@ -236,6 +260,11 @@ metrics:
global:
external_labels:
foo: bar
logs:
global:
clients:
- external_labels:
foo: bar
`
rc := RemoteConfig{
BaseConfig: BaseConfigContent(baseConfig),
Expand All @@ -250,6 +279,8 @@ metrics:
require.NoError(t, err)
require.Equal(t, 1, len(c.Logs.Configs))
require.Equal(t, 1, len(c.Metrics.Configs))
require.Equal(t, 1, len(c.Logs.Global.ClientConfigs))
require.Equal(t, c.Logs.Global.ClientConfigs[0].ExternalLabels.LabelSet, model.LabelSet{"foo": "bar"})
require.Contains(t, c.Metrics.Global.Prometheus.ExternalLabels, labels.Label{Name: "foo", Value: "bar"})
require.NotContains(t, c.Metrics.Global.Prometheus.ExternalLabels, labels.Label{Name: "foo", Value: "baz"})
})
Expand Down
18 changes: 14 additions & 4 deletions pkg/config/agentmanagement_remote_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/grafana/agent/pkg/logs"
"github.com/grafana/agent/pkg/metrics/instance"
"github.com/grafana/loki/clients/pkg/promtail/scrapeconfig"
"github.com/prometheus/common/model"
pc "github.com/prometheus/prometheus/config"
"github.com/prometheus/prometheus/model/labels"
"gopkg.in/yaml.v2"
Expand Down Expand Up @@ -130,11 +131,20 @@ func appendExternalLabels(c *Config, externalLabels map[string]string) {
return
}
// Start off with the existing external labels, which will only be added to (not replaced)
newExternalLabels := c.Metrics.Global.Prometheus.ExternalLabels.Map()
metricsExternalLabels := c.Metrics.Global.Prometheus.ExternalLabels.Map()
for k, v := range externalLabels {
if _, ok := newExternalLabels[k]; !ok {
newExternalLabels[k] = v
if _, ok := metricsExternalLabels[k]; !ok {
metricsExternalLabels[k] = v
}
}
c.Metrics.Global.Prometheus.ExternalLabels = labels.FromMap(newExternalLabels)

logsExternalLabels := make(model.LabelSet)
for k, v := range externalLabels {
logsExternalLabels[model.LabelName(k)] = model.LabelValue(v)
}

c.Metrics.Global.Prometheus.ExternalLabels = labels.FromMap(metricsExternalLabels)
for i, cc := range c.Logs.Global.ClientConfigs {
c.Logs.Global.ClientConfigs[i].ExternalLabels.LabelSet = logsExternalLabels.Merge(cc.ExternalLabels.LabelSet)
}
}

0 comments on commit 3831214

Please sign in to comment.