Skip to content

Commit 1673648

Browse files
NR-288387 feat: config option to disable container decoration (#1888)
* NR-288387 feat: config option to disable container decoration * container sampler enabled if no config * remove deprecated macos GH runner * fix test in darwin
1 parent dc896c4 commit 1673648

File tree

11 files changed

+243
-13
lines changed

11 files changed

+243
-13
lines changed

.github/workflows/component_macos_harvest_test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
runs-on: ${{ matrix.os }}
1010
strategy:
1111
matrix:
12-
os: [ macos-11, macos-12 ]
12+
os: [ macos-12, macos-13, macos-14 ]
1313
steps:
1414
- uses: actions/checkout@v2
1515

.github/workflows/component_macos_linter.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ jobs:
77

88
run-lint:
99
name: Lint tests
10-
runs-on: macos-11
10+
runs-on: macos-latest
1111
continue-on-error: true
1212

1313
steps:

.github/workflows/component_macos_unit_test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ env:
99
jobs:
1010
unit-test-macos:
1111
name: unit tests
12-
runs-on: macos-11
12+
runs-on: macos-latest
1313

1414
steps:
1515
- uses: actions/checkout@v2

pkg/config/config.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,6 +1272,11 @@ type Config struct {
12721272
// Default (Windows): C:\ProgramData\New Relic\newrelic-infra\tmp
12731273
// Public: No
12741274
AgentTempDir string `envconfig:"agent_temp_dir" yaml:"agent_temp_dir"`
1275+
1276+
// ProcessContainerDecoration controls if the ProcessSample gets decorated with Container Information
1277+
// Default: true
1278+
// Public: Yes
1279+
ProcessContainerDecoration bool `envconfig:"process_container_decoration" yaml:"process_container_decoration"`
12751280
}
12761281

12771282
// KeyValMap is used whenever a key value pair configuration is required.
@@ -1896,6 +1901,7 @@ func NewConfig() *Config {
18961901
NtpMetrics: NewNtpConfig(),
18971902
Http: NewHttpConfig(),
18981903
AgentTempDir: defaultAgentTempDir,
1904+
ProcessContainerDecoration: defaultProcessContainerDecoration,
18991905
}
19001906
}
19011907

pkg/config/defaults.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ var (
113113
defaultNtpEnabled = false
114114
defaultNtpInterval = uint(15) // minutes
115115
defaultNtpTimeout = uint(5) // seconds
116+
defaultProcessContainerDecoration = true
116117
)
117118

118119
// Default internal values

