From 0f7f948de3301187ae4c561f433b52c994f3c0f2 Mon Sep 17 00:00:00 2001 From: Mauri de Souza Meneguzzo Date: Mon, 7 Oct 2024 11:16:40 -0300 Subject: [PATCH 1/4] fix: don't write to files by default if running in a container environment --- logp/config.go | 9 +++++++- logp/defaults_test.go | 51 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/logp/config.go b/logp/config.go index 87c8e8c..58f2db6 100644 --- a/logp/config.go +++ b/logp/config.go @@ -70,9 +70,16 @@ const ( // DefaultConfig returns the default config options for a given environment the // Beat is supposed to be run within. func DefaultConfig(environment Environment) Config { + toFiles := true + + // If running in a container environment, don't write to files by default. + if environment == ContainerEnvironment { + toFiles = false + } + return Config{ Level: defaultLevel, - ToFiles: true, + ToFiles: toFiles, Files: FileConfig{ MaxSize: 10 * 1024 * 1024, MaxBackups: 7, diff --git a/logp/defaults_test.go b/logp/defaults_test.go index aeec9bc..21a88fe 100644 --- a/logp/defaults_test.go +++ b/logp/defaults_test.go @@ -19,9 +19,11 @@ package logp_test import ( "bufio" + "bytes" "encoding/json" "fmt" "os" + "os/exec" "path/filepath" "runtime" "sort" @@ -117,6 +119,55 @@ func TestDefaultConfig(t *testing.T) { } } +func TestDefaultConfigContainer(t *testing.T) { + switch runtime.GOOS { + case "wasip1", "js", "ios": + t.Skipf("cannot exec subprocess on %s/%s", runtime.GOOS, runtime.GOARCH) + } + + if os.Getenv("TEST_DEFAULT_CONFIG_CONTAINER") != "1" { + cmd := exec.Command(os.Args[0], "-test.run=^TestDefaultConfigContainer$", "-test.v") + cmd.Env = append(cmd.Env, "TEST_DEFAULT_CONFIG_CONTAINER=1") + + var stderr bytes.Buffer + cmd.Stderr = &stderr + + err := cmd.Run() + data := stderr.Bytes() + assert.NoError(t, err, "command failed with error: %s\nstderr: %s", err, data) + t.Logf("output:\n%s", data) + + logEntry := struct { + LogLevel string `json:"log.level"` + LogOrigin struct { + FileName string `json:"file.name"` + FileLine int `json:"file.line"` + } `json:"log.origin"` + Message string `json:"message"` + }{} + + assert.NoError(t, json.Unmarshal(data, &logEntry), "cannot unmarshal log entry from stderr") + + assert.Equal(t, "info", logEntry.LogLevel) + assert.Equal(t, "foo", logEntry.Message) + + _, fileName, _, _ := runtime.Caller(0) + expectedFileName := filepath.Base(fileName) + gotFileName := filepath.Base(logEntry.LogOrigin.FileName) + assert.Equal(t, expectedFileName, gotFileName) + + return + } + + // This is running in a separate process. By default the + // container environment should be logging to stderr. + cfg := logp.DefaultConfig(logp.ContainerEnvironment) + assert.NoError(t, logp.Configure(cfg)) + logger := logp.L() + defer logger.Close() + logger.Info("foo") +} + func TestWith(t *testing.T) { tempDir := t.TempDir() From 3b10333be7bc6e45f358ed7dfde7c8d96be26671 Mon Sep 17 00:00:00 2001 From: Mauri de Souza Meneguzzo Date: Mon, 7 Oct 2024 12:15:23 -0300 Subject: [PATCH 2/4] fix gosec lint --- logp/defaults_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logp/defaults_test.go b/logp/defaults_test.go index 21a88fe..4fa4258 100644 --- a/logp/defaults_test.go +++ b/logp/defaults_test.go @@ -126,7 +126,7 @@ func TestDefaultConfigContainer(t *testing.T) { } if os.Getenv("TEST_DEFAULT_CONFIG_CONTAINER") != "1" { - cmd := exec.Command(os.Args[0], "-test.run=^TestDefaultConfigContainer$", "-test.v") + cmd := exec.Command(os.Args[0], "-test.run=^TestDefaultConfigContainer$", "-test.v") //nolint:gosec // This is intentionally running a subprocess cmd.Env = append(cmd.Env, "TEST_DEFAULT_CONFIG_CONTAINER=1") var stderr bytes.Buffer From 399ae3f5871d2c20821cec3e32d1d2155ec33480 Mon Sep 17 00:00:00 2001 From: Mauri de Souza Meneguzzo Date: Wed, 9 Oct 2024 09:16:44 -0300 Subject: [PATCH 3/4] systemd should also log to stderr --- logp/config.go | 12 ++++++---- logp/defaults_test.go | 51 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/logp/config.go b/logp/config.go index 58f2db6..bdc4e83 100644 --- a/logp/config.go +++ b/logp/config.go @@ -71,15 +71,19 @@ const ( // Beat is supposed to be run within. func DefaultConfig(environment Environment) Config { toFiles := true + toStderr := false - // If running in a container environment, don't write to files by default. - if environment == ContainerEnvironment { + // For container and systemd environments, we don't write to files by default. + switch environment { + case ContainerEnvironment, SystemdEnvironment: toFiles = false + toStderr = true } return Config{ - Level: defaultLevel, - ToFiles: toFiles, + Level: defaultLevel, + ToFiles: toFiles, + ToStderr: toStderr, Files: FileConfig{ MaxSize: 10 * 1024 * 1024, MaxBackups: 7, diff --git a/logp/defaults_test.go b/logp/defaults_test.go index 4fa4258..288d386 100644 --- a/logp/defaults_test.go +++ b/logp/defaults_test.go @@ -159,8 +159,7 @@ func TestDefaultConfigContainer(t *testing.T) { return } - // This is running in a separate process. By default the - // container environment should be logging to stderr. + // This is running in a separate process. cfg := logp.DefaultConfig(logp.ContainerEnvironment) assert.NoError(t, logp.Configure(cfg)) logger := logp.L() @@ -168,6 +167,54 @@ func TestDefaultConfigContainer(t *testing.T) { logger.Info("foo") } +func TestDefaultConfigSystemd(t *testing.T) { + switch runtime.GOOS { + case "wasip1", "js", "ios": + t.Skipf("cannot exec subprocess on %s/%s", runtime.GOOS, runtime.GOARCH) + } + + if os.Getenv("TEST_DEFAULT_CONFIG_SYSTEMD") != "1" { + cmd := exec.Command(os.Args[0], "-test.run=^TestDefaultConfigSystemd$", "-test.v") //nolint:gosec // This is intentionally running a subprocess + cmd.Env = append(cmd.Env, "TEST_DEFAULT_CONFIG_SYSTEMD=1") + + var stderr bytes.Buffer + cmd.Stderr = &stderr + + err := cmd.Run() + data := stderr.Bytes() + assert.NoError(t, err, "command failed with error: %s\nstderr: %s", err, data) + t.Logf("output:\n%s", data) + + logEntry := struct { + LogLevel string `json:"log.level"` + LogOrigin struct { + FileName string `json:"file.name"` + FileLine int `json:"file.line"` + } `json:"log.origin"` + Message string `json:"message"` + }{} + + assert.NoError(t, json.Unmarshal(data, &logEntry), "cannot unmarshal log entry from stderr") + + assert.Equal(t, "info", logEntry.LogLevel) + assert.Equal(t, "foo", logEntry.Message) + + _, fileName, _, _ := runtime.Caller(0) + expectedFileName := filepath.Base(fileName) + gotFileName := filepath.Base(logEntry.LogOrigin.FileName) + assert.Equal(t, expectedFileName, gotFileName) + + return + } + + // This is running in a separate process. + cfg := logp.DefaultConfig(logp.SystemdEnvironment) + assert.NoError(t, logp.Configure(cfg)) + logger := logp.L() + defer logger.Close() + logger.Info("foo") +} + func TestWith(t *testing.T) { tempDir := t.TempDir() From 3db5712782c71da75fe8045bac268bbc34c777ad Mon Sep 17 00:00:00 2001 From: Mauri de Souza Meneguzzo Date: Wed, 9 Oct 2024 09:38:05 -0300 Subject: [PATCH 4/4] reuse code between tests --- logp/defaults_test.go | 62 ++++++++----------------------------------- 1 file changed, 11 insertions(+), 51 deletions(-) diff --git a/logp/defaults_test.go b/logp/defaults_test.go index 288d386..fa15e6c 100644 --- a/logp/defaults_test.go +++ b/logp/defaults_test.go @@ -119,63 +119,23 @@ func TestDefaultConfig(t *testing.T) { } } -func TestDefaultConfigContainer(t *testing.T) { - switch runtime.GOOS { - case "wasip1", "js", "ios": - t.Skipf("cannot exec subprocess on %s/%s", runtime.GOOS, runtime.GOARCH) - } - - if os.Getenv("TEST_DEFAULT_CONFIG_CONTAINER") != "1" { - cmd := exec.Command(os.Args[0], "-test.run=^TestDefaultConfigContainer$", "-test.v") //nolint:gosec // This is intentionally running a subprocess - cmd.Env = append(cmd.Env, "TEST_DEFAULT_CONFIG_CONTAINER=1") - - var stderr bytes.Buffer - cmd.Stderr = &stderr - - err := cmd.Run() - data := stderr.Bytes() - assert.NoError(t, err, "command failed with error: %s\nstderr: %s", err, data) - t.Logf("output:\n%s", data) - - logEntry := struct { - LogLevel string `json:"log.level"` - LogOrigin struct { - FileName string `json:"file.name"` - FileLine int `json:"file.line"` - } `json:"log.origin"` - Message string `json:"message"` - }{} - - assert.NoError(t, json.Unmarshal(data, &logEntry), "cannot unmarshal log entry from stderr") - - assert.Equal(t, "info", logEntry.LogLevel) - assert.Equal(t, "foo", logEntry.Message) - - _, fileName, _, _ := runtime.Caller(0) - expectedFileName := filepath.Base(fileName) - gotFileName := filepath.Base(logEntry.LogOrigin.FileName) - assert.Equal(t, expectedFileName, gotFileName) - - return - } +func TestDefaultConfigContainerLogsToStderr(t *testing.T) { + runTestEnvStderr(t, logp.ContainerEnvironment) +} - // This is running in a separate process. - cfg := logp.DefaultConfig(logp.ContainerEnvironment) - assert.NoError(t, logp.Configure(cfg)) - logger := logp.L() - defer logger.Close() - logger.Info("foo") +func TestDefaultConfigSystemdLogsToStderr(t *testing.T) { + runTestEnvStderr(t, logp.SystemdEnvironment) } -func TestDefaultConfigSystemd(t *testing.T) { +func runTestEnvStderr(t *testing.T, envType logp.Environment) { switch runtime.GOOS { case "wasip1", "js", "ios": t.Skipf("cannot exec subprocess on %s/%s", runtime.GOOS, runtime.GOARCH) } - if os.Getenv("TEST_DEFAULT_CONFIG_SYSTEMD") != "1" { - cmd := exec.Command(os.Args[0], "-test.run=^TestDefaultConfigSystemd$", "-test.v") //nolint:gosec // This is intentionally running a subprocess - cmd.Env = append(cmd.Env, "TEST_DEFAULT_CONFIG_SYSTEMD=1") + if os.Getenv("TEST_DEFAULT_CONFIG_STDERR") != "1" { + cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=^%s$", t.Name()), "-test.v") //nolint:gosec // This is intentionally running a subprocess + cmd.Env = append(cmd.Env, "TEST_DEFAULT_CONFIG_STDERR=1") var stderr bytes.Buffer cmd.Stderr = &stderr @@ -207,8 +167,8 @@ func TestDefaultConfigSystemd(t *testing.T) { return } - // This is running in a separate process. - cfg := logp.DefaultConfig(logp.SystemdEnvironment) + // This is running in a separate process to make sure we capture stderr. + cfg := logp.DefaultConfig(envType) assert.NoError(t, logp.Configure(cfg)) logger := logp.L() defer logger.Close()