I did a couple of small projects over the holidays while drinking coquito, so here they are.
TL;DR I made a very smol dynamic logging project, and migrated terse-logback-showcase from Heroku to fly.io. It's now https://terse-logback-showcase.fly.dev/ and it has pictures of cats.
The first is a "simplest possible dynamic logging" project called dynamic-logback. This is a project that sets up Logback, and then periodically refreshes log levels from a file. The functionality is in one file and is less than 100 lines of code. (After writing this, I did a search on "dynamic logback" on Github and discovered https://github.com/syamantm/dynamic-logback which is a more complete example.)
Anyway, the point is that dynamic logging is easy! You don't need a lot of infrastructure or to set up a database, you can just set up a timer task and be done with it.
There is an assumption that changing log levels requires a total configuration refresh. This is not helped by the documentation that only mentions autoscan as an option, and encourages the setting of levels directly in
logback.xml. The reality is that reloading only applies to Logback appenders and their ancillary supports. Log levels can be queried and modified without any heavy lifting. In SQL terms, appenders and filters are the
DDL statements, while querying and changing log levels are the
To abstract it from Log4J/Logback APIs, you could add a
LogLevelResult interaction for querying log levels, and a
LogLevelEvent for modifying log levels, and that would allow for a CQRS style API. That's probably for another project though.
Migrating terse-logback-showcase from Heroku to fly.io
The showcase application used to be on Heroku, but they closed down their free tier. Luckily, fly.io has an option for deploying docker containers.
The application runs on Play Framework, which is JVM based and has built in docker deployment via sbt-native-packager, so the only thing I needed to for a
Dockerfile was run
sbt docker:publishLocal. Play itself takes up barely any memory, but the JVM is used to having a bunch of memory available – the free tier is only 256 MB, so it was time to get creative.
ibm-semeru-runtimes:open-17-jre-focal image with
-XX:MaxRAM=70m was enough to get the JVM started, based on a tip from the community forums.
Then, I had to add the explicit
add-opens required by JDK 17 as
--illegal-access=permit is gone. I don't think there's any way to avoid this for now.
I had to make sure the internal sqlite database used by Blacklite was writable:
And I had to disable the PID file:
You can see build.sbt for the actual implementation.
For some reason the
logs directory wouldn't be created by
sbt docker:publishLocal so I added it to
dist directory for deployment:
I didn't have to set up HTTPS or anything special for fly.toml. I did have to set up some fly secrets:
and then it was just a case of creating docker images and running
And now https://terse-logback-showcase.fly.dev/ is up! It has pictures of cats.