Skip to content

Commit c84e4af

Browse files
committed
#62 add connection argument to AppenderConsole
1 parent d3f8a4b commit c84e4af

26 files changed

+300
-222
lines changed

NEWS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# lgr 0.4.5.9000
2+
3+
* `AppenderConsole` now accept a `connection` argument. If called from a
4+
`{knitr}` rendering process, log messages are now output to `stderr` instead
5+
of `stdout` by default, to avoid polluting markdown documents (#62, thx @gadenbuie).
6+
17
# lgr 0.4.4
28

39
* `%k` and `%K` parameters in `format.LogEvent` now work as expected when using

R/Appender.R

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,9 @@ Appender <- R6::R6Class(
139139
#' **crayon** installed log levels will be coloured by default
140140
#' (but you can modify this behaviour by passing a custom [Layout]).
141141
#'
142-
#' @param output Choose whether the message is printed to the \R console as
143-
#' regular output (`"stdout"`, default in most cases) or as a message
144-
#' (`"stderr"`, default inside a \pkg{knitr} rendering process).
142+
#' @param connection A connection or a `character` scalar. See the `file`
143+
#' argument of [cat()] for more details. Defaults to [stdout()], except
144+
#' inside \pkg{knitr} rendering processes where it defaults to [stderr()].
145145
#'
146146
#' @family Appenders
147147
#' @seealso [LayoutFormat]
@@ -173,41 +173,48 @@ AppenderConsole <- R6::R6Class(
173173
colors = getOption("lgr.colors", list())
174174
),
175175
filters = NULL,
176-
output = NULL
176+
connection = NULL
177177
){
178178
self$set_threshold(threshold)
179179
self$set_layout(layout)
180180
self$set_filters(filters)
181-
if (is.null(output)) {
182-
output <- default_console_output(output)
181+
if (is.null(connection)) {
182+
connection <- default_console_connection()
183183
}
184-
private$output <- match.arg(output, c("stdout", "stderr"))
184+
self$set_connection(connection)
185185
},
186186

187187
append = function(event){
188-
output <- switch(private$output, stdout = stdout(), stderr = stderr())
189-
cat(private$.layout$format_event(event), sep = "\n", file = output)
188+
cat(private$.layout$format_event(event), sep = "\n", file = get(".connection", private))
189+
},
190+
191+
set_connection = function(connection){
192+
assert(
193+
inherits(connection, "connection") || is_scalar_character(connection)
194+
)
195+
196+
private[[".connection"]] <- connection
190197
}
191198
),
192199

193200
active = list(
194-
destination = function() "console"
201+
destination = function() "console",
202+
connection = function() private[[".connection"]]
195203
),
196204

197205
private = list(
198-
output = "stdout"
206+
.connection = NULL
199207
)
200208
)
201209

