Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
I will be pushing a new version of futile.logger (version 1.5) to CRAN in January. This version introduces a number of enhancements and fixes some bugs. It will also contain at least one breaking change. I am making the release process public, since the package is now used in a number of other packages. If you use futile.logger, this is your opportunity to influence the direction of the package and prepare for changes. Please use the github issue tracker for discussion.
There are two main themes for enhancements: 1) integration with the signal conditions, and 2) supporting multiple appenders with different thresholds.
Hijacking the signal system
Currently, futile.logger is unaware of the signal system in R. The only tie-in is with ftry
, which catches a warning or error and prints a message. Unfortunately, the behavior is different from try
. This release will make ftry
consistent with try
. This is a breaking change, so if you use ftry
in your code, it will no longer halt processing.
In addition to this fix, futile.logger will now have better integration with the signal system. Currently, if a function emits a warning or an error, these are printed to the screen. It would be convenient if futile.logger can capture these signals and associate them to the correct log levels, i.e. warning to WARN and error to ERROR.
My proposal is to create a hijack_signal_handlers
function to override the existing signal handlers. This function can be called at the top of a script or within the .onLoad
function of a package. Once called, any warnings or errors would be captured and handled by futile.logger. The implementation would look like this, giving granular control of whether to hijack just warning, errors, or both:
hijack_signal_handlers <- function(warning=TRUE, error=TRUE) { if (warning) { # Override warning handler } if (error) { # Override error handler } }
One issue I see with this function is when used in a package’s .onLoad. Suppose a user requires package A and B. These don’t use futile.logger. Now the user requires package C, which calls hijack_signal_handlers
in its .onLoad
. When this occurs, warnings and errors emitted from packages A and B would also be captured by futile.logger. From my perspective, this is probably a good thing, but I can appreciate why others may not want this behavior.
Emitting signals
The other half of the signal handler puzzle is being able to emit signals from futile.logger. For this case, we want flog.warn
to emit a warning signal and flog.error
to emit an error signal. One signature looks like
flog.warn(message, emit=TRUE)
meaning that by default no signal is emitted. This would work for flog.warn
, flog.error
, and flog.fatal
(could map to error as well).
I have mixed feelings about this use case. Part of me says if futile.logger hijacks the signal system, then just use stop and futile.logger will catch it. On the other hand that seems roundabout and less capable than writing flog.error(message, emit=TRUE)
or whatever.
Really my main concern is what happens when these two systems work together? Will they play nice or will an error be emitted twice (likely)? If not, then there is more logic that has to be built in, which ultimately adds complexity and wastes cycles. Any input here is encouraged!
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.