5fc919e5233c21c3ea740de1149fb3657a48ce23
Every handler in this package accepts slog attributes and then throws
them away: Handle never reads record.Attrs, and WithAttrs and WithGroup
return the receiver unchanged in ConsoleHandler, JSONHandler and
WebhookHandler alike. So slog.Info("casting", "device", d, "file", f)
emits the message and silently loses both fields, which makes properly
structured logging carry less information than the interpolated
log.Printf calls it replaces.
The test asserts on the bytes the handlers actually write - os.Stdout
for the console and JSON handlers, the posted body for the webhook
handler - rather than on internal state, because the output is where the
loss is observable. It covers record attributes, WithAttrs accumulation,
WithAttrs not mutating its receiver so sibling loggers cannot leak
attributes into each other, WithGroup qualification, slog.Group nesting,
and LogValuer resolution, for each handler and through MultiplexHandler.
It also pins the properties a fix must not get wrong on the way past. A
value the caller logged is read and never written to, even when a group
later claims the same key - for maps and for slices, through the record
path and the derived-logger path, in all three handlers. A duration is
a number of nanoseconds in the json payload and the readable "3s" form
on the console. The four slog.Handler contract edge cases hold: an empty
Attr is ignored, an empty group is elided with its key, a group with an
empty key is inlined, and WithGroup("") is a no-op. And the two rules
that follow from the json payload being an object hold too: the record's
own field names win a collision, and a repeated key keeps its last
value, where the console line keeps both.
This commit adds only the test, and it fails. The fix follows.
Refs: #19
simplelog
Summary
simplelog is an opinionated logging package designed to facilitate easy and structured logging in Go applications with an absolute minimum of boilerplate.
The idea is that you can add a single import line which replaces the
stdlib log/slog default handler, and solve the 90% case for logging.
Current Status
Released v1.0.0 2024-06-14. Works as intended. No known bugs.
Features
- if output is a tty, outputs pretty color logs
- if output is not a tty, outputs json
- supports delivering each log message via a webhook
Planned Features
- supports delivering logs via tcp RELP (e.g. to remote rsyslog using imrelp)
Installation
To use simplelog, first ensure your project is set up with Go modules:
go mod init your_project_name
Then, add SimpleLog to your project:
go get sneak.berlin/go/simplelog
Usage
Below is an example of how to use SimpleLog in a Go application. This
example is provided in the form of a main.go file, which demonstrates
logging at various levels using structured logging syntax.
package main
import (
"log/slog"
_ "sneak.berlin/go/simplelog"
)
func main() {
// log structured data with slog as usual:
slog.Info("User login attempt", slog.String("user", "JohnDoe"), slog.Int("attempt", 3))
slog.Warn("Configuration mismatch", slog.String("expected", "config.json"), slog.String("found", "config.dev.json"))
slog.Error("Failed to save data", slog.String("reason", "permission denied"))
}
License
Languages
Go
89.6%
Dockerfile
4.6%
Makefile
3.8%
Shell
2%