Creating log files with R

R wallpaper

In this short post, I explain how creating log files with R using log4r package.

Scenario

So, I want to create a custom log for debugging.

Solution

log4r is a fast, lightweight, object-oriented approach to logging in R based on the widely-emulated Apache Log4j project.

log4r differs from other R logging packages in its focus on performance and simplicity. As such, it has fewer features – although it is still quite extensible, as seen below – but is much faster. See vignette("performance", package = "log4r") for details.

Installation

The package is available from CRAN:

 install.packages("log4r") 

If you want to use the development version, you can install the package from GitHub as follows:

 # install.packages("remotes") remotes::install_github("johnmyleswhite/log4r") 

Usage

Logging is configured by passing around logger objects created by logger(). By default, this will log to the console and suppress messages below the "INFO" level:

 logger <- logger() info(logger, "Located nearest gas station.") #> INFO [2019-09-04 16:31:04] Located nearest gas station. warn(logger, "Ez-Gas sensor network is not available.") #> WARN [2019-09-04 16:31:04] Ez-Gas sensor network is not available. debug(logger, "Debug messages are suppressed by default.") 

Logging destinations are controlled by Appenders, a few of which are provided by the package. For instance, if we want to debug-level messages to a file:

 log_file <- tempfile() logger <- logger("DEBUG", appenders = file_appender(log_file)) info(logger, "Messages are now written to the file instead.") debug(logger, "Debug messages are now visible.") readLines(log_file) #> [1] "INFO [2019-09-04 16:31:04] Messages are now written to the file instead." #> [2] "DEBUG [2019-09-04 16:31:04] Debug messages are now visible." 

The appenders parameter takes a list, so you can log to multiple destinations transparently.

To control the format of the messages you can change the Layout used by each appender. Layouts are functions; you can write your own quite easily:

 my_layout <- function(level, ...) { paste0(format(Sys.time()), " [", level, "] ", ..., collapse = "") } logger <- logger(appenders = console_appender(my_layout)) info(logger, "Messages should now look a little different.") #> 2019-09-04 16:31:04 [INFO] Messages should now look a little different. 

Real implementation

This example will give you log messages in the console output and in a text file. So, after loading the package we have four statements that setup the logging:

  • set the name of the text file that will contain the log messages
  • define the function that will write messages to the console (all default arguments)
  • define the function that will write messages to the text file (all default arguments except the name of the text file)
  • indicate that you want to use logging messages with severity INFO and higher with the functions you just defined

Then I define three functions as examples of a log call for resp. the INFO, ERROR and DEBUG level.
In your algorithm you will insert the log4r::infolog4r::error and log4r::debug calls at the points where you want them.

So, I call the three functions and at the end I show that the text file indeed contains the same messages that are shown in the console output.

 library(log4r) #> #> Attaching package: 'log4r' #> The following object is masked from 'package:base': #> #> debug my_logfile = "my_logfile.txt" my_console_appender = console_appender(layout = default_log_layout()) my_file_appender = file_appender(my_logfile, append = TRUE, layout = default_log_layout()) my_logger <- log4r::logger(threshold = "INFO", appenders= list(my_console_appender,my_file_appender)) log4r_info <- function() { log4r::info(my_logger, "Info_message.") } log4r_error <- function() { log4r::error(my_logger, "Error_message") } log4r_debug <- function() { log4r::debug(my_logger, "Debug_message") } log4r_debug() # will not trigger log entry because threshold was set to INFO log4r_info() #> INFO [2020-07-01 12:48:02] Info_message. log4r_error() #> ERROR [2020-07-01 12:48:02] Error_message readLines(my_logfile) #> [1] "INFO [2020-07-01 12:48:02] Info_message." #> [2] "ERROR [2020-07-01 12:48:02] Error_message" 

More about R

So, this is how you are creating log files with R. Here some more posts about it:

Related posts

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.