Package eslog implements a slog.Handler that writes prettier logs. Two modes are supported: pretty and json.
Supported logging levels:
- Trace
- Debug
- Info
- Warn
- Error
- Fatal
Logging formatting in Pretty mode. In this mode, it's easy to navigate to the file position where the log was called.
Logging formatting in JSON mode.
go get github.com/eliofery/eslog
// Configures the logger with the specified settings.
config := eslog.Config{
Level: "info", // trace, debug, info, warn, error, fatal (info: default)
AddSource: true,
JSON: false,
}
// Sets the logging level.
lvl := new(slog.LevelVar)
lvl.Set(config.Leveler())
// Creates a new instance of eslog with the configured settings.
logger := eslog.New(pretty.NewHandler(os.Stdout, &pretty.HandlerOptions{
SlogOptions: &slog.HandlerOptions{
Level: lvl,
AddSource: config.AddSource,
},
JSON: config.JSON,
}), lvl)
// Overrides the logging level.
logger.SetLevel(eslog.LevelTrace)
//logger.SetLevel(slog.LevelDebug)
//logger.SetLevel(slog.LevelInfo)
//logger.SetLevel(slog.LevelWarn)
//logger.SetLevel(slog.LevelError)
//logger.SetLevel(eslog.LevelFatal)
// Logs messages at different levels.
logger.Trace("Trace example", slog.Any("message", "trace message"))
logger.Debug("Debug example", slog.Any("message", "debug message"))
logger.Info("Info example", slog.Any("message", "info message"))
logger.Warn("Warn example", slog.Any("message", "warn message"))
logger.Error("Error example", slog.Any("message", "error message"))
logger.Fatal("Fatal example", slog.Any("message", "fatal message"))
ReplaceAttr can be used to alter or drop attributes. See slog.HandlerOptions for details.
lvl := new(slog.LevelVar)
lvl.Set(slog.LevelInfo)
eslog.New(pretty.NewHandler(os.Stdout, &pretty.HandlerOptions{
SlogOptions: &slog.HandlerOptions{
ReplaceAttr: func(_ []string, a slog.Attr) slog.Attr {
switch a.Key {
case slog.SourceKey:
return func(a slog.Attr) slog.Attr {
source := a.Value.Any().(slog.Source)
pwd, err := os.Getwd()
if err != nil {
return a
}
relPath, err := filepath.Rel(pwd, source.File)
if err != nil {
return a
}
basePath := filepath.Base(relPath)
formattedPath := fmt.Sprintf("%s:%d", basePath, source.Line)
return slog.Attr{
Key: a.Key,
Value: slog.StringValue(formattedPath),
}
}(a)
case slog.LevelKey:
return func(a slog.Attr) slog.Attr {
l := a.Value.Any().(slog.Level)
a.Value = slog.StringValue(l.String())
return a
}(a)
case slog.TimeKey:
return func(a slog.Attr) slog.Attr {
const timestampFormat = "2006-01-02 15:04:05.999999999 -0700 -07"
t, err := time.Parse(timestampFormat, a.Value.String())
if err != nil {
return a
}
formattedTime := t.Format(time.DateTime)
a.Value = slog.StringValue(formattedTime)
return a
}(a)
default:
return a
}
},
},
}), lvl)
You can still use methods from the standard package slog.
lvl := new(slog.LevelVar)
lvl.Set(eslog.LevelTrace)
// NewTextHandler
eslog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{}), lvl)
// NewJSONHandler
eslog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{}), lvl)