Skip to content

Commit e10aad1

Browse files
committed
zapslog: fix handler state management problems.
Signed-off-by: junya koyama <[email protected]>
1 parent baa935c commit e10aad1

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

exp/zapslog/handler.go

+22-13
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"context"
2727
"log/slog"
2828
"runtime"
29+
"slices"
2930

3031
"go.uber.org/zap"
3132
"go.uber.org/zap/internal/stacktrace"
@@ -163,15 +164,19 @@ func (h *Handler) Handle(ctx context.Context, record slog.Record) error {
163164
}
164165

165166
fields := make([]zapcore.Field, 0, record.NumAttrs()+1)
167+
var addedNamespace bool
166168
record.Attrs(func(attr slog.Attr) bool {
167169
f := convertAttrToField(attr)
168-
if h.holdGroup != "" && f != zap.Skip() {
169-
fields = append(fields, zap.Namespace(h.holdGroup))
170-
h.holdGroup = ""
170+
if !addedNamespace && f != zap.Skip() {
171+
addedNamespace = true
171172
}
172173
fields = append(fields, f)
173174
return true
174175
})
176+
if h.holdGroup != "" && addedNamespace {
177+
// group is before than other fields.
178+
fields = slices.Insert(fields, 0, zap.Namespace(h.holdGroup))
179+
}
175180

176181
ce.Write(fields...)
177182
return nil
@@ -181,31 +186,35 @@ func (h *Handler) Handle(ctx context.Context, record slog.Record) error {
181186
// both the receiver's attributes and the arguments.
182187
func (h *Handler) WithAttrs(attrs []slog.Attr) slog.Handler {
183188
fields := make([]zapcore.Field, 0, len(attrs)+1)
189+
var addedNamespace bool
184190
for _, attr := range attrs {
185191
f := convertAttrToField(attr)
186-
if h.holdGroup != "" && f != zap.Skip() {
187-
fields = append(fields, zap.Namespace(h.holdGroup))
188-
h.holdGroup = ""
192+
if !addedNamespace && f != zap.Skip() {
193+
addedNamespace = true
189194
}
190195
fields = append(fields, f)
191196
}
192-
return h.withFields(fields...)
197+
if h.holdGroup != "" && addedNamespace {
198+
// group is before than other fields.
199+
fields = slices.Insert(fields, 0, zap.Namespace(h.holdGroup))
200+
return h.withFields("", fields...)
201+
}
202+
return h.withFields(h.holdGroup, fields...)
193203
}
194204

195205
// WithGroup returns a new Handler with the given group appended to
196206
// the receiver's existing groups.
197207
func (h *Handler) WithGroup(group string) slog.Handler {
198-
cloned := *h
199208
if h.holdGroup != "" {
200-
cloned.core = h.core.With([]zapcore.Field{zap.Namespace(h.holdGroup)})
209+
return h.withFields(group, zap.Namespace(h.holdGroup))
201210
}
202-
cloned.holdGroup = group
203-
return &cloned
211+
return h.withFields(group)
204212
}
205213

206-
// withFields returns a cloned Handler with the given fields.
207-
func (h *Handler) withFields(fields ...zapcore.Field) *Handler {
214+
// withFields returns a cloned Handler with the given groups and fields.
215+
func (h *Handler) withFields(newGroup string, fields ...zapcore.Field) *Handler {
208216
cloned := *h
217+
cloned.holdGroup = newGroup
209218
cloned.core = h.core.With(fields)
210219
return &cloned
211220
}

0 commit comments

Comments
 (0)