Skip to content

Commit 4cf1253

Browse files
authored
add an in-memory logger and use it on install and uninstall (#4485)
1 parent ce229d2 commit 4cf1253

File tree

4 files changed

+61
-36
lines changed

4 files changed

+61
-36
lines changed

internal/pkg/agent/cmd/install.go

+2-17
Original file line numberDiff line numberDiff line change
@@ -193,28 +193,13 @@ func installCmd(streams *cli.IOStreams, cmd *cobra.Command) error {
193193

194194
progBar := install.CreateAndStartNewSpinner(streams.Out, "Installing Elastic Agent...")
195195

196-
logCfg := logp.DefaultConfig(logp.DefaultEnvironment)
197-
logCfg.Level = logp.DebugLevel
198-
// Using in memory logger, so we don't write logs to the
199-
// directory we are trying to delete
200-
logp.ToObserverOutput()(&logCfg)
201-
202-
err = logp.Configure(logCfg)
203-
if err != nil {
204-
return fmt.Errorf("error creating logging config: %w", err)
205-
}
206-
207-
log := logger.NewWithoutConfig("")
208-
196+
log, logBuff := logger.NewInMemory("install", logp.ConsoleEncoderConfig())
209197
defer func() {
210198
if err == nil {
211199
return
212200
}
213-
oLogs := logp.ObserverLogs().TakeAll()
214201
fmt.Fprintf(os.Stderr, "Error uninstalling. Printing logs\n")
215-
for _, oLog := range oLogs {
216-
fmt.Fprintf(os.Stderr, "%v\n", oLog.Entry)
217-
}
202+
fmt.Fprint(os.Stderr, logBuff.String())
218203
}()
219204

220205
var ownership utils.FileOwner

internal/pkg/agent/cmd/uninstall.go

+2-18
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"github.com/spf13/cobra"
1212

1313
"github.com/elastic/elastic-agent-libs/logp"
14-
1514
"github.com/elastic/elastic-agent/internal/pkg/agent/application/paths"
1615
"github.com/elastic/elastic-agent/internal/pkg/agent/install"
1716
"github.com/elastic/elastic-agent/internal/pkg/cli"
@@ -86,28 +85,13 @@ func uninstallCmd(streams *cli.IOStreams, cmd *cobra.Command) error {
8685

8786
progBar := install.CreateAndStartNewSpinner(streams.Out, "Uninstalling Elastic Agent...")
8887

89-
logCfg := logp.DefaultConfig(logp.DefaultEnvironment)
90-
logCfg.Level = logp.DebugLevel
91-
// Using in memory logger, so we don't write logs to the
92-
// directory we are trying to delete
93-
logp.ToObserverOutput()(&logCfg)
94-
95-
err = logp.Configure(logCfg)
96-
if err != nil {
97-
return fmt.Errorf("error creating logging config: %w", err)
98-
}
99-
100-
log := logger.NewWithoutConfig("")
101-
88+
log, logBuff := logger.NewInMemory("uninstall", logp.ConsoleEncoderConfig())
10289
defer func() {
10390
if err == nil {
10491
return
10592
}
106-
oLogs := logp.ObserverLogs().TakeAll()
10793
fmt.Fprintf(os.Stderr, "Error uninstalling. Printing logs\n")
108-
for _, oLog := range oLogs {
109-
fmt.Fprintf(os.Stderr, "%v\n", oLog.Entry)
110-
}
94+
fmt.Fprint(os.Stderr, logBuff.String())
11195
}()
11296

11397
err = install.Uninstall(paths.ConfigFile(), paths.Top(), uninstallToken, log, progBar)

pkg/core/logger/logger.go

+27-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package logger
66

77
import (
8+
"bytes"
89
"fmt"
910
"os"
1011
"path/filepath"
@@ -72,6 +73,31 @@ func NewWithoutConfig(name string) *Logger {
7273
return logp.NewLogger(name)
7374
}
7475

76+
// NewInMemory returns a new in-memory logger along with the buffer to which i
77+
// logs.
78+
// encCfg configures the log format, use logp.ConsoleEncoderConfig for console
79+
// format, logp.JSONEncoderConfig for JSON or any other valid zapcore.EncoderConfig.
80+
func NewInMemory(selector string, encCfg zapcore.EncoderConfig) (*Logger, *bytes.Buffer) {
81+
buff := bytes.Buffer{}
82+
83+
encoderConfig := ecszap.ECSCompatibleEncoderConfig(encCfg)
84+
encoderConfig.EncodeTime = UtcTimestampEncode
85+
encoder := zapcore.NewConsoleEncoder(encoderConfig)
86+
87+
core := zapcore.NewCore(
88+
encoder,
89+
zapcore.AddSync(&buff),
90+
zap.NewAtomicLevelAt(zap.DebugLevel))
91+
ecszap.ECSCompatibleEncoderConfig(logp.ConsoleEncoderConfig())
92+
93+
logger := logp.NewLogger(
94+
selector,
95+
zap.WrapCore(func(in zapcore.Core) zapcore.Core {
96+
return core
97+
}))
98+
return logger, &buff
99+
}
100+
75101
// AddCallerSkip returns new logger with incremented stack frames to skip.
76102
// This is needed in order to correctly report the log file lines when the logging statement
77103
// is wrapped in some convenience wrapping function for example.
@@ -147,7 +173,7 @@ func DefaultLoggingConfig() *Config {
147173
return &cfg
148174
}
149175

150-
// makeInternalFileOutput creates a zapcore.Core logger that cannot be changed with configuration.
176+
// MakeInternalFileOutput creates a zapcore.Core logger that cannot be changed with configuration.
151177
//
152178
// This is the logger that the spawned filebeat expects to read the log file from and ship to ES.
153179
func MakeInternalFileOutput(cfg *Config) (zapcore.Core, error) {

pkg/core/logger/logger_test.go

+30
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
package logger
66

77
import (
8+
"strings"
89
"testing"
910

11+
"github.com/stretchr/testify/assert"
1012
"github.com/stretchr/testify/require"
1113
"go.uber.org/zap/zapcore"
1214

@@ -56,3 +58,31 @@ func Test_SetLevel(t *testing.T) {
5658
require.Equal(t, tc.ErrEnabled, internalLevelEnabler.Enabled(zapcore.ErrorLevel))
5759
}
5860
}
61+
62+
func TestNewInMemory(t *testing.T) {
63+
log, buff := NewInMemory("in_memory", logp.ConsoleEncoderConfig())
64+
65+
log.Debugw("a debug message", "debug_key", "debug_val")
66+
log.Infow("a info message", "info_key", "info_val")
67+
log.Warnw("a warn message", "warn_key", "warn_val")
68+
log.Errorw("an error message", "error_key", "error_val")
69+
70+
logs := strings.Split(strings.TrimSpace(buff.String()), "\n")
71+
assert.Len(t, logs, 4, "expected 4 log entries")
72+
73+
assert.Contains(t, logs[0], "a debug message")
74+
assert.Contains(t, logs[0], "debug_key")
75+
assert.Contains(t, logs[0], "debug_val")
76+
77+
assert.Contains(t, logs[1], "a info message")
78+
assert.Contains(t, logs[1], "info_key")
79+
assert.Contains(t, logs[1], "info_val")
80+
81+
assert.Contains(t, logs[2], "a warn message")
82+
assert.Contains(t, logs[2], "warn_key")
83+
assert.Contains(t, logs[2], "warn_val")
84+
85+
assert.Contains(t, logs[3], "an error message")
86+
assert.Contains(t, logs[3], "error_key")
87+
assert.Contains(t, logs[3], "error_val")
88+
}

0 commit comments

Comments
 (0)