Skip to content

Commit

Permalink
Fix behaviour of typedCore.With
Browse files Browse the repository at this point in the history
  • Loading branch information
belimawr committed Apr 9, 2024
1 parent 8d81a29 commit 6a5335a
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 16 deletions.
2 changes: 1 addition & 1 deletion logp/configure/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func LoggingWithTypedOutputs(beatName string, cfg, typedCfg *config.C, logKey, k
typedLogpConfig.Beat = beatName
if typedCfg != nil {
if err := typedCfg.Unpack(&typedLogpConfig); err != nil {
return fmt.Errorf("cannot unpack sensitiveCfg: %w", err)
return fmt.Errorf("cannot unpack typed output config: %w", err)
}
}

Expand Down
78 changes: 66 additions & 12 deletions logp/core_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -537,24 +537,78 @@ func TestTypedLoggerCoreSync(t *testing.T) {
}

func TestTypedLoggerCoreWith(t *testing.T) {
defaultCoreMock := &ZapCoreMock{}
typedCoreMock := &ZapCoreMock{}
defaultWriter := writeSyncer{}
typedWriter := writeSyncer{}

cfg := zap.NewProductionEncoderConfig()
cfg.TimeKey = "" // remove the time to make the log entry consistent

defaultCore := zapcore.NewCore(
zapcore.NewJSONEncoder(cfg),
&defaultWriter,
zapcore.InfoLevel,
)

typedCore := zapcore.NewCore(
zapcore.NewJSONEncoder(cfg),
&typedWriter,
zapcore.InfoLevel,
)

defaultCoreMock.WithFunc = func(fields []zapcore.Field) zapcore.Core { return defaultCoreMock }
typedCoreMock.WithFunc = func(fields []zapcore.Field) zapcore.Core { return typedCoreMock }
core := typedLoggerCore{
defaultCore: defaultCoreMock,
typedCore: typedCoreMock,
defaultCore: defaultCore,
typedCore: typedCore,
key: "log.type",
value: "sensitive",
}

field := strField("foo", "bar")
core.With([]zapcore.Field{field})
expectedLines := []string{
// First/Default logger
`{"level":"info","msg":"Very first message"}`,

// Two messages after calling With
`{"level":"info","msg":"a message with extra fields","foo":"bar"}`,
`{"level":"info","msg":"another message with extra fields","foo":"bar"}`,

// A message with the default logger
`{"level":"info","msg":"a message without extra fields"}`,

// Two more messages with a different field
`{"level":"info","msg":"a message with an answer","answer":"42"}`,
`{"level":"info","msg":"another message with an answer","answer":"42"}`,

if core.defaultCore != defaultCoreMock {
t.Error("defaultCore must not change after call to With")
// One last message with the default logger
`{"level":"info","msg":"another message without any extra fields"}`,
}
if core.typedCore != typedCoreMock {
t.Error("typedCore must not change after call to With")

// The default logger, it should not be modified by any call to With.
logger := zap.New(&core)
logger.Info("Very first message")

// Add a field and write messages
loggerWithFields := logger.With(strField("foo", "bar"))
loggerWithFields.Info("a message with extra fields")
loggerWithFields.Info("another message with extra fields")

// Use the default logger again
logger.Info("a message without extra fields")

// New logger with other fields
loggerWithFields = logger.With(strField("answer", "42"))
loggerWithFields.Info("a message with an answer")
loggerWithFields.Info("another message with an answer")

// One last message with the default logger
logger.Info("another message without any extra fields")

scanner := bufio.NewScanner(strings.NewReader(defaultWriter.String()))
count := 0
for scanner.Scan() {
l := scanner.Text()
if l != expectedLines[count] {
t.Error("Expecting:\n", l, "\nGot:\n", expectedLines[count])
}
count++
}
}

Expand Down
10 changes: 7 additions & 3 deletions logp/typedloggercore.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,13 @@ func (t *typedLoggerCore) Enabled(l zapcore.Level) bool {
}

func (t *typedLoggerCore) With(fields []zapcore.Field) zapcore.Core {
t.defaultCore = t.defaultCore.With(fields)
t.typedCore = t.typedCore.With(fields)
return t
newCore := typedLoggerCore{
defaultCore: t.defaultCore.With(fields),
typedCore: t.typedCore.With(fields),
key: t.key,
value: t.value,
}
return &newCore
}

func (t *typedLoggerCore) Check(e zapcore.Entry, ce *zapcore.CheckedEntry) *zapcore.CheckedEntry {
Expand Down

0 comments on commit 6a5335a

Please sign in to comment.