@@ -80,40 +80,67 @@ func Make(sinks ...Sink) Logger {
8080}
8181
8282// Debug logs the msg and fields at LevelDebug.
83- func (l Logger ) Debug (ctx context.Context , msg string , fields ... Field ) {
83+ // See Info for information on the fields argument.
84+ func (l Logger ) Debug (ctx context.Context , msg string , fields ... any ) {
8485 l .log (ctx , LevelDebug , msg , fields )
8586}
8687
8788// Info logs the msg and fields at LevelInfo.
88- func (l Logger ) Info (ctx context.Context , msg string , fields ... Field ) {
89+ // Fields may contain any combination of key value pairs, Field, and Map.
90+ // For example:
91+ //
92+ // log.Info(ctx, "something happened", "user", "alex", slog.F("age", 20))
93+ //
94+ // is equivalent to:
95+ //
96+ // log.Info(ctx, "something happened", slog.F("user", "alex"), slog.F("age", 20))
97+ //
98+ // is equivalent to:
99+ //
100+ // log.Info(ctx, "something happened", slog.M(
101+ // slog.F("user", "alex"),
102+ // slog.F("age", 20),
103+ // ))
104+ //
105+ // is equivalent to:
106+ //
107+ // log.Info(ctx, "something happened", "user", "alex", "age", 20)
108+ //
109+ // In general, prefer using key value pairs over Field and Map, as that is how
110+ // the standard library's slog package works.
111+ func (l Logger ) Info (ctx context.Context , msg string , fields ... any ) {
89112 l .log (ctx , LevelInfo , msg , fields )
90113}
91114
92115// Warn logs the msg and fields at LevelWarn.
93- func (l Logger ) Warn (ctx context.Context , msg string , fields ... Field ) {
116+ // See Info() for information on the fields argument.
117+ func (l Logger ) Warn (ctx context.Context , msg string , fields ... any ) {
94118 l .log (ctx , LevelWarn , msg , fields )
95119}
96120
97121// Error logs the msg and fields at LevelError.
122+ // See Info() for information on the fields argument.
98123//
99124// It will then Sync().
100- func (l Logger ) Error (ctx context.Context , msg string , fields ... Field ) {
125+ func (l Logger ) Error (ctx context.Context , msg string , fields ... any ) {
101126 l .log (ctx , LevelError , msg , fields )
102127 l .Sync ()
103128}
104129
105130// Critical logs the msg and fields at LevelCritical.
131+ // See Info() for information on the fields argument.
106132//
107133// It will then Sync().
108- func (l Logger ) Critical (ctx context.Context , msg string , fields ... Field ) {
134+ func (l Logger ) Critical (ctx context.Context , msg string , fields ... any ) {
109135 l .log (ctx , LevelCritical , msg , fields )
110136 l .Sync ()
111137}
112138
113139// Fatal logs the msg and fields at LevelFatal.
140+ // See Info() for information on the fields argument.
114141//
115142// It will then Sync() and os.Exit(1).
116- func (l Logger ) Fatal (ctx context.Context , msg string , fields ... Field ) {
143+ func (l Logger ) Fatal (ctx context.Context , msg string , fields ... any ) {
117144 l .log (ctx , LevelFatal , msg , fields )
118145 l .Sync ()
119146
@@ -155,7 +182,32 @@ func (l Logger) AppendSinks(s ...Sink) Logger {
155182 return l
156183}
157184
158- func (l Logger ) log (ctx context.Context , level Level , msg string , fields Map ) {
185+ func (l Logger ) log (ctx context.Context , level Level , msg string , rawFields []any ) {
186+ fields := make (Map , 0 , len (rawFields ))
187+ var wipField Field
188+ for i , f := range rawFields {
189+ if wipField .Name != "" {
190+ wipField .Value = f
191+ fields = append (fields , wipField )
192+ wipField = Field {}
193+ continue
194+ }
195+ switch f := f .(type ) {
196+ case Field :
197+ fields = append (fields , f )
198+ case Map :
199+ fields = append (fields , f ... )
200+ case string :
201+ wipField .Name = f
202+ default :
203+ panic (fmt .Sprintf ("unexpected field type %T at index %v (does it have a key?)" , f , i ))
204+ }
205+ }
206+
207+ if wipField .Name != "" {
208+ panic (fmt .Sprintf ("field %q has no value" , wipField .Name ))
209+ }
210+
159211 ent := l .entry (ctx , level , msg , fields )
160212 l .Log (ctx , ent )
161213}
0 commit comments