---
title: "Logger Comparison"
author: "Stefan Fleck"
date: "`r Sys.Date()`"
output: 
  html_document:
    toc: true
    number_sections: true
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)

library(devtools)
library(bench)
library(dplyr)
library(forcats)

```

```{r eval = FALSE}
install_github("daroczig/logger")
install.packages("log4r")
install.packages("futile.logger")
install.packages("logging")
```

```{r}
library(lgr)
library(logger)
library(log4r)
library(futile.logger)
```



Setup packages that do not work out-of-the-box
```{r}
logging::addHandler(logging::writeToConsole, logger="logging")

lgr::lgr$info("an informative message")
logging::loginfo("an informative message")
futile.logger::flog.info("an informative message")

```

# Syntax Examples

wip

# Feature Matrix

wip


# Performance

This section reviews the performance of available logging packages against 
`cat()`.

## Simple Console Logging Call

Log a simple log message 

```{r, results='hide'}
# By default lgr is configured for color output, so we disable that for a fair
# comparison
lgr$set_appenders(AppenderConsole$new(layout = LayoutFormat$new()))
sink("/dev/null")
res <- bench::mark(
  cat  = cat("FATAL", " [", format(Sys.time()), "] ", "test", sep = ""),
  logger = logger::log_info("test"),
  futile.logger = futile.logger::flog.info("test"),
  logging = logging::logerror("test", logger = "logging"),
  lgr = lgr::lgr$info("test"),
  check = FALSE
)
sink()
```
```{r}
res %>% 
  select(expression, min, mean, median, mem_alloc) %>% 
  arrange(median) %>% 
  knitr::kable()

res$expression <- fct_reorder(res$expression, res$median)
  
plot(res)

```

For simple log messages **logging* and *logger** are in the clear lead 
performance wise


# Log a simple log message (with colors)

The only packages that support color output are **lgr** and **logger**. Both
do not allow much configuration of the color output. Here lgr is in the lead,
mainly because **logger** relies on **glue** for the color formatting. Both


```{r, results='hide'}
lgr$set_appenders(AppenderConsole$new())
log_layout(layout_glue_colors)
library(crayon)

sink("/dev/null")
res <- bench::mark(
  cat  = cat(red("FATAL"), " [", format(Sys.time()), "] ", "test", sep = ""),
  logger = logger::log_fatal("test"),
  lgr = lgr::lgr$info("test"),
  check = FALSE
)
sink()
```

```{r}
res %>% 
  select(expression, min, mean, median, mem_alloc) %>% 
  arrange(median) %>% 
  knitr::kable()

res$expression <- fct_reorder(res$expression, res$median)
  
plot(res)

```


# Log a suppressed message



```{r}
lgr$set_threshold("info")

res <- bench::mark(
  cat = cat(),
  logger = logger::log_debug("test"),
  futile.logger = futile.logger::flog.debug("test"),
  logging = logging::logdebug("test", logger = "logging"),
  lgr = lgr::lgr$debug("test"),
  check = FALSE
)

```

```{r}
plot(res)
```

Here lgr is pretty much in the lead, because it completely disables the 
logging functions that are under the loggers threshold.


### Conclusion

While there are subtle differences in the performance of the available logging
packages, all perform pretty well. Nothing can compare with a simple `cat()`,
but that was to be expected.
