A modern modular JDK 21+ logging framework that offers implementations for multiple facades like SLF4J / System.Logger and does mostly what you want out of the box.
It is called rainbow gum after Eucalyptus Deglupta a beautiful tree native to Hawaii that has colorful bark (colorful logs).
In Rainbow Gum you can:
Environment
). Because Rainbow Gum is very modular it can provide a more "choose your own" experience where you can scale down and only use the JDK System.Logger
with minimal dependencies or scale up with fully loaded ANSI SLF4J experience.
In some cases just adding modules will provide automatic configuration.
Rainbow Gum's default property configuration follows Spring Boot's patterns so if you are familiar with logging.level...
than you will feel at home with Rainbow Gum whether you use Spring or not.
Regardless of which configuration option you choose it is GraalVM native friendly, Jlinkable, and initializes hella fast.
The long term goal of Rainbow Gum is to be a logging framework for all with the only requirement being a modern JDK.
The doc is also on javadoc.io but is not aggregated like the above.
The aggregated javadoc is the preferred documentation and the rest of this readme
is mainly for propaganda marketing purposes.
For previous releases:
https://jstach.io/doc/rainbowgum/VERSION/apidocs
Where VERSION
is the version you want.
This section is being rewritten and is a work in progress. Rainbow Gum is ready for production but the marketing is not.
In terms of features and complexity Rainbow Gum aims to be slightly more complicated than
slf4j-simple
but massively more simple than Log4J 2.
For example in ascending order of complexity/features:
Library | Version | Jar Size(s) KBs | Sum | Notes |
---|---|---|---|---|
slf4j-simple | 2.0.9 | 15 | 15 KB | Uses System.out PrintStream |
penna | 0.6 | 41 + 8 + 9 | 58 KB | Only does JSON currently |
rainbowgum | 0.1.0 | 200 + 20 | 220 KB | Requires JDK 21 and preview (optional) |
reload4j | 1.2.25 | 325 + 10 | 335 KB | JDK 1.5 uses synchronized on IO |
logback | 1.4.11 | 583 + 276 | 859 KB | Slightly complicated to configure |
log4j2 | 2.20.0 | 305 + 1847 + 23 | 2.1 MB! | Kitchen sink of features. log4jshell |
Of all the major general purpose logging implementations including Tiny Log, Rainbow Gum is the only one that requires JUST java.base!
(core and not extensions)
java.sql
module.java.xml
module. Logback requires it transitively!SLF4J
a non JDK module.What this means is Rainbow Gum can deliver a much smaller executable if packaged with Graal or JLink.
Consequently:
synchronized
for any IO.However:
Logback and Log4j 2.0 have complex APIs and offer very little opinion on what should be done OOB.
Both offer complex non-java (xml/properties/yaml) configuration that slows initialization down while increasing security surface area as indictive of log4j 2 shell.
Both are in the realms of megabytes in jar size which may not matter much for traditional java deployments but does matter for Graal VM Native or even plain Hotspot as well as CI pipelines that build uber jars.
Both may not be ready for Loom, Panama, Valhalla, SIMD. Both cannot change API easily as there are numerous libraries that depend on legacy API.
Also Rainbow Gum may provide adapters to use Logback or Log4j core components.
Finally ideas and features of Rainbow Gum could eventually make their way into logback and log4j 2.0.
Someone needs to keep experimenting and pushing forward. The current author of rainbowgum made it so Logback was programmatically configurable many moons ago. We plan on continuing that tradition of bringing what we learn back to the established frameworks.
Because I think this is a fundemental problem with most logging frameworks. It is one of the reasons why they are so bloated and complicated. Let other libraries do configuration and have them run first.
When logging tries to handle configuration there are initialization issues. Because so many logging frameworks are the first to execute they provide their own configuration framework.
What really should happen is the configuration framework should load first, capture events like warnings or info, and then provide or replay them when the logging framework starts. Libraries that participate in configuration really should not use logging and while SLF4J does provide some form of trampolining (ie queue while initializing) that is not the case for JUL or System logger.
Because many poorly designed configuration libraries needing logging and logging needs configuration in some cases I have seen log4j2 initialize more than 5 times during boot (spring boot) and for logback 3 times (dropwizard).
For configuration library that understands these bootstrapping problems I recommend avaje config or writing your own to load simple properties files. It is a shame there are not more bootstrapping configuration libraries as most configuration really is just Map<String,String>
.
Configuration stored as files in projects is just asking for different configuration spread across an organization.
While it is possible to pack up the files as resources in a shared jar this does not always work in a module-info
world
as well as GraalVM native as resources files need special considerations.
Because different logging needs are needed for different environments many logging frameworks offer complicated solutions like expression languages and whatever the fuck is "Arbiter" (log4j 2) that could easily be managed with a tiny bit of user Java code.
In Rainbow gum you do all your configuration in Java and can choose to leverage your existing configuration framework. You write a single service provider using a discoverable API of builders and then package it up in a Jar. It will be graal vm native friendly, initialize hella fast and no configuration drift.