Skip to content

Commit

Permalink
integrations-next: Add extra_labels to inject extra labels for an int…
Browse files Browse the repository at this point in the history
…egration (grafana#1312)

* integrations-next: Add extra_labels to inject extra labels for an integration.

* separate tests
  • Loading branch information
rfratto committed Jan 25, 2022
1 parent 4fc6c0f commit 089e77e
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

- [ENHANCEMENT] Go 1.17 is now used for all builds of the Agent. (@tpaschalis)

- [ENHANCEMENT] integrations-next: Add `extra_labels` to add a custom set of
labels to integration targets. (@rfratto)

- [BUGFIX] Fixed issue where Grafana Agent may panic if there is a very large
WAL loading while old WALs are being deleted or the `/agent/api/v1/targets`
endpoint is called. (@tpaschalis)
Expand Down
7 changes: 7 additions & 0 deletions docs/configuration/integrations/integrations-next/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,13 @@ autoscrape:
# Autoscrape interval and timeout.
[scrape_interval: <duration> | default = <integrations.metrics.autoscrape.scrape_interval>]
[scrape_timeout: <duration> | default = <integrations.metrics.autoscrape.scrape_timeout>]

# An optional extra set of labels to add to metrics from the integration target. These
# labels are only exposed via the integration service discovery HTTP API and
# added when autoscrape is used. They will not be found directly on the metrics
# page for an integration.
extra_labels:
[ <labelname>: <labelvalue> ... ]
```

The old set of common options have been removed and do not work when the revamp
Expand Down
2 changes: 2 additions & 0 deletions pkg/integrations/v2/common/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package common

import (
"github.com/grafana/agent/pkg/integrations/v2/autoscrape"
"github.com/prometheus/prometheus/pkg/labels"
)

// MetricsConfig is a set of common options shared by metrics integrations. It
Expand All @@ -14,6 +15,7 @@ import (
type MetricsConfig struct {
Autoscrape autoscrape.Config `yaml:"autoscrape,omitempty"`
InstanceKey *string `yaml:"instance,omitempty"`
ExtraLabels labels.Labels `yaml:"extra_labels,omitempty"`
}

// ApplyDefaults applies defaults to mc.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ func (i *metricsHandlerIntegration) Targets(ep integrations.Endpoint) []*targetg
Source: fmt.Sprintf("%s/%s", i.integrationName, i.instanceID),
}

for _, lbl := range i.common.ExtraLabels {
group.Labels[model.LabelName(lbl.Name)] = model.LabelValue(lbl.Value)
}

for _, t := range i.targets {
group.Targets = append(group.Targets, model.LabelSet{
model.AddressLabel: model.LabelValue(ep.Host),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package metricsutils

import (
"fmt"
"net/http"
"net/url"
"testing"

"github.com/go-kit/log"
"github.com/grafana/agent/pkg/integrations/v2"
"github.com/grafana/agent/pkg/integrations/v2/common"
"github.com/prometheus/common/model"
"github.com/prometheus/prometheus/discovery/targetgroup"
"github.com/prometheus/prometheus/pkg/labels"
"github.com/stretchr/testify/require"
)

func TestMetricsHandlerIntegration_Targets(t *testing.T) {
globals := integrations.Globals{
AgentIdentifier: "testagent",
AgentBaseURL: func() *url.URL {
u, err := url.Parse("http://testagent/")
require.NoError(t, err)
return u
}(),
SubsystemOpts: integrations.DefaultSubsystemOptions,
}

t.Run("Targets", func(t *testing.T) {
var cfg common.MetricsConfig
cfg.ApplyDefaults(globals.SubsystemOpts.Metrics.Autoscrape)

i, err := NewMetricsHandlerIntegration(nil, fakeConfig{}, cfg, globals, http.NotFoundHandler())
require.NoError(t, err)

actual := i.Targets(integrations.Endpoint{Host: "test", Prefix: "/test/"})
expect := []*targetgroup.Group{{
Source: "fake/testagent",
Labels: model.LabelSet{
"instance": "testagent",
"job": "integrations/fake",
"agent_hostname": "testagent",

"__meta_agent_integration_name": "fake",
"__meta_agent_integration_instance": "testagent",
"__meta_agent_integration_autoscrape": "1",
},
Targets: []model.LabelSet{{
"__address__": "test",
"__metrics_path__": "/test/metrics",
}},
}}
require.Equal(t, expect, actual)

t.Run("Extra labels", func(t *testing.T) {
cfg := common.MetricsConfig{
ExtraLabels: labels.FromMap(map[string]string{"foo": "bar", "fizz": "buzz"}),
}
cfg.ApplyDefaults(globals.SubsystemOpts.Metrics.Autoscrape)

i, err := NewMetricsHandlerIntegration(nil, fakeConfig{}, cfg, globals, http.NotFoundHandler())
require.NoError(t, err)
actual := i.Targets(integrations.Endpoint{Host: "test", Prefix: "/test/"})
require.Len(t, actual, 1)

for _, lbl := range cfg.ExtraLabels {
val, ok := actual[0].Labels[model.LabelName(lbl.Name)]
require.True(t, ok, "target does not have extra label %s", lbl.Name)
require.Equal(t, lbl.Value, string(val), "extra label %s does not match expectation", lbl.Name)
}
})
})
}

type fakeConfig struct{}

func (fakeConfig) Name() string { return "fake" }
func (fakeConfig) ApplyDefaults(_ integrations.Globals) error { return nil }
func (fakeConfig) Identifier(g integrations.Globals) (string, error) { return g.AgentIdentifier, nil }
func (fakeConfig) NewIntegration(_ log.Logger, _ integrations.Globals) (integrations.Integration, error) {
return nil, fmt.Errorf("not implemented")
}

0 comments on commit 089e77e

Please sign in to comment.