Repository: uber-go/zap
File: exp/zapslog/handler.go (Go)

Code before:
			ce.Caller = zapcore.EntryCaller{
				Defined:  true,
				PC:       frame.PC,
				File:     frame.File,
				Line:     frame.Line,
				Function: frame.Function,
			}
		}
	}

	if record.Level >= h.addStackAt {
		// Skipping 3:
		// zapslog/handler log/slog.(*Logger).log
		// slog/logger log/slog.(*Logger).log
		// slog/logger log/slog.(*Logger).<level>
		ce.Stack = stacktrace.Take(3 + h.callerSkip)
	}

	fields := make([]zapcore.Field, 0, record.NumAttrs()+1)
	record.Attrs(func(attr slog.Attr) bool {
		f := convertAttrToField(attr)
		if h.holdGroup != "" && f != zap.Skip() {
			fields = append(fields, zap.Namespace(h.holdGroup))
			h.holdGroup = ""
		}
		fields = append(fields, f)
		return true
	})

	ce.Write(fields...)
	return nil
}

// WithAttrs returns a new Handler whose attributes consist of
// both the receiver's attributes and the arguments.
func (h *Handler) WithAttrs(attrs []slog.Attr) slog.Handler {
	fields := make([]zapcore.Field, 0, len(attrs)+1)
	for _, attr := range attrs {
		f := convertAttrToField(attr)
		if h.holdGroup != "" && f != zap.Skip() {
			fields = append(fields, zap.Namespace(h.holdGroup))
			h.holdGroup = ""
		}
		fields = append(fields, f)
	}
	return h.withFields(fields...)
}

// WithGroup returns a new Handler with the given group appended to
// the receiver's existing groups.
func (h *Handler) WithGroup(group string) slog.Handler {

Review comment (suggestion):
I don't think this bit is right. We cannot modify `h`'s internal state in a `Handle`.
If we have two concurrent Handle calls, this will include the group in only one of those calls.
I think what we want to do here is record a boolean in the closure outside the Attrs loop, and flip it after the first `zap.Namespace`.

Something like this:

```
var addedNamespace bool
record.Attrs(... {
  if ... && !addedNamespace {
    fields = append(...)
    addedNamespace = true
  }
})
```

This way two concurrent calls will not fight each other on this.

Code after:
		return nil
	}

	if h.addCaller && record.PC != 0 {
		frame, _ := runtime.CallersFrames([]uintptr{record.PC}).Next()
		if frame.PC != 0 {
			ce.Caller = zapcore.EntryCaller{
				Defined:  true,
				PC:       frame.PC,
				File:     frame.File,
				Line:     frame.Line,
				Function: frame.Function,
			}
		}
	}

	if record.Level >= h.addStackAt {
		// Skipping 3:
		// zapslog/handler log/slog.(*Logger).log
		// slog/logger log/slog.(*Logger).log
		// slog/logger log/slog.(*Logger).<level>
		ce.Stack = stacktrace.Take(3 + h.callerSkip)
	}

	fields := make([]zapcore.Field, 0, record.NumAttrs()+len(h.groups))

	var addedNamespace bool
	record.Attrs(func(attr slog.Attr) bool {
		f := convertAttrToField(attr)
		if !addedNamespace && len(h.groups) > 0 && f != zap.Skip() {
			// Namespaces are added only if at least one field is present
			// to avoid creating empty groups.
			fields = h.appendGroups(fields)
			addedNamespace = true
		}
		fields = append(fields, f)
		return true
	})

	ce.Write(fields...)
	return nil
}

func (h *Handler) appendGroups(fields []zapcore.Field) []zapcore.Field {
	for _, g := range h.groups {
		fields = append(fields, zap.Namespace(g))
	}
	return fields
}

// WithAttrs returns a new Handler whose attributes consist of