@@ -26,6 +26,7 @@ import (
26
26
"context"
27
27
"log/slog"
28
28
"runtime"
29
+ "slices"
29
30
30
31
"go.uber.org/zap"
31
32
"go.uber.org/zap/internal/stacktrace"
@@ -163,15 +164,19 @@ func (h *Handler) Handle(ctx context.Context, record slog.Record) error {
163
164
}
164
165
165
166
fields := make ([]zapcore.Field , 0 , record .NumAttrs ()+ 1 )
167
+ var addedNamespace bool
166
168
record .Attrs (func (attr slog.Attr ) bool {
167
169
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
171
172
}
172
173
fields = append (fields , f )
173
174
return true
174
175
})
176
+ if h .holdGroup != "" && addedNamespace {
177
+ // group is before than other fields.
178
+ fields = slices .Insert (fields , 0 , zap .Namespace (h .holdGroup ))
179
+ }
175
180
176
181
ce .Write (fields ... )
177
182
return nil
@@ -181,31 +186,35 @@ func (h *Handler) Handle(ctx context.Context, record slog.Record) error {
181
186
// both the receiver's attributes and the arguments.
182
187
func (h * Handler ) WithAttrs (attrs []slog.Attr ) slog.Handler {
183
188
fields := make ([]zapcore.Field , 0 , len (attrs )+ 1 )
189
+ var addedNamespace bool
184
190
for _ , attr := range attrs {
185
191
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
189
194
}
190
195
fields = append (fields , f )
191
196
}
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 ... )
193
203
}
194
204
195
205
// WithGroup returns a new Handler with the given group appended to
196
206
// the receiver's existing groups.
197
207
func (h * Handler ) WithGroup (group string ) slog.Handler {
198
- cloned := * h
199
208
if h .holdGroup != "" {
200
- cloned . core = h . core . With ([]zapcore. Field { zap .Namespace (h .holdGroup )} )
209
+ return h . withFields ( group , zap .Namespace (h .holdGroup ))
201
210
}
202
- cloned .holdGroup = group
203
- return & cloned
211
+ return h .withFields (group )
204
212
}
205
213
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 {
208
216
cloned := * h
217
+ cloned .holdGroup = newGroup
209
218
cloned .core = h .core .With (fields )
210
219
return & cloned
211
220
}
0 commit comments