pkg/metrics/process/sampler_darwin.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ type processSampler struct {
3030
var (
3131
_ sampler.Sampler = (*processSampler)(nil) // static interface assertion
3232
containerNotRunningErrs = map[string]struct{}{}
33+
containerSamplerGetter = metrics.GetContainerSamplers //nolint:gochecknoglobals
3334
)
3435

3536
// NewProcessSampler creates and returns a new process Sampler, given an agent context.
@@ -38,17 +39,22 @@ func NewProcessSampler(ctx agent.AgentContext) sampler.Sampler {
3839

3940
ttlSecs := config.DefaultContainerCacheMetadataLimit
4041
apiVersion := ""
41-
interval := config.FREQ_INTERVAL_FLOOR_PROCESS_METRICS
4242
dockerContainerdNamespace := ""
43+
interval := config.FREQ_INTERVAL_FLOOR_PROCESS_METRICS
44+
var containerSamplers []metrics.ContainerSampler
4345
if hasConfig {
4446
cfg := ctx.Config()
4547
ttlSecs = cfg.ContainerMetadataCacheLimit
4648
apiVersion = cfg.DockerApiVersion
4749
dockerContainerdNamespace = cfg.DockerContainerdNamespace
4850
interval = cfg.MetricsProcessSampleRate
4951
}
52+
53+
if (hasConfig && ctx.Config().ProcessContainerDecoration) || !hasConfig {
54+
containerSamplers = containerSamplerGetter(time.Duration(ttlSecs)*time.Second, apiVersion, dockerContainerdNamespace)
55+
}
56+
5057
harvester := newHarvester(ctx)
51-
containerSamplers := metrics.GetContainerSamplers(time.Duration(ttlSecs)*time.Second, apiVersion, dockerContainerdNamespace)
5258

5359
return &processSampler{
5460
harvest: harvester,

pkg/metrics/process/sampler_darwin_test.go

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ package process
44

55
import (
66
"errors"
7-
"testing"
8-
97
"github.com/newrelic/infrastructure-agent/pkg/metrics"
8+
"testing"
9+
"time"
1010

1111
"github.com/newrelic/infrastructure-agent/internal/agent/mocks"
1212
"github.com/newrelic/infrastructure-agent/pkg/config"
@@ -18,7 +18,7 @@ import (
1818
func TestProcessSampler_Sample(t *testing.T) {
1919
ctx := new(mocks.AgentContext)
2020
cfg := &config.Config{RunMode: config.ModeRoot}
21-
ctx.On("Config").Times(3).Return(cfg)
21+
ctx.On("Config").Times(4).Return(cfg)
2222

2323
harvester := &HarvesterMock{}
2424
sampler := NewProcessSampler(ctx).(*processSampler)
@@ -61,7 +61,7 @@ func TestProcessSampler_Sample(t *testing.T) {
6161
func TestProcessSampler_Sample_ErrorOnProcessShouldNotStop(t *testing.T) {
6262
ctx := new(mocks.AgentContext)
6363
cfg := &config.Config{RunMode: config.ModeRoot}
64-
ctx.On("Config").Times(3).Return(cfg)
64+
ctx.On("Config").Times(4).Return(cfg)
6565

6666
harvester := &HarvesterMock{}
6767
sampler := NewProcessSampler(ctx).(*processSampler)
@@ -108,7 +108,7 @@ func TestProcessSampler_Sample_ErrorOnProcessShouldNotStop(t *testing.T) {
108108
func TestProcessSampler_Sample_DockerDecorator(t *testing.T) {
109109
ctx := new(mocks.AgentContext)
110110
cfg := &config.Config{RunMode: config.ModeRoot}
111-
ctx.On("Config").Times(3).Return(cfg)
111+
ctx.On("Config").Times(4).Return(cfg)
112112

113113
harvester := &HarvesterMock{}
114114
sampler := NewProcessSampler(ctx).(*processSampler)
@@ -153,3 +153,63 @@ func TestProcessSampler_Sample_DockerDecorator(t *testing.T) {
153153

154154
mock.AssertExpectationsForObjects(t, ctx, harvester)
155155
}
156+
157+
//nolint:paralleltest
158+
func TestProcessSampler_Sample_DisabledDockerDecorator(t *testing.T) {
159+
ctx := new(mocks.AgentContext)
160+
cfg := config.NewConfig()
161+
cfg.ProcessContainerDecoration = false
162+
ctx.On("Config").Times(4).Return(cfg)
163+
164+
// The container sampler getter should not be called
165+
containerSamplerGetter = func(cacheTTL time.Duration, dockerAPIVersion, dockerContainerdNamespace string) []metrics.ContainerSampler {
166+
t.Errorf("containerSamplerGetter should not be called")
167+
168+
return nil
169+
}
170+
171+
defer func() {
172+
containerSamplerGetter = metrics.GetContainerSamplers
173+
}()
174+
175+
var expected []metrics.ContainerSampler
176+
sampler := NewProcessSampler(ctx).(*processSampler) //nolint:forcetypeassert
177+
assert.Equal(t, expected, sampler.containerSamplers)
178+
}
179+
180+
//nolint:paralleltest
181+
func TestProcessSampler_Sample_DockerDecoratorEnabledByDefault(t *testing.T) {
182+
ctx := new(mocks.AgentContext)
183+
cfg := config.NewConfig()
184+
ctx.On("Config").Times(4).Return(cfg)
185+
186+
containerSamplerGetter = func(cacheTTL time.Duration, dockerAPIVersion, dockerContainerdNamespace string) []metrics.ContainerSampler {
187+
return []metrics.ContainerSampler{&fakeContainerSampler{}}
188+
}
189+
190+
defer func() {
191+
containerSamplerGetter = metrics.GetContainerSamplers
192+
}()
193+
194+
expected := []metrics.ContainerSampler{&fakeContainerSampler{}}
195+
sampler := NewProcessSampler(ctx).(*processSampler) //nolint:forcetypeassert
196+
assert.Equal(t, expected, sampler.containerSamplers)
197+
}
198+
199+
//nolint:paralleltest
200+
func TestProcessSampler_Sample_DockerDecoratorEnabledWithNoConfig(t *testing.T) {
201+
ctx := new(mocks.AgentContext)
202+
ctx.On("Config").Times(2).Return(nil)
203+
204+
containerSamplerGetter = func(cacheTTL time.Duration, dockerAPIVersion, dockerContainerdNamespace string) []metrics.ContainerSampler {
205+
return []metrics.ContainerSampler{&fakeContainerSampler{}}
206+
}
207+
208+
defer func() {
209+
containerSamplerGetter = metrics.GetContainerSamplers
210+
}()
211+
212+
expected := []metrics.ContainerSampler{&fakeContainerSampler{}}
213+
sampler := NewProcessSampler(ctx).(*processSampler) //nolint:forcetypeassert
214+
assert.Equal(t, expected, sampler.containerSamplers)
215+
}

pkg/metrics/process/sampler_linux.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ type processSampler struct {
3131
var (
3232
_ sampler.Sampler = (*processSampler)(nil) // static interface assertion
3333
containerNotRunningErrs = map[string]struct{}{}
34+
containerSamplerGetter = metrics.GetContainerSamplers //nolint:gochecknoglobals
3435
)
3536

3637
// NewProcessSampler creates and returns a new process Sampler, given an agent context.
@@ -41,16 +42,21 @@ func NewProcessSampler(ctx agent.AgentContext) sampler.Sampler {
4142
apiVersion := ""
4243
dockerContainerdNamespace := ""
4344
interval := config.FREQ_INTERVAL_FLOOR_PROCESS_METRICS
45+
var containerSamplers []metrics.ContainerSampler
4446
if hasConfig {
4547
cfg := ctx.Config()
4648
ttlSecs = cfg.ContainerMetadataCacheLimit
4749
apiVersion = cfg.DockerApiVersion
4850
dockerContainerdNamespace = cfg.DockerContainerdNamespace
4951
interval = cfg.MetricsProcessSampleRate
5052
}
53+
54+
if (hasConfig && ctx.Config().ProcessContainerDecoration) || !hasConfig {
55+
containerSamplers = containerSamplerGetter(time.Duration(ttlSecs)*time.Second, apiVersion, dockerContainerdNamespace)
56+
}
57+
5158
cache := newCache()
5259
harvest := newHarvester(ctx, &cache)
53-
containerSamplers := metrics.GetContainerSamplers(time.Duration(ttlSecs)*time.Second, apiVersion, dockerContainerdNamespace)
5460

5561
return &processSampler{
5662
harvest: harvest,

pkg/metrics/process/sampler_linux_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"errors"
88
"fmt"
99
"testing"
10+
"time"
1011

1112
"github.com/stretchr/testify/assert"
1213
"github.com/stretchr/testify/mock"
@@ -67,6 +68,66 @@ func TestProcessSampler_DockerDecorator(t *testing.T) {
6768
}
6869
}
6970

71+
//nolint:paralleltest
72+
func TestProcessSampler_Sample_DisabledDockerDecorator(t *testing.T) {
73+
ctx := new(mocks.AgentContext)
74+
cfg := config.NewConfig()
75+
cfg.ProcessContainerDecoration = false
76+
ctx.On("Config").Times(4).Return(cfg)
77+
78+
// The container sampler getter should not be called
79+
containerSamplerGetter = func(cacheTTL time.Duration, dockerAPIVersion, dockerContainerdNamespace string) []metrics.ContainerSampler {
80+
t.Errorf("containerSamplerGetter should not be called")
81+
82+
return nil
83+
}
84+
85+
defer func() {
86+
containerSamplerGetter = metrics.GetContainerSamplers
87+
}()
88+
89+
var expected []metrics.ContainerSampler
90+
sampler := NewProcessSampler(ctx).(*processSampler) //nolint:forcetypeassert
91+
assert.Equal(t, expected, sampler.containerSamplers)
92+
}
93+
94+
//nolint:paralleltest
95+
func TestProcessSampler_Sample_DockerDecoratorEnabledByDefault(t *testing.T) {
96+
ctx := new(mocks.AgentContext)
97+
cfg := config.NewConfig()
98+
ctx.On("Config").Times(4).Return(cfg)
99+
100+
containerSamplerGetter = func(cacheTTL time.Duration, dockerAPIVersion, dockerContainerdNamespace string) []metrics.ContainerSampler {
101+
return []metrics.ContainerSampler{&fakeContainerSampler{}}
102+
}
103+
104+
defer func() {
105+
containerSamplerGetter = metrics.GetContainerSamplers
106+
}()
107+
108+
expected := []metrics.ContainerSampler{&fakeContainerSampler{}}
109+
sampler := NewProcessSampler(ctx).(*processSampler) //nolint:forcetypeassert
110+
assert.Equal(t, expected, sampler.containerSamplers)
111+
}
112+
113+
//nolint:paralleltest
114+
func TestProcessSampler_Sample_DockerDecoratorEnabledWithNoConfig(t *testing.T) {
115+
ctx := new(mocks.AgentContext)
116+
ctx.On("Config").Times(2).Return(nil)
117+
118+
containerSamplerGetter = func(cacheTTL time.Duration, dockerAPIVersion, dockerContainerdNamespace string) []metrics.ContainerSampler {
119+
return []metrics.ContainerSampler{&fakeContainerSampler{}}
120+
}
121+
122+
defer func() {
123+
containerSamplerGetter = metrics.GetContainerSamplers
124+
}()
125+
126+
expected := []metrics.ContainerSampler{&fakeContainerSampler{}}
127+
sampler := NewProcessSampler(ctx).(*processSampler) //nolint:forcetypeassert
128+
assert.Equal(t, expected, sampler.containerSamplers)
129+
}
130+
70131
type harvesterMock struct {
71132
samples map[int32]*types.ProcessSample
72133
}

pkg/metrics/procs_windows.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ var (
4040
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-queryfullprocessimagenamew
4141
queryFullProcessImageName = modkernel32.NewProc("QueryFullProcessImageNameW")
4242
containerNotRunningErrs = map[string]struct{}{}
43+
containerSamplerGetter = GetContainerSamplers //nolint:gochecknoglobals
4344
)
4445

4546
const (
@@ -347,7 +348,10 @@ func NewProcsMonitor(context agent.AgentContext) *ProcsMonitor {
347348
)
348349
ttlSecs := config.DefaultContainerCacheMetadataLimit
349350
getProcFunc := getWin32Proc
350-
if context != nil && context.Config() != nil {
351+
var containerSamplers []ContainerSampler
352+
hasConfig := context != nil && context.Config() != nil
353+
354+
if hasConfig {
351355
if len(context.Config().AllowedListProcessSample) > 0 {
352356
allowedListProcessing = true
353357
for _, processName := range context.Config().AllowedListProcessSample {
@@ -362,10 +366,15 @@ func NewProcsMonitor(context agent.AgentContext) *ProcsMonitor {
362366
getProcFunc = getWin32ProcFromWMI
363367
}
364368
}
369+
370+
if (hasConfig && context.Config().ProcessContainerDecoration) || !hasConfig {
371+
containerSamplers = containerSamplerGetter(time.Duration(ttlSecs)*time.Second, apiVersion, dockerContainerdNamespace)
372+
}
373+
365374
return &ProcsMonitor{
366375
context: context,
367376
procCache: make(map[string]*ProcessCacheEntry),
368-
containerSamplers: GetContainerSamplers(time.Duration(ttlSecs)*time.Second, apiVersion, dockerContainerdNamespace),
377+
containerSamplers: containerSamplers,
369378
previousProcessTimes: make(map[string]*SystemTimes),
370379
processInterrogator: NewInternalProcessInterrogator(true),
371380
waitForCleanup: &sync.WaitGroup{},

0 commit comments

Comments
 (0)