202-
default_console_output <- function(output) {
203-
if (!is.null(output)) output
204-
210+
default_console_connection <- function() {
205211
# In knitr, default to using stderr where log messages can be better handled
206212
if (isTRUE(getOption("knitr.in.progress", FALSE))) {
207-
return("stderr")
213+
return(stderr())
208214
}
209215

210-
"stdout"
216+
# has to be this, not a call to `stdout()`
217+
""
211218
}
212219

213220

R/basic_config.R

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#' @param console_fmt `character` scalar: like `fmt` but used for console output
1515
#' @param console_timestamp_fmt `character` scalar: like `timestamp_fmt` but
1616
#' used for console output
17+
#' @param console_connection see [cat()] `file` argument.
1718
#' @inheritParams print.LogEvent
1819
#' @inheritParams Logger
1920
#' @param appenders a single [Appender] or a list thereof.
@@ -53,6 +54,7 @@ basic_config <- function(
5354
console = if (is.null(appenders)) "all" else FALSE,
5455
console_fmt = "%L [%t] %m %f",
5556
console_timestamp_fmt = "%H:%M:%OS3",
57+
console_connection = NULL,
5658
memory = FALSE
5759
){
5860
default_fmt = "%L [%t] %m" # only relevant for triggering warning when logging to json
@@ -134,6 +136,7 @@ basic_config <- function(
134136
name = "console",
135137
AppenderConsole$new(
136138
threshold = console,
139+
connection = console_connection,
137140
layout = LayoutFormat$new(
138141
colors = getOption("lgr.colors"),
139142
fmt = console_fmt,

README.Rmd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ knitr::opts_chunk$set(
1313
)
1414
1515
library(lgr)
16-
basic_config() # ensure default config
16+
basic_config(console_connection = stdout()) # ensure default config
1717
# <img src="man/figures/lgr-logo-plain.svg" align="right" width=160 height=160/>
1818
```
1919
# lgr

README.md

Lines changed: 81 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -28,28 +28,28 @@ Appenders.
2828

2929
## Features
3030

31-
- *Hierarchical loggers* like in log4j and python logging. This is
32-
useful if you want to be able to configure logging on a per-package
33-
basis.
34-
- An *arbitrary number of appenders* for each logger. A single logger
35-
can write to the console, a logfile, a database, etc… .
36-
- Support for structured logging. As opposed to many other logging
37-
packages for R a log event is not just a message with a timestamp,
38-
but an object that can contain arbitrary data fields. This is useful
39-
for producing machine readable logs.
40-
- *Vectorized* logging (so `lgr$fatal(capture.output(iris))` works)
41-
- Lightning fast *in-memory logs* for interactive use.
42-
- Appenders that write logs to a wide range of destinations:
43-
- databases (buffered or directly)
44-
- email or pushbullet
45-
- plaintext files (with a powerful formatting syntax)
46-
- JSON files with arbitrary data fields
47-
- Rotating files that are reset and backed-up after they reach a
48-
certain file size or age
49-
- memory buffers
50-
- (colored) console output
51-
- Optional support to use [glue](https://glue.tidyverse.org/) instead
52-
of `sprintf()` for composing log messages.
31+
- *Hierarchical loggers* like in log4j and python logging. This is
32+
useful if you want to be able to configure logging on a per-package
33+
basis.
34+
- An *arbitrary number of appenders* for each logger. A single logger
35+
can write to the console, a logfile, a database, etc… .
36+
- Support for structured logging. As opposed to many other logging
37+
packages for R a log event is not just a message with a timestamp, but
38+
an object that can contain arbitrary data fields. This is useful for
39+
producing machine readable logs.
40+
- *Vectorized* logging (so `lgr$fatal(capture.output(iris))` works)
41+
- Lightning fast *in-memory logs* for interactive use.
42+
- Appenders that write logs to a wide range of destinations:
43+
- databases (buffered or directly)
44+
- email or pushbullet
45+
- plaintext files (with a powerful formatting syntax)
46+
- JSON files with arbitrary data fields
47+
- Rotating files that are reset and backed-up after they reach a
48+
certain file size or age
49+
- memory buffers
50+
- (colored) console output
51+
- Optional support to use [glue](https://glue.tidyverse.org/) instead of
52+
`sprintf()` for composing log messages.
5353

5454
## Usage
5555

@@ -61,13 +61,13 @@ vignette.
6161

6262
``` r
6363
lgr$fatal("A critical error")
64-
#> FATAL [09:29:52.755] A critical error
64+
#> FATAL [20:38:17.998] A critical error
6565
lgr$error("A less severe error")
66-
#> ERROR [09:29:52.777] A less severe error
66+
#> ERROR [20:38:18.057] A less severe error
6767
lgr$warn("A potentially bad situation")
68-
#> WARN [09:29:52.784] A potentially bad situation
68+
#> WARN [20:38:18.072] A potentially bad situation
6969
lgr$info("iris has %s rows", nrow(iris))
70-
#> INFO [09:29:52.785] iris has 150 rows
70+
#> INFO [20:38:18.074] iris has 150 rows
7171

7272
# the following log levels are hidden by default
7373
lgr$debug("A debug message")
@@ -81,9 +81,9 @@ appender to log to a file with little effort.
8181
tf <- tempfile()
8282
lgr$add_appender(AppenderFile$new(tf, layout = LayoutJson$new()))
8383
lgr$info("cars has %s rows", nrow(cars))
84-
#> INFO [09:29:52.805] cars has 50 rows
84+
#> INFO [20:38:18.173] cars has 50 rows
8585
cat(readLines(tf))
86-
#> {"level":400,"timestamp":"2022-04-28 09:29:52","logger":"root","caller":"eval","msg":"cars has 50 rows"}
86+
#> {"level":400,"timestamp":"2023-03-04 20:38:18","logger":"root","caller":"eval","msg":"cars has 50 rows"}
8787
```
8888

8989
By passing a named argument to `info()`, `warn()`, and co you can log
@@ -94,10 +94,10 @@ logfiles that are machine as well as (somewhat) human readable.
9494
``` r
9595
lgr$info("loading cars", "cars", rows = nrow(cars), cols = ncol(cars))
9696
#> Warning in (function (fmt, ...) : one argument not used by format 'loading cars'
97-
#> INFO [09:29:52.832] loading cars {rows: `50`, cols: `2`}
97+
#> INFO [20:38:18.263] loading cars {rows: `50`, cols: `2`}
9898
cat(readLines(tf), sep = "\n")
99-
#> {"level":400,"timestamp":"2022-04-28 09:29:52","logger":"root","caller":"eval","msg":"cars has 50 rows"}
100-
#> {"level":400,"timestamp":"2022-04-28 09:29:52","logger":"root","caller":"eval","msg":"loading cars","rows":50,"cols":2}
99+
#> {"level":400,"timestamp":"2023-03-04 20:38:18","logger":"root","caller":"eval","msg":"cars has 50 rows"}
100+
#> {"level":400,"timestamp":"2023-03-04 20:38:18","logger":"root","caller":"eval","msg":"loading cars","rows":50,"cols":2}
101101
```
102102

103103
For more examples please see the package
@@ -135,13 +135,13 @@ file.remove(logfile)
135135
lgr in general is stable and safe for use, but **the following features
136136
are still experimental**:
137137

138-
- Database appenders which are available from the separate package
139-
[lgrExtra](https://github.com/s-fleck/lgrExtra).
140-
- yaml/json config files for loggers (do not yet support all planned
141-
features)
142-
- The documentation in general. I’m still hoping for more R6-specific
143-
features in [roxygen2](https://github.com/r-lib/roxygen2) before I
144-
invest more time in object documentation.
138+
- Database appenders which are available from the separate package
139+
[lgrExtra](https://github.com/s-fleck/lgrExtra).
140+
- yaml/json config files for loggers (do not yet support all planned
141+
features)
142+
- The documentation in general. I’m still hoping for more R6-specific
143+
features in [roxygen2](https://github.com/r-lib/roxygen2) before I
144+
invest more time in object documentation.
145145

146146
## Dependencies
147147

@@ -162,60 +162,62 @@ maintained :
162162

163163
Extra appenders (in the main package):
164164

165-
- [jsonlite](https://github.com/jeroen/jsonlite) for JSON logging via
166-
`LayoutJson`. JSON is a popular plaintext based file format that is
167-
easy to read for humans and machines alike.
165+
- [jsonlite](https://github.com/jeroen/jsonlite) for JSON logging via
166+
`LayoutJson`. JSON is a popular plaintext based file format that is
167+
easy to read for humans and machines alike.
168168

169-
- [rotor](https://github.com/s-fleck/rotor) for log rotation via
170-
AppenderFileRotating and co.
169+
- [rotor](https://github.com/s-fleck/rotor) for log rotation via
170+
AppenderFileRotating and co.
171171

172-
- [data.table](https://github.com/Rdatatable/) for fast in-memory
173-
logging with `AppenderDt`, and also by all database / DBI Appenders.
172+
- [data.table](https://github.com/Rdatatable/) for fast in-memory
173+
logging with `AppenderDt`, and also by all database / DBI Appenders.
174174

175-
- [glue](https://glue.tidyverse.org/) for a more flexible formatting
176-
syntax via LoggerGlue and LayoutGlue.
175+
- [glue](https://glue.tidyverse.org/) for a more flexible formatting
176+
syntax via LoggerGlue and LayoutGlue.
177177

178178
Extra appenders via [lgrExtra](https://github.com/s-fleck/lgrExtra):
179179

180-
- [DBI](https://github.com/r-dbi/DBI) for logging to databases. lgr is
181-
confirmed to work with the following backends:
180+
- [DBI](https://github.com/r-dbi/DBI) for logging to databases. lgr is
181+
confirmed to work with the following backends:
182182

183-
- [RSQLite](https://github.com/r-dbi/RSQLite),
184-
- [RMariaDB](https://github.com/r-dbi/RMariaDB) for MariaDB and
185-
MySQL,
186-
- [RPostgres](https://cran.r-project.org/package=RPostgres),
187-
- [RJDBC](https://github.com/s-u/RJDBC) for DB2, and
188-
- [odbc](https://github.com/r-dbi/odbc) also for DB2.
183+
- [RSQLite](https://github.com/r-dbi/RSQLite),
184+
- [RMariaDB](https://github.com/r-dbi/RMariaDB) for MariaDB and MySQL,
185+
- [RPostgres](https://cran.r-project.org/package=RPostgres),
186+
- [RJDBC](https://github.com/s-u/RJDBC) for DB2, and
187+
- [odbc](https://github.com/r-dbi/odbc) also for DB2.
189188

190-
In theory all DBI compliant database packages should work. If you
191-
are using lgr with a database backend, please report your (positive
192-
and negative) experiences, as database support is still somewhat
193-
experimental.
189+
In theory all DBI compliant database packages should work. If you are
190+
using lgr with a database backend, please report your (positive and
191+
negative) experiences, as database support is still somewhat
192+
experimental.
194193

195-
- [gmailr](https://cran.r-project.org/package=gmailr) or
194+
- [gmailr](https://cran.r-project.org/package=gmailr) or
196195

197-
- [sendmailR](https://cran.r-project.org/package=sendmailR) for email
198-
notifications.
196+
- [sendmailR](https://cran.r-project.org/package=sendmailR) for email
197+
notifications.
199198

200-
- [RPushbullet](https://github.com/eddelbuettel/rpushbullet) for push
201-
notifications.
199+
- [RPushbullet](https://github.com/eddelbuettel/rpushbullet) for push
200+
notifications.
202201

203-
- [Rsyslog](https://cran.r-project.org/package=rsyslog) for logging to
204-
syslog on POSIX-compatible systems.
202+
- [Rsyslog](https://cran.r-project.org/package=rsyslog) for logging to
203+
syslog on POSIX-compatible systems.
204+
205+
- [elastic](https://cran.r-project.org/package=elastic) for logging to
206+
ElasticSearch
205207

206208
Other extra features:
207209

208-
- [yaml](https://CRAN.R-project.org/package=yaml) for configuring
209-
loggers via YAML files
210-
- [crayon](https://github.com/r-lib/crayon) for colored console
211-
output.
212-
- [whoami](https://github.com/r-lib/whoami/blob/master/DESCRIPTION)
213-
for guessing the user name from various sources. You can also set
214-
the user name manually if you want to use it for logging.
215-
- [desc](https://CRAN.R-project.org/package=desc) for the package
216-
development convenience function `use_logger()`
217-
- [cli](https://CRAN.R-project.org/package=cli) for printing the tree
218-
structure of registered loggers with `logger_tree()`
210+
- [yaml](https://CRAN.R-project.org/package=yaml) for configuring
211+
loggers via YAML files
212+
- [crayon](https://github.com/r-lib/crayon) for colored console
213+
output.
214+
- [whoami](https://github.com/r-lib/whoami/blob/master/DESCRIPTION) for
215+
guessing the user name from various sources. You can also set the user
216+
name manually if you want to use it for logging.
217+
- [desc](https://CRAN.R-project.org/package=desc) for the package
218+
development convenience function `use_logger()`
219+
- [cli](https://CRAN.R-project.org/package=cli) for printing the tree
220+
structure of registered loggers with `logger_tree()`
219221

220222
Other `Suggests` ([future](https://CRAN.R-project.org/package=future),
221223
[future.apply](https://CRAN.R-project.org/package=future.apply)) do not
@@ -246,5 +248,5 @@ to post a feature request on the issue tracker.
246248

247249
## Acknowledgement
248250

249-
- [diagrams.net](https://app.diagrams.net/) for the flow chart in the
250-
vignette
251+
- [diagrams.net](https://app.diagrams.net/) for the flow chart in the
252+
vignette

inst/WORDLIST

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,9 @@ FilterInject
112112
Hotfix
113113
FilterForceLevel
114114
cron
115+
ElasticSearch
116+
json
117+
jsonlines
118+
colours
119+
hardcoded
120+
thx

man/Appender.Rd

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)