diff --git a/changelog/fragments/1718138001-Fix-possible-crash-in-reading-component-logs.yaml b/changelog/fragments/1718138001-Fix-possible-crash-in-reading-component-logs.yaml new file mode 100644 index 00000000000..e62b32a0e78 --- /dev/null +++ b/changelog/fragments/1718138001-Fix-possible-crash-in-reading-component-logs.yaml @@ -0,0 +1,32 @@ +# Kind can be one of: +# - breaking-change: a change to previously-documented behavior +# - deprecation: functionality that is being removed in a later release +# - bug-fix: fixes a problem in a previous version +# - enhancement: extends functionality but does not break or fix existing behavior +# - feature: new functionality +# - known-issue: problems that we are aware of in a given version +# - security: impacts on the security of a product or a user’s deployment. +# - upgrade: important information for someone upgrading from a prior version +# - other: does not fit into any of the other categories +kind: bug-fix + +# Change summary; a 80ish characters long description of the change. +summary: Fix possible crash in reading component logs + +# Long description; in case the summary is not enough to describe the change +# this field accommodate a description without length limits. +# NOTE: This field will be rendered only for breaking-change and known-issue kinds at the moment. +#description: + +# Affected component; usually one of "elastic-agent", "fleet-server", "filebeat", "metricbeat", "auditbeat", "all", etc. +component: elastic-agent + +# PR URL; optional; the PR number that added the changeset. +# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added. +# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number. +# Please provide it if you are adding a fragment for a different PR. +pr: https://github.com/elastic/elastic-agent/pull/4910 + +# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of). +# If not present is automatically filled by the tooling with the issue linked to the PR number. +issue: https://github.com/elastic/elastic-agent/issues/4907 diff --git a/pkg/component/runtime/log_writer.go b/pkg/component/runtime/log_writer.go index 960c7f07a1a..9cf68489342 100644 --- a/pkg/component/runtime/log_writer.go +++ b/pkg/component/runtime/log_writer.go @@ -106,6 +106,10 @@ func (r *logWriter) Write(p []byte) (int, error) { continue } str := strings.TrimSpace(string(line)) + if len(str) == 0 { + // empty line after trim + continue + } // try to parse line as JSON if str[0] == '{' && r.handleJSON(str) { // handled as JSON diff --git a/pkg/component/runtime/log_writer_test.go b/pkg/component/runtime/log_writer_test.go index f0b6b01caaa..dd7cc1ff338 100644 --- a/pkg/component/runtime/log_writer_test.go +++ b/pkg/component/runtime/log_writer_test.go @@ -122,6 +122,33 @@ func TestLogWriter(t *testing.T) { }, }, }, + { + Name: "multi empty text line", + LogLevel: zapcore.InfoLevel, + LogSource: logSourceStdout, + Lines: []string{ + "simple written line\r\n", + "\r\n", // empty line + " \r\n", // empty line with space + "another line\n", + }, + Wrote: []wrote{ + { + entry: zapcore.Entry{ + Level: zapcore.InfoLevel, + Time: time.Time{}, + Message: "simple written line", + }, + }, + { + entry: zapcore.Entry{ + Level: zapcore.InfoLevel, + Time: time.Time{}, + Message: "another line", + }, + }, + }, + }, { Name: "json log line split", LogLevel: zapcore.DebugLevel,