diff --git a/internal/runtime/foreach_metrics_test.go b/internal/runtime/foreach_metrics_test.go deleted file mode 100644 index 38e1fb06aa..0000000000 --- a/internal/runtime/foreach_metrics_test.go +++ /dev/null @@ -1,29 +0,0 @@ -package runtime_test - -import ( - "os" - "path/filepath" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestForeachMetrics(t *testing.T) { - directory := "./testdata/foreach_metrics" - for _, file := range getTestFiles(directory, t) { - tc := buildTestForEach(t, filepath.Join(directory, file.Name())) - t.Run(tc.description, func(t *testing.T) { - if tc.module != "" { - defer os.Remove("module.alloy") - require.NoError(t, os.WriteFile("module.alloy", []byte(tc.module), 0664)) - } - if tc.update != nil { - testConfigForEach(t, tc.main, tc.reloadConfig, func() { - require.NoError(t, os.WriteFile(tc.update.name, []byte(tc.update.updateConfig), 0664)) - }, tc.expectedMetrics, tc.expectedDurationMetrics) - } else { - testConfigForEach(t, tc.main, tc.reloadConfig, nil, tc.expectedMetrics, tc.expectedDurationMetrics) - } - }) - } -} diff --git a/internal/runtime/foreach_test.go b/internal/runtime/foreach_test.go index 16ea85e9ef..b5a76c18b4 100644 --- a/internal/runtime/foreach_test.go +++ b/internal/runtime/foreach_test.go @@ -39,6 +39,26 @@ func TestForeach(t *testing.T) { } } +func TestForeachMetrics(t *testing.T) { + directory := "./testdata/foreach_metrics" + for _, file := range getTestFiles(directory, t) { + tc := buildTestForEach(t, filepath.Join(directory, file.Name())) + t.Run(tc.description, func(t *testing.T) { + if tc.module != "" { + defer os.Remove("module.alloy") + require.NoError(t, os.WriteFile("module.alloy", []byte(tc.module), 0664)) + } + if tc.update != nil { + testConfigForEach(t, tc.main, tc.reloadConfig, func() { + require.NoError(t, os.WriteFile(tc.update.name, []byte(tc.update.updateConfig), 0664)) + }, tc.expectedMetrics, tc.expectedDurationMetrics) + } else { + testConfigForEach(t, tc.main, tc.reloadConfig, nil, tc.expectedMetrics, tc.expectedDurationMetrics) + } + }) + } +} + type testForEachFile struct { description string // description at the top of the txtar file main string // root config that the controller should load @@ -115,11 +135,9 @@ func testConfigForEach(t *testing.T, config string, reloadConfig string, update "alloy_component_evaluation_seconds", } - if countedMetrics, err := testutil.GatherAndCount(reg, metricsToCheck...); err != nil { - require.NoError(t, err) - } else { - require.Equal(t, *expectedDurationMetrics, countedMetrics) - } + countedMetrics, err := testutil.GatherAndCount(reg, metricsToCheck...) + require.NoError(t, err) + require.Equal(t, *expectedDurationMetrics, countedMetrics) } if expectedMetrics != nil { @@ -132,9 +150,8 @@ func testConfigForEach(t *testing.T, config string, reloadConfig string, update "pulse_count", } - if err := testutil.GatherAndCompare(reg, strings.NewReader(*expectedMetrics), metricsToCheck...); err != nil { - require.NoError(t, err) - } + err := testutil.GatherAndCompare(reg, strings.NewReader(*expectedMetrics), metricsToCheck...) + require.NoError(t, err) } if update != nil { diff --git a/internal/runtime/internal/controller/node_config_foreach.go b/internal/runtime/internal/controller/node_config_foreach.go index b613438031..1a85074d65 100644 --- a/internal/runtime/internal/controller/node_config_foreach.go +++ b/internal/runtime/internal/controller/node_config_foreach.go @@ -118,9 +118,13 @@ func (fn *ForeachConfigNode) ID() ComponentID { // Foreach doesn't have the ability to export values. // This is something we could implement in the future if there is a need for it. type Arguments struct { - Collection []any `alloy:"collection,attr"` - Var string `alloy:"var,attr"` - EnableMetrics bool `alloy:"enable_metrics,attr,optional"` + Collection []any `alloy:"collection,attr"` + Var string `alloy:"var,attr"` + + // enable_metrics should be false by default. + // That way users are protected from an explosion of debug metrics + // if there are many items inside "collection". + EnableMetrics bool `alloy:"enable_metrics,attr,optional"` } func (fn *ForeachConfigNode) Evaluate(evalScope *vm.Scope) error { diff --git a/internal/runtime/internal/testcomponents/pulse.go b/internal/runtime/internal/testcomponents/pulse.go index d66f1520ae..20876a2761 100644 --- a/internal/runtime/internal/testcomponents/pulse.go +++ b/internal/runtime/internal/testcomponents/pulse.go @@ -76,6 +76,7 @@ func (p *Pulse) Run(ctx context.Context) error { for _, r := range p.cfg.ForwardTo { r.ReceiveInt(1) } + p.pulseCount.Inc() p.count++ } p.cfgMut.Unlock() diff --git a/internal/runtime/testdata/foreach_metrics/foreach_1.txtar b/internal/runtime/testdata/foreach_metrics/foreach_1.txtar index f0479ea278..67bd58b01d 100644 --- a/internal/runtime/testdata/foreach_metrics/foreach_1.txtar +++ b/internal/runtime/testdata/foreach_metrics/foreach_1.txtar @@ -1,4 +1,5 @@ -Foreach with only one item. The pulse will send "1" to the receiver of the summation component until it reaches 10. +Test to make sure debug metrics are disabled by default for foreach. +Use a foreach with only one item. The pulse will send "1" to the receiver of the summation component until it reaches 10. -- main.alloy -- foreach "testForeach" { diff --git a/internal/runtime/testdata/foreach_metrics/foreach_2.txtar b/internal/runtime/testdata/foreach_metrics/foreach_2.txtar index 36112fe6bc..b8894cc32c 100644 --- a/internal/runtime/testdata/foreach_metrics/foreach_2.txtar +++ b/internal/runtime/testdata/foreach_metrics/foreach_2.txtar @@ -1,3 +1,4 @@ +Test to make sure debug metrics for foreach are shown when they are enabled explicitly. Foreach with only one item. The pulse will send "1" to the receiver of the summation component until it reaches 10. -- main.alloy -- @@ -35,7 +36,7 @@ alloy_component_evaluation_queue_size{controller_id="",controller_path="/"} 1 alloy_component_evaluation_queue_size{controller_id="foreach_10_1",controller_path="/foreach.testForeach"} 0 # HELP pulse_count # TYPE pulse_count counter -pulse_count{component_id="testcomponents.pulse.pt",component_path="/foreach.testForeach/foreach_10_1"} 0 +pulse_count{component_id="testcomponents.pulse.pt",component_path="/foreach.testForeach/foreach_10_1"} 10 -- expected_duration_metrics.prom -- diff --git a/internal/runtime/testdata/foreach_metrics/foreach_3.txtar b/internal/runtime/testdata/foreach_metrics/foreach_3.txtar new file mode 100644 index 0000000000..06809a3dd7 --- /dev/null +++ b/internal/runtime/testdata/foreach_metrics/foreach_3.txtar @@ -0,0 +1,46 @@ +This test uses two different items in the collection. + +-- main.alloy -- +foreach "testForeach" { + collection = [6,4] + var = "num" + enable_metrics = true + + template { + testcomponents.pulse "pt" { + max = num + frequency = "10ms" + forward_to = [testcomponents.summation_receiver.sum.receiver] + } + } +} + +// Similar to testcomponents.summation, but with a "receiver" export +testcomponents.summation_receiver "sum" { +} + +-- expected_metrics.prom -- + +# HELP alloy_component_controller_evaluating Tracks if the controller is currently in the middle of a graph evaluation +# TYPE alloy_component_controller_evaluating gauge +alloy_component_controller_evaluating{controller_id="",controller_path="/"} 0 +alloy_component_controller_evaluating{controller_id="foreach_4_1",controller_path="/foreach.testForeach"} 0 +alloy_component_controller_evaluating{controller_id="foreach_6_1",controller_path="/foreach.testForeach"} 0 +# HELP alloy_component_controller_running_components Total number of running components. +# TYPE alloy_component_controller_running_components gauge +alloy_component_controller_running_components{controller_id="",controller_path="/",health_type="healthy"} 2 +alloy_component_controller_running_components{controller_id="foreach_4_1",controller_path="/foreach.testForeach",health_type="healthy"} 1 +alloy_component_controller_running_components{controller_id="foreach_6_1",controller_path="/foreach.testForeach",health_type="healthy"} 1 +# HELP alloy_component_evaluation_queue_size Tracks the number of components waiting to be evaluated in the worker pool +# TYPE alloy_component_evaluation_queue_size gauge +alloy_component_evaluation_queue_size{controller_id="",controller_path="/"} 1 +alloy_component_evaluation_queue_size{controller_id="foreach_4_1",controller_path="/foreach.testForeach"} 0 +alloy_component_evaluation_queue_size{controller_id="foreach_6_1",controller_path="/foreach.testForeach"} 0 +# HELP pulse_count +# TYPE pulse_count counter +pulse_count{component_id="testcomponents.pulse.pt",component_path="/foreach.testForeach/foreach_4_1"} 4 +pulse_count{component_id="testcomponents.pulse.pt",component_path="/foreach.testForeach/foreach_6_1"} 6 + +-- expected_duration_metrics.prom -- + +6 \ No newline at end of file