Securing the Fundamentals: Our Support for Log4j
sovereigntechfund.de
sovereigntechfund.de
The state of software security seems truly abysmal. Which is no surprise, given that many companies outsource development, receive a working product, and then the development team moves on and no one ever seems to bother with security maintenance.
I like minimal application configuration and find the “configuration surface” offered by most logging libraries much too large and also see it as a burden for users to learn/google the configuration file format of the chosen implementation.
I prefer to offer minimal and ergonomic logging configuration options. Analogous to basic “-q”, “-v”, “-d” options typical of command line programs, which my code translates to whatever logging framework.
And you don’t end up spending ages fiddling with slf4f and other exclusions and version range stuff in maven.
A very very very close second is figuring out where to put the fucking config file so the app will pick it up in preference to whatever defaults or packaged settings are.
There's an article on the feed today about events that was hitchikers something and then threw about 10 more layers of sarcasm and meme on the subject, and one of the frustrations I have with current logging frameworks is that a truly mature logging framework needs a LOT of interesting things:
- how about a per-user log? - how about a per-core or per-node log? - how about a per-request log? - event extraction and publishing
And of course the issue of cross-system-boundary tracking/tracing.
Sure, log aggregation and mining can help, but it seems like a very very big expensive hammer for an intricate peg and hole.
Anyway, Log4j was written from the age of computer science where computers were single machine monoliths with a database (two-tier or three-tier: that's right systems architect in two or three boxes rather than https://www.youtube.com/watch?v=y8OnoxKotPQ
1) It's a decent API. Simple, easy to use.
2) you don't control what your library dependencies use. This can be a mix of log4j, log4j2, java util logging, and commons-logging. These are all commonly used in libraries. If you don't use slf4j, you end up with a console full of messages that are formatted slightly different from each other.
So even if you use JUL logging, you should use slf4j to ensure some uniformity. And if you do that, you might as well take the next step and format your logs properly using log4j2 or logback. It's not that hard with slf4j, you can use any of the common logging APIs and it will all end up in the same place.
If you use most common server frameworks (e.g. Spring), you have no choice. Slf4j is going to be on the classpath and it will likely come in via any number of other dependencies as well.
It's an old and tired API, inefficient, slow... you can do better by using the newer System.Logger which fixes those issues, mostly: https://docs.oracle.com/en/java/javase/17/docs/api/java.base...
And of course the python logging library was inspired on it. Sigh...
One part of the std python lib that needed a big overhaul
People still write tutorials about the obsolete HttpUrlConnection in 2023, when HttpClient exists.
In fact, almost every API in the Java standard library is bad and once they realize the necessity to replace it, they add a second actually usable API that nobody uses.
Separating how logs are formatted and published from how you log from your code is a good idea. This is essentially what slf4j does. It will happily intercept java util logging, log4j, and other common logging APIs using API compatible stubs for each of these and redirect them to your preferred logging framework. What things like log4j2 and logback offer is a lot of control over how the logs are processed, formatted, and published.
Logback has plugins, appenders for different logging backends, etc. I actually have my own plugin for logback that writes logs straight to a remote elasticsearch cluster. It does things like add MDC (mapped diagnostic context) fields and selected environment variables to the json blob that it sends to elasticsearch and a few more useful things. That makes it easy to make logging dashboards. Log4j2 has similar features. Java util logging is a bit barebones. It's what you use when you really don't care about your logs.
util logging and commons logging weren't nearly as good, although I don't recall specifically why. jdk logging was fine-finer-finest and some other weird things
Ultimately what is important in javaland is adopting SLF4J and then delegating to whatever you want to use beyond that for the actual logging.