Replies: 2 comments 3 replies
-
It's printing the same message because the This should give you what you were expecting to see:
Prints:
|
Beta Was this translation helpful? Give feedback.
-
Quick meta note: zap's fields are intended to be (effectively) static once either (a) attached to a logger or (b) added as part of a log statement, both because the semantics of how/when fields are encoded aren't specified as part of the API, and because it would cause unpredictable behavior e.g. in the case of mutating logger-level fields. Zap expects field values to be unchanged while it holds them. In the case of non-scalars – for example, Edit: To correct myself, both log methods ( The reason for this is because encoding is a two-stage process: first, logger-level fields are encoded with the logger's core's encoder prior to returning the logger back to the user (modulo preemption). This encoder is not used directly for encoding log entries. Second, when writing out log entries, the core encoder is cloned, log-level (e.g. One idea that we've discussed a bit is the concept of "dynamic" fields, for example (pseudocode): type DynamicField[T] struct {
key string
getter func() T
// ...
}
func DynamicField[T any](key string, fn func() T) DynamicField[T] {
return DynamicField[T]{
key: key,
getter: fn,
}
}
func (f *DynamicField[T]) AddTo(enc ObjectEncoder) {
// add f.key to enc with value from f.getter()
} which would enable users to do things like, func (a *App) getFooValue() string {
a.mu.RLock()
defer a.mu.RUnlock()
return a.someDynamicStringValue
}
logger = logger.With(zap.DynamicField("foo", getFooValue))
logger.Info("hello world", zap.Int("bar", 123))
// -> msg="hello world" fields={"bar":123,"foo":"<current foo value at encoding time>"} (Obviously this code won't work with zap's API, just used to illustrate the idea.) The problem with this is that it introduces ambiguity around what value will be logged. Will the expected "current" value (at call time) be used? Will the value change (and potentially be incorrect) prior to encoding? Since the encoding pipeline is (somewhat) abstracted from users, there's no way for this to work deterministically without external synchronization, which would likely be brittle, complicated, and ruin performance. So, even if we did add the concept of "dynamic" fields to Zap, users would need to be very careful about how they're used, and we would have limited ability to provide guardrails from them being misused. Arguably, they could introduce more problems than they'd solve (depending upon the implementation), so we'd need a compelling reason to add them instead of continuing to use "static" fields as we do now. |
Beta Was this translation helpful? Give feedback.
-
Is your feature request related to a problem? Please describe.
Suppose I have a progress field, which will be changed during the execution of my code.
code:
output:
I want the progress parameter in with to be called when my log is actually printed. But I don't know how to deal with it.
I hope that every time I call log printing, progress will change. For example, I pass a callback function as a parameter.
I have considered solutions such as JSON encoder, but I am not familiar with golang. After investigation for a period of time, there is still no good solution.
Beta Was this translation helpful? Give feedback.
All reactions