-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable sending host tags with metrics for a configurable duration #22467
Changes from all commits
bfbda6d
688c745
f075426
32258e5
d7c2377
6f36263
5477b01
7ca0cdb
b4eef0b
f32e80f
6fac038
3b16d78
7a4adc2
fd5dda0
c80632c
ddf16a0
09da2f9
e85d769
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
// Unless explicitly stated otherwise all files in this repository are licensed | ||
// under the Apache License Version 2.0. | ||
// This product includes software developed at Datadog (https://www.datadoghq.com/). | ||
// Copyright 2016-present Datadog, Inc. | ||
|
||
// Package host implements the host tag Workloadmeta collector. | ||
package host | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/benbjohnson/clock" | ||
|
||
"github.com/DataDog/datadog-agent/comp/core/config" | ||
"github.com/DataDog/datadog-agent/comp/core/workloadmeta" | ||
hostMetadataUtils "github.com/DataDog/datadog-agent/comp/metadata/host/hostimpl/hosttags" | ||
"github.com/DataDog/datadog-agent/pkg/util/log" | ||
|
||
"go.uber.org/fx" | ||
) | ||
|
||
const id = "host" | ||
|
||
type dependencies struct { | ||
fx.In | ||
|
||
Config config.Component | ||
} | ||
|
||
type collector struct { | ||
store workloadmeta.Component | ||
catalog workloadmeta.AgentType | ||
config config.Component | ||
clock clock.Clock | ||
timeoutTimer *clock.Timer | ||
} | ||
|
||
// GetFxOptions returns the FX framework options for the collector | ||
func GetFxOptions() fx.Option { | ||
return fx.Provide(NewCollector) | ||
} | ||
|
||
// NewCollector returns a new host collector provider and an error | ||
func NewCollector(deps dependencies) (workloadmeta.CollectorProvider, error) { | ||
return workloadmeta.CollectorProvider{ | ||
Collector: &collector{ | ||
catalog: workloadmeta.NodeAgent | workloadmeta.ProcessAgent, | ||
config: deps.Config, | ||
clock: clock.New(), | ||
}, | ||
}, nil | ||
} | ||
|
||
func (c *collector) Start(_ context.Context, store workloadmeta.Component) error { | ||
|
||
c.store = store | ||
|
||
duration := c.config.GetDuration("expected_tags_duration") | ||
if duration <= 0 { | ||
return nil | ||
} | ||
|
||
log.Debugf("Adding host tags to metrics for %v", duration) | ||
c.timeoutTimer = c.clock.Timer(duration) | ||
|
||
return nil | ||
} | ||
|
||
func (c *collector) Pull(ctx context.Context) error { | ||
// Feature is disabled or timeout has previously occurred | ||
if c.timeoutTimer == nil { | ||
return nil | ||
} | ||
|
||
// Timeout reached - expire any host tags in the store | ||
if c.resetTimerIfTimedOut() { | ||
c.store.Notify(makeEvent([]string{})) | ||
return nil | ||
} | ||
|
||
tags := hostMetadataUtils.Get(ctx, false, c.config).System | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. quick question hostmetadata package is not a component yet? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Host metadata is - but this function still depends on a bunch of non-component bits. So I assume that's the reason it has not yet been converted. |
||
c.store.Notify(makeEvent(tags)) | ||
return nil | ||
} | ||
|
||
func (c *collector) GetID() string { | ||
return id | ||
} | ||
|
||
func (c *collector) GetTargetCatalog() workloadmeta.AgentType { | ||
return c.catalog | ||
} | ||
|
||
func (c *collector) resetTimerIfTimedOut() bool { | ||
select { | ||
case <-c.timeoutTimer.C: | ||
c.timeoutTimer = nil | ||
return true | ||
default: | ||
return false | ||
} | ||
} | ||
|
||
func makeEvent(tags []string) []workloadmeta.CollectorEvent { | ||
return []workloadmeta.CollectorEvent{ | ||
{ | ||
Type: workloadmeta.EventTypeSet, | ||
Source: workloadmeta.SourceHost, | ||
Entity: &workloadmeta.HostTags{ | ||
EntityID: workloadmeta.EntityID{ | ||
Kind: workloadmeta.KindHost, | ||
ID: id, | ||
}, | ||
HostTags: tags, | ||
}, | ||
}} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// Unless explicitly stated otherwise all files in this repository are licensed | ||
// under the Apache License Version 2.0. | ||
// This product includes software developed at Datadog (https://www.datadoghq.com/). | ||
// Copyright 2016-present Datadog, Inc. | ||
|
||
// Package host implements the host tag Workloadmeta collector. | ||
package host | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
"time" | ||
|
||
"github.com/benbjohnson/clock" | ||
"github.com/stretchr/testify/assert" | ||
|
||
"github.com/DataDog/datadog-agent/comp/core" | ||
"github.com/DataDog/datadog-agent/comp/core/config" | ||
"github.com/DataDog/datadog-agent/comp/core/workloadmeta" | ||
"github.com/DataDog/datadog-agent/pkg/util/fxutil" | ||
|
||
"go.uber.org/fx" | ||
) | ||
|
||
type testDeps struct { | ||
fx.In | ||
|
||
Config config.Component | ||
Wml workloadmeta.Mock | ||
} | ||
|
||
func TestHostCollector(t *testing.T) { | ||
expectedTags := []string{"tag1:value1", "tag2", "tag3"} | ||
ctx := context.TODO() | ||
|
||
overrides := map[string]interface{}{ | ||
"tags": expectedTags, | ||
"expected_tags_duration": "10m", | ||
} | ||
|
||
deps := fxutil.Test[testDeps](t, fx.Options( | ||
fx.Replace(config.MockParams{Overrides: overrides}), | ||
core.MockBundle(), | ||
fx.Supply(workloadmeta.NewParams()), | ||
fx.Supply(context.Background()), | ||
workloadmeta.MockModule(), | ||
)) | ||
|
||
eventChan := deps.Wml.SubscribeToEvents() | ||
|
||
mockClock := clock.NewMock() | ||
c := collector{ | ||
config: deps.Config, | ||
clock: mockClock, | ||
} | ||
|
||
c.Start(ctx, deps.Wml) | ||
c.Pull(ctx) | ||
|
||
assertTags(t, (<-eventChan).Entity, expectedTags) | ||
|
||
mockClock.Add(11 * time.Minute) | ||
mockClock.WaitForAllTimers() | ||
c.Pull(ctx) | ||
|
||
assertTags(t, (<-eventChan).Entity, []string{}) | ||
} | ||
|
||
func assertTags(t *testing.T, entity workloadmeta.Entity, expectedTags []string) { | ||
e := entity.(*workloadmeta.HostTags) | ||
assert.ElementsMatch(t, e.HostTags, expectedTags) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there was a warning here telling users that they set the duration too low. Was that not useful?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 1 min constraint is no longer relevant with the new design. I suppose I could add back a warning about it being
< 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually there was no warning about it being
<= 0
before.