Skip to content

Get Started

This documents the core functionalities of the log package.

Setup

A logger is created from the Logger class. Setting write to TRUE will write every message logged to the file. The prefix is a string that will precede every message. The sep argument is the separator between the prefix and the rest of the message to the right, it defaults to a tab (t).

1
2
3
4
5
6
7
8
9
library(log)

# defaults
log <- Logger$new(
  prefix = "",
  write = FALSE,
  file = "log.log",
  sep = "\t"
)

Different loggers can write to the same file.

One can leave write as the default FALSE and later use the dump method to save it to a file.

Basic

After the logger has been instantiated one can use the log method to log a message to the console (and the file depending on whether that was set).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
log <- Logger$new(prefix = "INFO")

fnc <- function() {
  log$log("Something")
  Sys.sleep(.7)
  log$log("Something else")
}

fnc()
#> INFO       Something 
#> INFO       Something else

Flags

When setting up the logger one can customise it with “flags” so it includes a bit more information that might be useful to debug, e.g.: the time and date at which the message was logged. These will be written after the prefix and are placed in the order they are used (e.g.: date then time as shown below).

The date and time format can be customised with the format argument.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
logError <- Logger$new("ERROR")$
  date()$
  time()

fnc <- function() {
  logError$log("Oh no")
  Sys.sleep(.7)
  logError$log("Snap!")
}

fnc()
#> ERROR     19-12-2020 17:29:02 Oh no 
#> ERROR     19-12-2020 17:29:03 Snap!

Flags available:

  • date - current date
  • time - current time
  • unix - unix timestamp
  • wd - working directory

Tip

You can also customise the look of the prefix with hook, pass it a function that will take the prefix and return a modified version of it.

While the package comes with basic flags you can add your own with the flag method. This method accepts either a function that will be run every time a message is logged or a string that will simply be included in the message.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
random_flag <- function(){
  paste0(sample(letters, 3), collapse = "|")
}

l <- Logger$new("ERROR")$
  time()$
  flag("[README.md]")$
  flag(random_flag)

fnc <- function() {
  l$log("Oh no")
  Sys.sleep(.7)
  l$log("Snap!")
}

fnc()
#> ERROR     17:29:03 [README.md] w|e|g Oh no 
#> ERROR     17:29:04 [README.md] u|p|n Snap!

Hook

There is also the possibility to pass a “hook;” a function that will preprocess the prefix and return a modified version of it.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# using crayon to write the entire line red
logError$hook(crayon::red)

logError$log("Whoops!")
#> ERROR     19-12-2020 17:29:02 Whoops!

# fancier
hook <- function(x) {
  paste(crayon::blue(cli::symbol$info, x))
}

log <- Logger$new("INFO")$hook(hook)
log$log("Fancy this!?")
#> ℹ INFO     Fancy this!?

Tip

The package comes with default loggers, see templates

Dump

Finally you can dump the log to a file with dump.

1
log$dump("stuff.log")

Printer

By default log uses cli::cat_cli to print the messages, this can be changed via the printer field. It accepts a function that will be used to print messages, this function must accept a single argument: the message.

1
2
3
4
5
log <- Logger$new("PRINTER")
log$printer <- cli::cli_li

log$log("{.val something}")
#> ● PRINTER something

Predicate

The predicate field allows you to pass a predicate function that defines whether the logger actually runs. This very useful when debugging for instance.

If the predicate function returns TRUE then the logger runs, if it returns FALSE the logger does not print, write to file, or dump the log.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
log <- Logger$new("TEST")
log$predicate <- function(){
  getOption("DEBUG", FALSE)
}

# FALSE so not running
log$log("You should not see this")

# set debug to TRUE
options(DEBUG = TRUE)

log$log("You should now see this")
#> TEST      You should now see this