@@ -66,6 +66,8 @@ func MustConfigFromEnv(envvars ...string) {
6666func UnmarshalEnv (o * HandlerOptions , envvars ... string ) error {
6767 for _ , v := range envvars {
6868 if configString := os .Getenv (v ); configString != "" {
69+ // todo: need to add a branch here to handle when the environment variable is
70+ // set to a raw levels string, and isn't JSON
6971 err := json .Unmarshal ([]byte (configString ), o )
7072 if err != nil {
7173 return fmt .Errorf ("parsing configuration from environment variable %v: %w" , v , err )
@@ -85,15 +87,21 @@ func resetBuiltInHandlerFns() {
8587 textHandlerFn := func (_ string , w io.Writer , opts * slog.HandlerOptions ) slog.Handler {
8688 return slog .NewTextHandler (w , opts )
8789 }
88- handlerFns . Store (TextHandler , textHandlerFn )
90+ registerHandlerFn (TextHandler , textHandlerFn )
8991 // for v1 compatibility, "console" is an alias for "text"
90- handlerFns . Store (ConsoleHandler , textHandlerFn )
91- handlerFns . Store (JSONHandler , func (_ string , w io.Writer , opts * slog.HandlerOptions ) slog.Handler {
92+ registerHandlerFn (ConsoleHandler , textHandlerFn )
93+ registerHandlerFn (JSONHandler , func (_ string , w io.Writer , opts * slog.HandlerOptions ) slog.Handler {
9294 return slog .NewJSONHandler (w , opts )
9395 })
94- handlerFns .Store (TermHandler , termHandlerFn (false ))
95- handlerFns .Store (TermColorHandler , termHandlerFn (true ))
96- handlerFns .Store (NoopHandler , func (_ string , _ io.Writer , _ * slog.HandlerOptions ) slog.Handler {
96+ registerHandlerFn (TermHandler , func (_ string , w io.Writer , opts * slog.HandlerOptions ) slog.Handler {
97+ termOpts := termHandlerOptions (opts )
98+ termOpts .NoColor = true
99+ return console .NewHandler (w , termOpts )
100+ })
101+ registerHandlerFn (TermColorHandler , func (_ string , w io.Writer , opts * slog.HandlerOptions ) slog.Handler {
102+ return console .NewHandler (w , termHandlerOptions (opts ))
103+ })
104+ registerHandlerFn (NoopHandler , func (_ string , _ io.Writer , _ * slog.HandlerOptions ) slog.Handler {
97105 return noop
98106 })
99107}
@@ -104,17 +112,23 @@ func initHandlerFns() {
104112 })
105113}
106114
107- func LookupHandlerFn (name string ) func ( string , io. Writer , * slog. HandlerOptions ) slog. Handler {
115+ func LookupHandlerFn (name string ) HandlerFn {
108116 initHandlerFns ()
109117 v , ok := handlerFns .Load (name )
110118 if ! ok {
111119 return nil
112120 }
113- return v .(func (string , io.Writer , * slog.HandlerOptions ) slog.Handler ) //nolint:forcetypeassert // if it's not a HandlerFn, we should panic
121+ // fn := v.(func(string, io.Writer, *slog.HandlerOptions) slog.Handler) //nolint:forcetypeassert // if it's not a HandlerFn, we should panic
122+ fn := v .(HandlerFn ) //nolint:forcetypeassert // if it's not a HandlerFn, we should panic
123+ return fn
114124}
115125
116- func RegisterHandlerFn (name string , fn func ( string , io. Writer , * slog. HandlerOptions ) slog. Handler ) {
126+ func RegisterHandlerFn (name string , fn HandlerFn ) {
117127 initHandlerFns ()
128+ registerHandlerFn (name , fn )
129+ }
130+
131+ func registerHandlerFn (name string , fn HandlerFn ) {
118132 if fn == nil {
119133 panic (fmt .Sprintf ("constructor for sink %q is nil" , name ))
120134 }
@@ -124,19 +138,26 @@ func RegisterHandlerFn(name string, fn func(string, io.Writer, *slog.HandlerOpti
124138 handlerFns .Store (name , fn )
125139}
126140
127- func termHandlerFn (color bool ) func (string , io.Writer , * slog.HandlerOptions ) slog.Handler {
128- return func (_ string , w io.Writer , opts * slog.HandlerOptions ) slog.Handler {
129- if opts == nil {
130- opts = & slog.HandlerOptions {}
131- }
132- return console .NewHandler (w , & console.HandlerOptions {
133- NoColor : ! color ,
134- AddSource : opts .AddSource ,
135- Theme : console .NewDefaultTheme (),
136- ReplaceAttr : opts .ReplaceAttr ,
137- TimeFormat : "15:04:05.000" ,
138- HeaderFormat : "%t %[" + LoggerKey + "]8h %l | %m" ,
139- TruncateSourcePath : 2 ,
140- })
141+ func termHandlerOptions (opts * slog.HandlerOptions ) * console.HandlerOptions {
142+ // todo: it would be nice if consumers could tweak this, either programatically
143+ // or via configuration, but that would mean exposing the dependency on console-slog,
144+ // which is currently opaque. For now, I want to keep this opaque. That means, if
145+ // a consumer was a slightly different configuration of console-slog, they will
146+ // have to construct it from scratch themselves.
147+ if opts == nil {
148+ opts = & slog.HandlerOptions {}
149+ }
150+ theme := console .NewDefaultTheme ()
151+ theme .Name = "flume"
152+ theme .Source = console .ToANSICode (console .BrightBlack , console .Italic )
153+ theme .AttrKey = console .ToANSICode (console .Green , console .Faint )
154+ return & console.HandlerOptions {
155+ AddSource : opts .AddSource ,
156+ ReplaceAttr : opts .ReplaceAttr ,
157+ Level : opts .Level ,
158+ Theme : theme ,
159+ TimeFormat : "15:04:05.000" ,
160+ HeaderFormat : "%t %[" + LoggerKey + "]8h |%l| %m %a %(source){→ %s%}" ,
161+ TruncateSourcePath : 2 ,
141162 }
142163}
0 commit comments