Advertisement
R wallpaper
Advertisement

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.

Advertisement

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:

Advertisement

By Enrico

My greatest passion is technology. I am interested in multiple fields and I have a lot of experience in software design and development. I started professional development when I was 6 years. Today I am a strong full-stack .NET developer (C#, Xamarin, Azure)

Leave a Reply

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

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.