Tools and testing for log/slog
(hereafter just slog
) handlers.
Recent benchmark data is available via GitHub Pages.
See the source or documentation for more detailed documentation.
- Test harness for benchmarking
slog
handler performance - Test harness for verifying
slog
handler functionality - Web Server that processes output of previous two steps and provides access to result.
- Static copies of server pages provided via GitHub Pages.
- Functions for use with
slog.HandlerOptions.ReplaceAttr
- Utility to redirect internal
gin
logging toslog
- Demo Handlers
- Template for repository use
- Test handler
trace.Handler
Benchmarks of slog
handlers can be done by creating
simple _test.go
files that utilize the bench/test.SlogBenchmarkSuite
located in this repository.
Usage details for this facility are provided in
the README
file
located in the bench
package directory.
Benchmarks are intended to compare multiple handlers.
This repository is configured to test all known, functional slog
handlers that generate JSON.
The benchmark data generated can be processed by two applications:
tabular
generates a set of tables, each of which compares handlers for a given benchmark test.server
runs a simple web server showing the same tables plus bar charts and handler verification warnings.
Verification of slog
handlers can be done by creating
simple _test.go
files that utilize the verify/test.SlogTestSuite
located in this repository.
Usage details for this facility are provided in
the README
file
located in the verify
package directory.
Verification testing is intended to test a single handler or to compare multiple handlers.
This repository is configured to test all known, functional slog
handlers that generate JSON.
The tests implemented herein were inspired by:
- the
slogtest
application, - rules specified in
the
log/slog.Hander
and handler writing guide documentation, - issues I noticed while exploring
go-logging-benchmark
- as well as some other test cases that seemed useful.
The cmd/server
application is intended to process the benchmark and verification output and
display it on a series of web pages.
The pages display:
- handler data: benchmarks and warnings
- bench test data: benchmarks and warnings
- verification test data: warnings
- warning definitions and coverage
The benchmark data is displayed as a table
(similar to cmd/tabular
) and
as a series of bar charts comparing tests for a handler or handlers for a test.
Server pages are generated on a weekly basis using GitHub Actions and Pages. The GitHub Action:
- updates libraries used by this repository
- builds and runs:
- handler benchmarks,
- handler verifications, and
- the
cmd/server
application
- at which point the
wget
tool is used to copy the server pages into thedocs
subdirectory.
The pages in the docs
subdirectory are then
vended by GitHub Pages.
A small collection of functions in the
replace
package
can be used with slog.HandlerOptions.ReplaceAttr
.
These functions are intended to "fix" some of the verification issues with various handlers.
Package gin
contains utilities for using slog
with
gin-gonic/gin
.
In particular, this package provides
gin.NewWriter
which can be used to redirect Gin-internal logging.
Several new slog
handlers are available.
The sloggy
package defines a feature-complete, green field slog.Handler
implementation.
This can be used as is, though it is admittedly slower than slog.JSONHandler
(also feature-complete and generally used as the model for correct functionality).
It might be useful as a starting point for other, better implementations.
The flash
package is a copy of sloggy
with subsequent performance-enhancing edits.
It is just as feature-compliant and much faster, now in the group of "fastest" handlers
(slog/JSONHandler
, phsym/zeroslog
, and chanchal/zaphandler
,
though only the first of these is feature-complete).
Profiling of the verification and benchmark code shows almost all CPU cycles
used for formatting various data items into []byte
buffers.
It is possible that the slog/JSONHandler
and madkins/flash
handlers
have reached something like the theoretical speed limit for fully functional slog
handlers.
At this point flash
may be as usable as slog.JSONHandler
,
though the latter may be a smarter choice as it is supported by the core Go team.
The flash
handler also supports
flash.Extras
options.
The documented slog.HandlerOptions
continue to be supported.
The optional flash.Extras
options can be used to adjust output somewhat
in order to achieve compatability with previous logging solutions.
The "trace" handler trace.Handler
doesn't log anything,
it just prints out the slog.Handler
interface calls it receives.
These test suites can be linked into any slog.Handler
repository.
The advantage would be quicker feedback on changes in progress in your code.
A template
package
is provided to make installation and usage as simple as possible.
The tests in this repository only apply to slog
JSON output.
Console output can come in a variety of formats and
generally doesn't have a performance issue as only humans will look at it.
Your response to this repository, especially if you are a slog
handler author,
may well be one or more of:
- "Why does this exist?"
- "Who are you to make these rules?"
These are reasonable questions.
The genesis of this repository was the author noticing that different
slog
handlers had varying outputs.
The author wanted to provide a way to compare the outputs,
because it seemed important (or at least personally interesting).
Over time the project grew to include handler benchmarks and a lot of other stuff.
The author has no authority to dictate slog
handler behavior.
The intent of this project was to measure handlers against each other and
published documentation.
Benchmark and verification tests come from slog
documentation,
the slogtest
test harness, and tests embedded in
betterstack-community/go-logging-benchmarks.
Warnings generated by these tests pretty much defined themselves (with the author's help, of course).
Each test and/or warning is based on some sort of justification. This justification is reflected in documentation and comments throughout the code. It should be possible to follow this trail of bread crumbs to justify each test or warning. Whether the reader agrees with this justification is subjective.
The several levels of verification tests are defined based on the strength of justification:
- Required
Justified from requirements in theslog.Handler
documentation. - Implied
Implied by documentation but can't be considered required. - Suggested
Not mandated by any documentation or requirements. These are the ones that the author just made up because they seemed appropriate. - Administrative
Information about the tests or conflicts with other warnings.
- You don't have to pay attention to any of this. Really.
- If you do pay attention, you should probably work down from
Required
warnings. - Consider your users' viewpoint...
- Are you confident that the
slog
handler you choose will be fine forever? - If you need to swap out
slog
handlers will the new one support your usage of the old one?- Should your code use only generally supported features even if more useful ones are available?
- Are you prepared to change logging statements to use a less functional handler?
- Consider the trade-off between performance and functionality.
- Do you need faster logging without support for picky warnings?
- Do you need full support of all verification tests at the cost of performance?
The author considers the interoperability of logging via slog
to be very important,
and possibly the best aspect of slog
logging.
Editing every log statement in a large project can be a real pain.
Slog Documentation
Slog Handlers
The following handlers are currently under test in this repository:
chanchal/zaphandler
madkins/flash
madkins/replattr
madkins/sloggy
phsym/zeroslog
phuslu/slog
samber/slog-logrus
samber/slog-zap
samber/slog-zerolog
slog/JSONHandler
Handlers that have been investigated and found wanting:
-
darvaza
handlers are based on a different definition oflog/slog
as an interface that is not compatible with the "real"log/slog/Logger
. Since the latter is not an interface there is no way to build a shim. In addition, there is no separateHandler
object. -
Some handlers are still using
golang.org/x/exp/slog
instead of the standard librarylog/slog
: -
The
trim21/slog
handler is documented as "immature". -
The
go-logr/zerologr
handler presents some challenges:- Wraps
go-logr/logr
around ars/zerolog
logger (not a handler),
then wraps another layer (zerologr.LogSink
) around that to return aslog.Handler
. - Doesn't support
slog.HandlerOptions
directly. - Configuring a default
slog.Level
per handler is difficult.- Negative integers are unsupported so levels must be "fixed" in use.
- Higher numbers are less important, whereas in
slog
lower numbers (including negative numbers) are less important so everything must be reversed. - The
Enabled()
implementation uses both local level value and
the globalzerolog
level so the per-handler/logger level isn't truly local.
- Wraps
Console handlers are not tested in this repository,
but the author likes this one (and uses it in cmd/server
):
Miscellaneous
- Awesome
slog
list of link to variousslog
-related projects and resources. - Go Logging Benchmarks
- Benchmarks of various Go logging packages (not just
slog
loggers). - Used GitHub Action in this project as template for generating GitHub Pages for the current repository.
- Benchmarks of various Go logging packages (not just