From f222e2e08bbd636fe75108199c8814c674042876 Mon Sep 17 00:00:00 2001 From: Robert Fratto <robertfratto@gmail.com> Date: Thu, 29 Feb 2024 14:24:19 -0500 Subject: [PATCH] Prepare release v0.40.1 (#6569) * ignore errors when the logging node empties the log buffer (#6558) (cherry picked from commit b691a44b47b3d443cf9fa462190069ed5ff5b98f) * Fix wiring of custom component nodes (#6563) * fix wiring of custom component nodes by checking import before local declares * update changelog * add comment in loader to explain why the imports should be checked before the local declare (cherry picked from commit 0dde507f404ca2236789f8fe35ecb5f916ab50e4) * flow/logging: check for nil values when writing logs (#6561) There may be situations where the flow mode logger receivers a nil value, potentially due to misconfiguration or a component which exports its values only after being ran. Fixes #6557. (cherry picked from commit bcc9b0a79730598a7e30460b581d335b01d476fb) * changelog: cut 0.40.1 (#6568) (cherry picked from commit 9154af36520ee2ff4f368daa62f883504d67ac82) --------- Co-authored-by: William Dumont <william.dumont@grafana.com> --- CHANGELOG.md | 11 ++++++ docs/sources/_index.md | 2 +- pkg/flow/internal/controller/loader.go | 10 +++--- pkg/flow/logging/logger.go | 15 ++++++-- pkg/flow/logging/logger_test.go | 20 +++++++++++ .../testdata/import_file/import_file_16.txtar | 36 +++++++++++++++++++ pkg/operator/defaults.go | 2 +- tools/gen-versioned-files/agent-version.txt | 2 +- 8 files changed, 88 insertions(+), 10 deletions(-) create mode 100644 pkg/flow/testdata/import_file/import_file_16.txtar diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a220278e711..48f592c8165a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,17 @@ internal API changes are not present. +v0.40.1 (2024-02-27) +-------------------- + +### Bugfixes + +- Fix an issues where the logging config block would trigger an error when trying to send logs to components that were not running. (@wildum) + +- Fix an issue where a custom component might be wired to a local declare instead of an import declare when they have the same label. (@wildum) + +- Fix an issue where flow mode panics if the `logging` config block is given a `null` Loki receiver to write log entries to. (@rfratto) + v0.40.0 (2024-02-27) -------------------- diff --git a/docs/sources/_index.md b/docs/sources/_index.md index 605655ef6a7d..556ea167a769 100644 --- a/docs/sources/_index.md +++ b/docs/sources/_index.md @@ -9,7 +9,7 @@ title: Grafana Agent description: Grafana Agent is a flexible, performant, vendor-neutral, telemetry collector weight: 350 cascade: - AGENT_RELEASE: v0.40.0 + AGENT_RELEASE: v0.40.1 OTEL_VERSION: v0.87.0 --- diff --git a/pkg/flow/internal/controller/loader.go b/pkg/flow/internal/controller/loader.go index 741f4e4d5c25..79779837cce9 100644 --- a/pkg/flow/internal/controller/loader.go +++ b/pkg/flow/internal/controller/loader.go @@ -589,15 +589,17 @@ func (l *Loader) wireGraphEdges(g *dag.Graph) diag.Diagnostics { // wireCustomComponentNode wires a custom component to the import/declare nodes that it depends on. func (l *Loader) wireCustomComponentNode(g *dag.Graph, cc *CustomComponentNode) { - if declare, ok := l.declareNodes[cc.customComponentName]; ok { + // It's important to check first if the importNamespace matches an import node because there might be a + // local node that has the same label as an imported declare. + if importNode, ok := l.importConfigNodes[cc.importNamespace]; ok { + // add an edge between the custom component and the corresponding import node. + g.AddEdge(dag.Edge{From: cc, To: importNode}) + } else if declare, ok := l.declareNodes[cc.customComponentName]; ok { refs := l.findCustomComponentReferences(declare.Block()) for ref := range refs { // add edges between the custom component and declare/import nodes. g.AddEdge(dag.Edge{From: cc, To: ref}) } - } else if importNode, ok := l.importConfigNodes[cc.importNamespace]; ok { - // add an edge between the custom component and the corresponding import node. - g.AddEdge(dag.Edge{From: cc, To: importNode}) } } diff --git a/pkg/flow/logging/logger.go b/pkg/flow/logging/logger.go index da0046a281af..1856c5465401 100644 --- a/pkg/flow/logging/logger.go +++ b/pkg/flow/logging/logger.go @@ -126,9 +126,9 @@ func (l *Logger) Update(o Options) error { // Print out the buffered logs since we determined the log format already for _, bufferedLogChunk := range l.buffer { - if err := slogadapter.GoKit(l.handler).Log(bufferedLogChunk...); err != nil { - return err - } + // the buffered logs are currently only sent to the standard output + // because the components with the receivers are not running yet + slogadapter.GoKit(l.handler).Log(bufferedLogChunk...) } l.buffer = nil @@ -164,6 +164,15 @@ type lokiWriter struct { func (fw *lokiWriter) Write(p []byte) (int, error) { for _, receiver := range fw.f { + // We may have been given a nil value in rare circumstances due to + // misconfiguration or a component which generates exports after + // construction. + // + // Ignore nil values so we don't panic. + if receiver == nil { + continue + } + select { case receiver.Chan() <- loki.Entry{ Labels: model.LabelSet{"component": "agent"}, diff --git a/pkg/flow/logging/logger_test.go b/pkg/flow/logging/logger_test.go index d199f1488747..cf3f7a66c139 100644 --- a/pkg/flow/logging/logger_test.go +++ b/pkg/flow/logging/logger_test.go @@ -11,6 +11,7 @@ import ( "github.com/go-kit/log" gokitlevel "github.com/go-kit/log/level" + "github.com/grafana/agent/component/common/loki" "github.com/grafana/agent/pkg/flow/logging" flowlevel "github.com/grafana/agent/pkg/flow/logging/level" "github.com/stretchr/testify/require" @@ -165,6 +166,25 @@ func TestLevels(t *testing.T) { } } +// Test_lokiWriter_nil ensures that writing to a lokiWriter doesn't panic when +// given a nil receiver. +func Test_lokiWriter_nil(t *testing.T) { + logger, err := logging.New(io.Discard, debugLevel()) + require.NoError(t, err) + + err = logger.Update(logging.Options{ + Level: logging.LevelDebug, + Format: logging.FormatLogfmt, + + WriteTo: []loki.LogsReceiver{nil}, + }) + require.NoError(t, err) + + require.NotPanics(t, func() { + _ = logger.Log("msg", "test message") + }) +} + func BenchmarkLogging_NoLevel_Prints(b *testing.B) { logger, err := logging.New(io.Discard, infoLevel()) require.NoError(b, err) diff --git a/pkg/flow/testdata/import_file/import_file_16.txtar b/pkg/flow/testdata/import_file/import_file_16.txtar new file mode 100644 index 000000000000..804c7c6d751e --- /dev/null +++ b/pkg/flow/testdata/import_file/import_file_16.txtar @@ -0,0 +1,36 @@ +Imported declare and local declare have the same label. + +-- main.river -- +testcomponents.count "inc" { + frequency = "10ms" + max = 10 +} + +import.file "certmanager" { + filename = "module.river" +} + +certmanager.config "this" { + input = testcomponents.count.inc.count +} + +declare "config" { +} + +testcomponents.summation "sum" { + input = certmanager.config.this.output +} + +-- module.river -- +declare "config" { + argument "input" {} + + testcomponents.passthrough "pt" { + input = argument.input.value + lag = "1ms" + } + + export "output" { + value = testcomponents.passthrough.pt.output + } +} \ No newline at end of file diff --git a/pkg/operator/defaults.go b/pkg/operator/defaults.go index d62a46a1ece9..e985937bb348 100644 --- a/pkg/operator/defaults.go +++ b/pkg/operator/defaults.go @@ -2,7 +2,7 @@ package operator // Supported versions of the Grafana Agent. var ( - DefaultAgentVersion = "v0.40.0" + DefaultAgentVersion = "v0.40.1" DefaultAgentBaseImage = "grafana/agent" DefaultAgentImage = DefaultAgentBaseImage + ":" + DefaultAgentVersion ) diff --git a/tools/gen-versioned-files/agent-version.txt b/tools/gen-versioned-files/agent-version.txt index dbccec6e080f..01437515a7c3 100644 --- a/tools/gen-versioned-files/agent-version.txt +++ b/tools/gen-versioned-files/agent-version.txt @@ -1 +1 @@ -v0.40.0 \ No newline at end of file +v0.40.1