-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Convert to .Rmd so we can show live logger output * Minimise the coloured output since the main goal is to show that it exists * Update related work section since most of the GitHub packages haven't been update in ~7 years and I think you can be more explicit about the benefits of logger * Fix a few typos and generally proofread the text. * Hide the links to the pkgdown site on the pkgdown site :)
- Loading branch information
Showing
4 changed files
with
245 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,3 +17,4 @@ dev-resources | |
^pkgdown$ | ||
^\.github$ | ||
revdep | ||
^README\.Rmd$ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
docs/ | ||
README.html |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
--- | ||
output: github_document | ||
--- | ||
|
||
<!-- README.md is generated from README.Rmd. Please edit that file --> | ||
|
||
```{r, include = FALSE} | ||
knitr::opts_chunk$set( | ||
collapse = TRUE, | ||
comment = "#>", | ||
fig.path = "man/figures/README-", | ||
out.width = "100%" | ||
) | ||
``` | ||
|
||
# logger | ||
|
||
<!-- badges: start --> | ||
[](https://www.repostatus.org/#active) [](https://cran.r-project.org/package=logger) [](https://github.com/daroczig/logger/actions) [](https://app.codecov.io/gh/daroczig/logger) [](https://mikata.dev) | ||
<!-- badges: end --> | ||
|
||
A lightweight, modern and flexibly logging utility for R -- heavily inspired by the `futile.logger` R package and `logging` Python module. | ||
|
||
## Installation | ||
|
||
[](https://cran.r-project.org/package=logger) | ||
|
||
```{r} | ||
#| eval: false | ||
install.packages('logger') | ||
``` | ||
|
||
The most recent, development version of `logger` can also be installed from GitHub: | ||
|
||
```{r} | ||
#| eval: false | ||
# install.packages("pak") | ||
pak::pak('daroczig/logger') | ||
``` | ||
|
||
## Quick example | ||
|
||
Setting the log level threshold to something low and logging various messages in ad-hoc and programmatic ways: | ||
|
||
```{r} | ||
#| include: false | ||
library(logger) | ||
log_appender(appender_stdout) | ||
``` | ||
|
||
```{r} | ||
library(logger) | ||
log_threshold(DEBUG) | ||
log_info('Script starting up...') | ||
pkgs <- available.packages() | ||
log_info('There are {nrow(pkgs)} 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' | ||
) | ||
} | ||
log_warn('There might be many, like {1:2} or more warnings!!!') | ||
``` | ||
|
||
You can even use a custom log layout to render the log records with colors, asyou can see in `demo(colors, package = 'logger', echo = FALSE)`: | ||
|
||
<img src="man/figures/colors.png" alt="colored log output"> | ||
|
||
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 `vignette("write_custom_extensions")`. | ||
|
||
## Related work | ||
|
||
There are many other logging packages available on CRAN: | ||
|
||
- [`futile.logger`](https://cran.r-project.org/package=futile.logger): probably the most popular `log4j` variant (and I'm a big fan) | ||
- [`logging`](https://cran.r-project.org/package=logging): just like Python's `logging` package | ||
- [`lgr`](https://cran.r-project.org/package=lgr): built on top of R6. | ||
- [`loggit`](https://cran.r-project.org/package=loggit): capture `message`, `warning` and `stop` function messages in a JSON file | ||
- [`log4r`](https://cran.r-project.org/package=log4r): `log4j`-based, object-oriented logger | ||
- [`rsyslog`](https://cran.r-project.org/package=rsyslog): logging to `syslog` on 'POSIX'-compatible operating systems | ||
- [`lumberjack`](https://cran.r-project.org/package=lumberjack): provides a special operator to log changes in data | ||
|
||
Why use logger? I decided to write the `n+1`th extensible `log4j` logger that fits my liking --- and hopefully yours as well --- the the aim to: | ||
|
||
- Keep it close to `log4j`. | ||
- Respect the modern 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 prefer `sprintf()` (e.g. 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 (e.g. 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 the `TRACE` log messages to the console, while only pushing `ERROR`s to DataDog and eg `INFO` messages to CloudWatch. | ||
- Optionally colorize log message based on the log level. | ||
- Make logging fun! | ||
|
||
Welcome to the [Bazaar](https://en.wikipedia.org/wiki/The_Cathedral_and_the_Bazaar)! If you already use any of the above packages for logging, you might find `vignette("migration")` useful. | ||
|
||
::: .pkgdown-hide | ||
|
||
## Interested in more details? | ||
|
||
Check out the main documentation site at <https://daroczig.github.io/logger> or the vignettes on the below topics: | ||
|
||
* [Introduction to logger](https://daroczig.github.io/logger/articles/Intro.html) | ||
* [The Anatomy of a Log Request](https://daroczig.github.io/logger/articles/anatomy.html) | ||
* [Customizing the Format and the Destination of a Log Record](https://daroczig.github.io/logger/articles/customize_logger.html) | ||
* [Writing Custom Logger Extensions](https://daroczig.github.io/logger/articles/write_custom_extensions.html) | ||
* [Migration Guide from other logging packages](https://daroczig.github.io/logger/articles/migration.html) | ||
* [Logging from R Packages](https://daroczig.github.io/logger/articles/r_packages.html) | ||
* [Simple Benchmarks on Performance](https://daroczig.github.io/logger/articles/performance.html) | ||
|
||
::: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,133 +1,163 @@ | ||
|
||
<!-- README.md is generated from README.Rmd. Please edit that file --> | ||
|
||
# logger | ||
|
||
<!-- badges: start --> | ||
[](https://www.repostatus.org/#active) [](https://cran.r-project.org/package=logger) [](https://github.com/daroczig/logger/actions) [](https://app.codecov.io/gh/daroczig/logger) [](https://mikata.dev) | ||
|
||
[](https://www.repostatus.org/#active) | ||
[](https://cran.r-project.org/package=logger) | ||
[](https://github.com/daroczig/logger/actions) | ||
[](https://app.codecov.io/gh/daroczig/logger) | ||
[](https://mikata.dev) | ||
<!-- badges: end --> | ||
|
||
A lightweight, modern and flexibly logging utility for R -- heavily inspired by the `futile.logger` R package and `logging` Python module. | ||
A lightweight, modern and flexibly logging utility for R – heavily | ||
inspired by the `futile.logger` R package and `logging` Python module. | ||
|
||
## Installation | ||
|
||
[](https://cran.r-project.org/package=logger) | ||
[](https://cran.r-project.org/package=logger) | ||
|
||
```r | ||
``` r | ||
install.packages('logger') | ||
``` | ||
|
||
The most recent, development version of `logger` can also be installed from GitHub: | ||
The most recent, development version of `logger` can also be installed | ||
from GitHub: | ||
|
||
```r | ||
remotes::install_github('daroczig/logger') | ||
``` r | ||
# install.packages("pak") | ||
pak::pak('daroczig/logger') | ||
``` | ||
|
||
## Quick example | ||
|
||
Setting the log level threshold to something low and logging various messages in ad-hoc and programmatic ways: | ||
Setting the log level threshold to something low and logging various | ||
messages in ad-hoc and programmatic ways: | ||
|
||
```r | ||
``` r | ||
library(logger) | ||
log_threshold(DEBUG) | ||
log_info('Script starting up...') | ||
#> INFO [2018-20-11 22:49:36] Script starting up... | ||
#> INFO [2024-07-31 07:37:34] 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! | ||
#> INFO [2024-07-31 07:37:34] There are 21122 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') | ||
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 | ||
#> DEBUG [2024-07-31 07:37:34] 10188 R packages including the 'a' letter | ||
#> DEBUG [2024-07-31 07:37:34] 7013 R packages including the 'c' letter | ||
#> DEBUG [2024-07-31 07:37:34] 5750 R packages including the 'd' letter | ||
#> DEBUG [2024-07-31 07:37:34] 10902 R packages including the 'e' letter | ||
#> DEBUG [2024-07-31 07:37:34] 8821 R packages including the 'i' letter | ||
#> DEBUG [2024-07-31 07:37:34] 7055 R packages including the 'l' letter | ||
#> DEBUG [2024-07-31 07:37:34] 7039 R packages including the 'm' letter | ||
#> DEBUG [2024-07-31 07:37:34] 6661 R packages including the 'n' letter | ||
#> DEBUG [2024-07-31 07:37:34] 7859 R packages including the 'o' letter | ||
#> DEBUG [2024-07-31 07:37:34] 6579 R packages including the 'p' letter | ||
#> DEBUG [2024-07-31 07:37:34] 11224 R packages including the 'r' letter | ||
#> DEBUG [2024-07-31 07:37:34] 10292 R packages including the 's' letter | ||
#> DEBUG [2024-07-31 07:37:34] 9526 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: | ||
|
||
```r | ||
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') | ||
#> WARN [2024-07-31 07:37:34] There might be many, like 1 or more warnings!!! | ||
#> WARN [2024-07-31 07:37:34] There might be many, like 2 or more warnings!!! | ||
``` | ||
|
||
Or simply run the related demo: | ||
|
||
```r | ||
demo(colors, package = 'logger', echo = FALSE) | ||
``` | ||
You can even use a custom log layout to render the log records with | ||
colors, asyou can see in | ||
`demo(colors, package = 'logger', echo = FALSE)`: | ||
|
||
<img src="man/figures/colors.png" alt="colored log output"> | ||
|
||
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`](https://cran.r-project.org/package=futile.logger): probably the most popular `log4j` variant (and I'm a big fan) | ||
- [`logging`](https://cran.r-project.org/package=logging): just like Python's `logging` package | ||
- [`loggit`](https://cran.r-project.org/package=loggit): capture `message`, `warning` and `stop` function messages in a JSON file | ||
- [`log4r`](https://cran.r-project.org/package=log4r): `log4j`-based, object-oriented logger | ||
- [`rsyslog`](https://cran.r-project.org/package=rsyslog): logging to `syslog` on 'POSIX'-compatible operating systems | ||
- [`lumberjack`](https://cran.r-project.org/package=lumberjack): 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 prefer `sprintf` (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 the `TRACE` log messages to the console, while only pushing `ERROR`s to DataDog and eg `INFO` messages to CloudWatch | ||
- optionally colorize log message based on the log level | ||
- make logging fun | ||
|
||
Welcome to the [Bazaar](https://en.wikipedia.org/wiki/The_Cathedral_and_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](https://daroczig.github.io/logger/articles/migration.html). | ||
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 `vignette("write_custom_extensions")`. | ||
|
||
## Related work | ||
|
||
There are many other logging packages available on CRAN: | ||
|
||
- [`futile.logger`](https://cran.r-project.org/package=futile.logger): | ||
probably the most popular `log4j` variant (and I’m a big fan) | ||
- [`logging`](https://cran.r-project.org/package=logging): just like | ||
Python’s `logging` package | ||
- [`lgr`](https://cran.r-project.org/package=lgr): built on top of R6. | ||
- [`loggit`](https://cran.r-project.org/package=loggit): capture | ||
`message`, `warning` and `stop` function messages in a JSON file | ||
- [`log4r`](https://cran.r-project.org/package=log4r): `log4j`-based, | ||
object-oriented logger | ||
- [`rsyslog`](https://cran.r-project.org/package=rsyslog): logging to | ||
`syslog` on ‘POSIX’-compatible operating systems | ||
- [`lumberjack`](https://cran.r-project.org/package=lumberjack): | ||
provides a special operator to log changes in data | ||
|
||
Why use logger? I decided to write the `n+1`th extensible `log4j` logger | ||
that fits my liking — and hopefully yours as well — the the aim to: | ||
|
||
- Keep it close to `log4j`. | ||
- Respect the modern 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 prefer `sprintf()` | ||
(e.g. 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 (e.g. 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 the `TRACE` | ||
log messages to the console, while only pushing `ERROR`s to DataDog | ||
and eg `INFO` messages to CloudWatch. | ||
- Optionally colorize log message based on the log level. | ||
- Make logging fun! | ||
|
||
Welcome to the | ||
[Bazaar](https://en.wikipedia.org/wiki/The_Cathedral_and_the_Bazaar)! If | ||
you already use any of the above packages for logging, you might find | ||
`vignette("migration")` useful. | ||
|
||
<div class=".pkgdown-hide"> | ||
|
||
## Interested in more details? | ||
|
||
Check out the main documentation site at https://daroczig.github.io/logger or the vignettes on the below topics: | ||
|
||
* [Introduction to logger](https://daroczig.github.io/logger/articles/Intro.html) | ||
* [The Anatomy of a Log Request](https://daroczig.github.io/logger/articles/anatomy.html) | ||
* [Customizing the Format and the Destination of a Log Record](https://daroczig.github.io/logger/articles/customize_logger.html) | ||
* [Writing Custom Logger Extensions](https://daroczig.github.io/logger/articles/write_custom_extensions.html) | ||
* [Migration Guide from other logging packages](https://daroczig.github.io/logger/articles/migration.html) | ||
* [Logging from R Packages](https://daroczig.github.io/logger/articles/r_packages.html) | ||
* [Simple Benchmarks on Performance](https://daroczig.github.io/logger/articles/performance.html) | ||
Check out the main documentation site at | ||
<https://daroczig.github.io/logger> or the vignettes on the below | ||
topics: | ||
|
||
- [Introduction to | ||
logger](https://daroczig.github.io/logger/articles/Intro.html) | ||
- [The Anatomy of a Log | ||
Request](https://daroczig.github.io/logger/articles/anatomy.html) | ||
- [Customizing the Format and the Destination of a Log | ||
Record](https://daroczig.github.io/logger/articles/customize_logger.html) | ||
- [Writing Custom Logger | ||
Extensions](https://daroczig.github.io/logger/articles/write_custom_extensions.html) | ||
- [Migration Guide from other logging | ||
packages](https://daroczig.github.io/logger/articles/migration.html) | ||
- [Logging from R | ||
Packages](https://daroczig.github.io/logger/articles/r_packages.html) | ||
- [Simple Benchmarks on | ||
Performance](https://daroczig.github.io/logger/articles/performance.html) | ||
|
||
</div> |