@@ -6,12 +6,22 @@ import (
66 "io"
77 "log/slog"
88 "strconv"
9+ "strings"
910 "sync"
1011 "sync/atomic"
1112 "unicode"
1213 "unicode/utf8"
1314)
1415
16+ const (
17+ resetSeq = "0"
18+ boldSeq = "1"
19+ faintSeq = "2"
20+
21+ esc = '\x1b'
22+ csi = string (esc ) + "["
23+ )
24+
1525// HandlerOption is the signature of a functional option that can be used to
1626// modify the behaviour of the DefaultHandler.
1727type HandlerOption func (* handlerOpts )
@@ -39,6 +49,15 @@ func WithCallerFlags(flags uint32) HandlerOption {
3949 }
4050}
4151
52+ // WithStyledOutput can be used to add additional styling to the logs. This
53+ // currently includes colored & bold tags and faint fonts for attribute keys and
54+ // callsites.
55+ func WithStyledOutput () HandlerOption {
56+ return func (opts * handlerOpts ) {
57+ opts .styled = true
58+ }
59+ }
60+
4261// WithNoTimestamp is an option that can be used to omit timestamps from the log
4362// lines.
4463func WithNoTimestamp () HandlerOption {
@@ -213,6 +232,23 @@ func (d *DefaultHandler) with(tag string, withCallstackOffset bool,
213232 return & sl
214233}
215234
235+ func (d * DefaultHandler ) styleString (s string , styles ... string ) string {
236+ if ! d .opts .styled {
237+ return s
238+ }
239+
240+ if len (styles ) == 0 {
241+ return s
242+ }
243+
244+ seq := strings .Join (styles , ";" )
245+ if seq == "" {
246+ return s
247+ }
248+
249+ return fmt .Sprintf ("%s%sm%s%sm" , csi , seq , s , csi + resetSeq )
250+ }
251+
216252func (d * DefaultHandler ) appendAttr (buf * buffer , a slog.Attr ) {
217253 // Resolve the Attr's value before doing anything else.
218254 a .Value = a .Value .Resolve ()
@@ -229,15 +265,19 @@ func (d *DefaultHandler) appendAttr(buf *buffer, a slog.Attr) {
229265func (d * DefaultHandler ) writeLevel (buf * buffer , level Level ) {
230266 str := fmt .Sprintf ("[%s] " , level )
231267
232- buf .writeString (str )
268+ buf .writeString (d .styleString (
269+ str , boldSeq , string (level .ansiColoSeq ())),
270+ )
233271}
234272
235273func (d * DefaultHandler ) writeCallSite (buf * buffer , file string , line int ) {
236274 if file == "" {
237275 return
238276 }
239277
240- buf .writeString (fmt .Sprintf (" %s:%d" , file , line ))
278+ buf .writeString (
279+ d .styleString (fmt .Sprintf (" %s:%d" , file , line ), faintSeq ),
280+ )
241281}
242282
243283func appendString (buf * buffer , str string ) {
@@ -255,7 +295,7 @@ func (d *DefaultHandler) appendKey(buf *buffer, key string) {
255295 }
256296 key += "="
257297
258- buf .writeString (key )
298+ buf .writeString (d . styleString ( key , faintSeq ) )
259299}
260300
261301func appendValue (buf * buffer , v slog.Value ) {
0 commit comments