This is going to be a quick blog post about dynamic logging – changing the logging behavior of the application while it's still running without recompiling.
The code is available at https://github.com/wsargent/blindsight-groovy.
Dynamic logging is important for diagnostic purposes, when you want to investigate a particular bug, and for bandwidth purposes, when you want to stop a particular logging message spamming you. I've talked a bit about enabling targeted logging using feature flags and conditions, but this does require some extra set up, and there are simpler solutions.
or on the statement itself:
A condition has to return
Boolean but is intentionally left open so that anything can be a condition. This means that
we can tie a condition to a JSR 223 script.
In this example, we'll use Groovy to evaluate a condition and return a boolean.
So. We run the program. While the program is running, we edit the Groovy script. The code will reload the script as soon as the file's last modification date is changed, and we can turn on and off individual logging statements at run time.
Here's the example program:
One of the things we get for free in Scala is source code location access using SourceCode.
When we log using
cm.condition(), the enclosing method and file name is compiled into the code using macros, so
the code really looks like this:
From there, we can expose that
Enclosing to the script:
So the end result is that you can turn off or on logging on a method basis, without touching Logback, having to write a
special filter, or integrating with feature flags. For example, we flip
com.tersesystems.blindsight.groovy.Main.logInfoSpecial to return
true instead of
false and you can see it pop up
Because this is a full on Groovy script, you can also add arbitrary logic into it, for example sampling, adding
temporal logic, calling out to system properties and environment variables, and even call
System.exit(). This level of
power does mean that it's a security risk, but you can use a different scripting language like
Tweakflow that gives the application more power over execution.
Also note that this is an intentionally trivial example for the purposes of demonstration, and a condition source may come from any text-base stream, so Redis, Consul KV, or ctlstore all work as places where you can store conditions.