forked from s-fleck/lgr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathREADME.Rmd
264 lines (195 loc) · 9.14 KB
/
README.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
---
output: github_document
---
<!-- README.md is generated from README.Rmd. Please edit that file -->
```{r setup, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
library(lgr)
basic_config() # ensure default config
# <img src="man/figures/lgr-logo-plain.svg" align="right" width=160 height=160/>
```
# lgr
[![CRAN status](https://www.r-pkg.org/badges/version/lgr)](https://cran.r-project.org/package=lgr)
[![Lifecycle: maturing](https://img.shields.io/badge/lifecycle-maturing-blue.svg)](https://lifecycle.r-lib.org/articles/stages.html)
lgr is a logging package for R built on the back of
[R6](https://github.com/r-lib/R6) classes. It is designed to be flexible,
performant and extensible. The package
[vignette](https://s-fleck.github.io/lgr/articles/lgr.html) contains a
comprehensive description of the features of lgr (some of them unique among
R logging packages) along with many code examples.
Users that have not worked with R6 classes before, will find configuring
Loggers a bit strange and verbose, but care was taken to keep
the syntax for common logging tasks and interactive usage simple and concise.
User that have experience with
[shiny](https://github.com/rstudio/shiny),
[plumber](https://github.com/rstudio/plumber),
[python logging](https://docs.python.org/3/library/logging.html) or
[Apache Log4j](https://logging.apache.org/log4j/2.x/) will feel
at home. User that are proficient with R6 classes will also find it easy
to extend and customize lgr, for example with their own appenders Loggers or
Appenders.
## Features
* *Hierarchical loggers* like in log4j and python logging. This is useful if you
want to be able to configure logging on a per-package basis.
* An *arbitrary number of appenders* for each logger. A single logger can write
to the console, a logfile, a database, etc... .
* Support for structured logging. As opposed to many other logging
packages for R a log event is not just a message with a timestamp, but an
object that can contain arbitrary data fields. This is useful for producing
machine readable logs.
* *Vectorized* logging (so `lgr$fatal(capture.output(iris))` works)
* Lightning fast *in-memory logs* for interactive use.
* Appenders that write logs to a wide range of destinations:
* databases (buffered or directly)
* email or pushbullet
* plaintext files (with a powerful formatting syntax)
* JSON files with arbitrary data fields
* Rotating files that are reset and backed-up after they reach
a certain file size or age
* memory buffers
* (colored) console output
* Optional support to use [glue](https://glue.tidyverse.org/) instead of
`sprintf()` for composing log messages.
## Usage
To log an *event* with with lgr we call `lgr$<logging function>()`. Unnamed
arguments to the logging function are interpreted by `sprintf()`. For a way
to create loggers that [glue](https://glue.tidyverse.org/) instead
please refer to the vignette.
```{r}
lgr$fatal("A critical error")
lgr$error("A less severe error")
lgr$warn("A potentially bad situation")
lgr$info("iris has %s rows", nrow(iris))
# the following log levels are hidden by default
lgr$debug("A debug message")
lgr$trace("A finer grained debug message")
```
A Logger can have several Appenders. For example, we can add a JSON appender to
log to a file with little effort.
```{r}
tf <- tempfile()
lgr$add_appender(AppenderFile$new(tf, layout = LayoutJson$new()))
lgr$info("cars has %s rows", nrow(cars))
cat(readLines(tf))
```
By passing a named argument to `info()`, `warn()`, and co you can log not only
text but arbitrary R objects. Not all appenders support structured logging
perfectly, but JSON does. This way you can create
logfiles that are machine as well as (somewhat) human readable.
```{r}
lgr$info("loading cars", "cars", rows = nrow(cars), cols = ncol(cars))
cat(readLines(tf), sep = "\n")
```
```{r, echo=FALSE}
unlink(tf)
```
For more examples please see the
package
[vignette](https://s-fleck.github.io/lgr/articles/lgr.html) and
[documentation](https://s-fleck.github.io/lgr/)
## See lgr in action
lgr is used to govern console output in my shiny based csv editor
[shed](https://github.com/s-fleck/shed)
```{r eval = FALSE}
# install.packages("remotes")
remotes::install_github("s-fleck/shed")
library(shed)
# log only output from the "shed" logger to a file
logfile <- tempfile()
lgr::get_logger("shed")$add_appender(AppenderFile$new(logfile))
lgr::threshold("all")
# edit away and watch the rstudio console!
lgr$info("starting shed")
shed(iris)
lgr$info("this will not end up in the log file")
readLines(logfile)
# cleanup
file.remove(logfile)
```
## Development status
lgr in general is stable and safe for use, but **the following features are still experimental**:
* Database appenders which are available from the separate package
[lgrExtra](https://github.com/s-fleck/lgrExtra).
* yaml/json config files for loggers (do not yet support all planned features)
* The documentation in general. I'm still hoping for more R6-specific features
in [roxygen2](https://github.com/r-lib/roxygen2) before I invest more
time in object documentation.
## Dependencies
[R6](https://github.com/r-lib/R6): The R6 class system provides the framework
on which lgr is built and the **only Package lgr will ever depend on**. If you
are a **package developer** and want to add logging to your package, this is the
only transitive dependency you have to worry about, as configuring of the
loggers should be left to the user of your package.
### Optional dependencies
lgr comes with a long list of optional dependencies that make a wide range of
appenders possible. You only need the dependencies for the Appenders you
actually want to use. Care was taken to choose packages that are slim, stable,
have minimal dependencies, and are well maintained :
Extra appenders (in the main package):
- [jsonlite](https://github.com/jeroen/jsonlite) for JSON logging via
`LayoutJson`. JSON is a popular plaintext based file format that is easy to
read for humans and machines alike.
- [rotor](https://github.com/s-fleck/rotor) for log rotation via
AppenderFileRotating and co.
- [data.table](https://github.com/Rdatatable/) for fast in-memory
logging with `AppenderDt`, and also by all database / DBI Appenders.
- [glue](https://glue.tidyverse.org/) for a more flexible formatting syntax
via LoggerGlue and LayoutGlue.
Extra appenders via [lgrExtra](https://github.com/s-fleck/lgrExtra):
- [DBI](https://github.com/r-dbi/DBI) for logging to databases. lgr is
confirmed to work with the following backends:
- [RSQLite](https://github.com/r-dbi/RSQLite),
- [RMariaDB](https://github.com/r-dbi/RMariaDB) for MariaDB and MySQL,
- [RPostgres](https://cran.r-project.org/package=RPostgres),
- [RJDBC](https://github.com/s-u/RJDBC) for DB2, and
- [odbc](https://github.com/r-dbi/odbc) also for DB2.
In theory all DBI compliant database packages should work. If you
are using lgr with a database backend, please report your (positive and
negative) experiences, as database support is still somewhat experimental.
- [gmailr](https://cran.r-project.org/package=gmailr) or
- [sendmailR](https://cran.r-project.org/package=sendmailR) for email
notifications.
- [RPushbullet](https://github.com/eddelbuettel/rpushbullet) for push
notifications.
- [Rsyslog](https://cran.r-project.org/package=rsyslog) for logging to
syslog on POSIX-compatible systems.
- [elastic](https://cran.r-project.org/package=elastic) for logging
to ElasticSearch
Other extra features:
- [yaml](https://CRAN.R-project.org/package=yaml) for configuring loggers
via YAML files
- [crayon](https://github.com/r-lib/crayon) for colored console output.
- [whoami](https://github.com/r-lib/whoami/blob/master/DESCRIPTION) for
guessing the user name from various sources. You can also set the user name
manually if you want to use it for logging.
- [desc](https://CRAN.R-project.org/package=desc) for the package development
convenience function `use_logger()`
- [cli](https://CRAN.R-project.org/package=cli) for printing the tree
structure of registered loggers with `logger_tree()`
Other `Suggests`
([future](https://CRAN.R-project.org/package=future),
[future.apply](https://CRAN.R-project.org/package=future.apply)) do not
provide extra functionality but had to be included for some of
the automated unit tests run by lgr.
## Installation
You can install lgr from CRAN
```{r eval = FALSE}
install.packages("lgr")
```
Or you can install the current development version directly from github
```{r eval = FALSE}
#install.packages("remotes")
remotes::install_github("s-fleck/lgr")
```
## Outlook
The long term goal is to support (nearly) all features of the python logging
module. If you have experience with python logging or Log4j and are missing
features/appenders that you'd like to see, please feel free to post a feature
request on the issue tracker.
## Acknowledgement
* [diagrams.net](https://app.diagrams.net/) for the flow chart in the vignette