lmittmann / tint

🌈 slog.Handler that writes tinted (colorized) logs

Home Page:https://pkg.go.dev/github.com/lmittmann/tint

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

feature request: support for custom message prefix

dpotapov opened this issue · comments

zerolog.ConsoleWriter has a nice feature to print "caller" at the beginning of a message line. Caller by default is being set to <filename>:<number> (just like the AddSource feature), but the user can easily override it.

Could we introduce a similar capability in tint?

11:00PM INF main > Starting server addr=: 8080 env=production
11:00PM DBG main > Connected to DB db=myapp host=localhost: 5432
11:00PM WRN database > Slow request method=GET path=/users duration=497ms
11:00PM ERR database > DB connection lost err="connection reset" db=myapp

You can change the printed source using tint.Options.ReplaceAttr like this:

logger := slog.New(tint.NewHandler(os.Stderr, &tint.Options{
	AddSource: true,
	ReplaceAttr: func(groups []string, attr slog.Attr) slog.Attr {
		if attr.Key == slog.SourceKey {
			src := attr.Value.Any().(*slog.Source)
			// extract the info you want from slog.Source...
			// NOTE: if you also need coloring, you need to manage this here yourself
			return slog.String(slog.SourceKey, /* ... */)
		}
		return attr
	},
}))
logger.Info("test")

Feel free to reopen the issue if this does not solve your issue.

Hi, sorry for re-opening the issue, I just wasn't able to achieve what I wanted...

Let's say I want to have a field named "module" to be printed in front of a message, e.g.:

slog.Error("Connection failure", "module", "database")

# to produce:
ERR database > Connection failure

I'm trying to create a replacer where I'm removing the original slog.SourceKey (I don't want to print the native source info) and replacing "module" field name with slog.SourceKey to let the tint handle the logic for prefixing:

ReplaceAttr: func(groups []string, attr slog.Attr) slog.Attr {
	if attr.Key == "module" {
		return slog.String(slog.SourceKey, attr.Value.String() + " >")
	}
	if attr.Key == slog.SourceKey {
		return slog.Attr{}
	}
	return attr
},

It just doesn't work as expected:

ERR Connection failure source=database

Appreciate any help!

Tint writes logs in an opinionated way and tries to stay close to the slog.TextHandler API. It does not provide a way to reorder the standard arguments time, level, src or message.

However, if your module is in fact the package of the source file you could do this:

logger := slog.New(tint.NewHandler(os.Stderr, &tint.Options{
	AddSource: true,
	ReplaceAttr: func(g []string, a slog.Attr) slog.Attr {
		if a.Key == slog.SourceKey {
			src := a.Value.Any().(*slog.Source)
			return slog.String(slog.SourceKey, filepath.Base(filepath.Dir(src.File))+" >")
		}
		return a
	},
}))
logger.Info("test")