logger
A lightweight, modern and flexibly logging utility for R -- heavily inspired by the futile.logger
R package and logging
Python module.
Installation
install.packages('logger')
The most recent, development version of logger
can also be installed from GitHub:
remotes::install_github('daroczig/logger')
Quick example
Setting the log level threshold to something low and logging various messages in ad-hoc and programmatic ways:
library(logger)
log_threshold(DEBUG)
log_info('Script starting up...')
#> INFO [2018-20-11 22:49:36] Script starting up...
pkgs <- available.packages()
log_info('There are {nrow(pkgs)} R packages hosted on CRAN!')
#> INFO [2018-20-11 22:49:37] There are 13433 R packages hosted on CRAN!
for (letter in letters) {
lpkgs <- sum(grepl(letter, pkgs[, 'Package'], ignore.case = TRUE))
log_level(if (lpkgs < 5000) TRACE else DEBUG,
'{lpkgs} R packages including the {shQuote(letter)} letter')
}
#> DEBUG [2018-20-11 22:49:38] 6300 R packages including the 'a' letter
#> DEBUG [2018-20-11 22:49:38] 6772 R packages including the 'e' letter
#> DEBUG [2018-20-11 22:49:38] 5412 R packages including the 'i' letter
#> DEBUG [2018-20-11 22:49:38] 7014 R packages including the 'r' letter
#> DEBUG [2018-20-11 22:49:38] 6402 R packages including the 's' letter
#> DEBUG [2018-20-11 22:49:38] 5864 R packages including the 't' letter
log_warn('There might be many, like {1:2} or more warnings!!!')
#> WARN [2018-20-11 22:49:39] There might be many, like 1 or more warnings!!!
#> WARN [2018-20-11 22:49:39] There might be many, like 2 or more warnings!!!
Setting a custom log layout to render the log records with colors:
library(logger)
log_layout(layout_glue_colors)
log_threshold(TRACE)
log_info('Starting the script...')
log_debug('This is the second log line')
log_trace('Note that the 2nd line is being placed right after the 1st one.')
log_success('Doing pretty well so far!')
log_warn('But beware, as some errors might come :/')
log_error('This is a problem')
log_debug('Note that getting an error is usually bad')
log_error('This is another problem')
log_fatal('The last problem')
Or simply run the related demo:
demo(colors, package = 'logger', echo = FALSE)
But you could set up any custom colors and layout, eg using custom colors only for the log levels, make it grayscale, include the calling function or R package namespace with specific colors etc. For more details, see the related vignettes.
Why yet another logging R package?
Although there are multiple pretty good options already hosted on CRAN when it comes to logging in R, such as
futile.logger
: probably the most popularlog4j
variant (and I'm a big fan)logging
: just like Python'slogging
packageloggit
: capturemessage
,warning
andstop
function messages in a JSON filelog4r
:log4j
-based, object-oriented loggerrsyslog
: logging tosyslog
on 'POSIX'-compatible operating systemslumberjack
: provides a special operator to log changes in data
Also many more work-in-progress R packages hosted on eg GitHub, such as
- https://github.com/smbache/loggr
- https://github.com/nfultz/tron
- https://github.com/metrumresearchgroup/logrrr
- https://github.com/lorenzwalthert/drogger
- https://github.com/s-fleck/yog
But some/most of these packages are
- not actively maintained any more, and/or maintainers are not being open for new features / patches
- not being modular enough for extensions
- prone to scoping issues
- using strange syntax elements, eg dots in function names or object-oriented approaches not being very familiar to most R users
- requires a lot of typing and code repetitions
So based on all the above subjective opinions, I decided to write the n+1
th extensible log4j
logger that fits my liking -- and hopefully yours as well -- with the focus being on:
- keep it close to
log4j
- respect the most recent function / variable naming conventions and general R coding style
- by default, rely on
glue
when it comes to formatting / rendering log messages, but keep it flexible if others prefersprintf
(eg for performance reasons) or other functions - support vectorization (eg passing a vector to be logged on multiple lines)
- make it easy to extend with new features (eg custom layouts, message formats and output)
- prepare for writing to various services, streams etc
- provide support for namespaces, preferably automatically finding and creating a custom namespace for all R packages writing log messages, each with optionally configurable log level threshold, message and output formats
- allow stacking loggers to implement logger hierarchy -- even within a namespace, so that the very same
log
call can write all theTRACE
log messages to the console, while only pushingERROR
s to DataDog and egINFO
messages to CloudWatch - optionally colorize log message based on the log level
- make logging fun
Welcome to the Bazaar, and if you have happened to already use any of the above mentioned R packages for logging, you might find useful the Migration Guide.
Interested in more details?
Check out the main documentation site at https://daroczig.github.io/logger or the vignettes on the below topics: