switching formatters
- Dominant language
- HTML
- Stars
- 323
- Forks
- 46
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 1
Description
I work with others, and we don't always have the same formatter set. We found recently that when my code (I tend to use `formatter_json`) is logging with their non-json formatter, the message is lost.
For instance,
```r
log_formatter(formatter_glue)
log_info("hello: {nrow(mtcars)}") # fashioned for formatter_glue
# INFO [2022-12-09 14:46:11] hello: 32
log_info(msg = "hello", n = nrow(mtcars)) # fashioned for formatter_json
# INFO [2022-12-09 14:46:11]
```
Where the last message is empty. If all of our code bases were using the same assumptions, then either all or none would have (say) `msg=` as the main message. The issue is that it is a named argument, not that it's `msg=`.
(One of my colleagues likes `formatter_glue`, ergo my inclusion of `{..}` above.)
It's not a problem in the reverse, a non-json-assuming log is sent with `formatter_json`:
```r
log_formatter(formatter_json)
log_info("hello: {nrow(mtcars)}") # fashioned for formatter_glue
# INFO [2022-12-09 14:46:21] ["hello: {nrow(mtcars)}"]
log_info(msg = "hello", n = nrow(mtcars)) # fashioned for formatter_json
# INFO [2022-12-09 14:46:21] {"msg":"hello","n":32}
```
I suggest either updating the formatters or supplying alternative functions, such as
```r
formatter_glue2 <- function (..., .logcall = sys.call(), .topcall = sys.call(-1),
.topenv = parent.frame(), collapse = "; ") {
fail_on_missing_package("glue")
paste(
sapply(list(...), function(dot) {
tryCatch(as.character(glue::glue(dot, .envir = .topenv)),
error = function(e) {
stop(paste("`glue` failed in `formatter_glue` on:\n\n",
capture.output(str(dot)), "\n\nRaw error message:\n\n",
e$message, "\n\nPlease consider using another `log_formatter` or",
"`skip_formatter` on strings with curly braces."))
})
}),
collapse = collapse)
}
log_formatter(formatter_glue2)
log_info("hello: {nrow(mtcars)}")
# INFO [2022-12-09 14:48:50] hello: 32
log_info(msg = "hello", n = nrow(mtcars))
# INFO [2022-12-09 14:48:50] hello; 32
```
(No missing messages.) Since one of my colleagues prefers `formatter_glue`, I focused on that formatter, but this could apply to others as well.
---
As one more step, it would be nice if my colleague were able to see all of the components send in my messages, where I often have one or more named components (in lieu of encoding within a string, where json makes it much easier to programmatically consume later). What about:
```r
formatter_json_glue <- function(..., .logcall = sys.call(), .topcall = sys.call(-1),
.topenv = parent.frame()) {
logger::fail_on_missing_package("jsonlite")
dots <- list(...)
if (is.null(nms <- names(dots))) nms <- rep("", length(dots))
if (any(!nzchar(nms))) {
nms[!nzchar(nms)] <- paste0("arg", seq_along(dots))[!nzchar(nms)]
}
names(dots) <- nms
eval(as.character(jsonlite::toJSON(
lapply(dots, function(dot) tryCatch(glue::glue(dot, .envir = .topenv), error = function(ign) dot)),
auto_unbox = TRUE)),
envir = .topenv)
}
logger::log_formatter(formatter_json_glue)
logger::log_info("hello") # fashioned for any formatter
# INFO [2022-12-09 14:52:55] {"arg1":"hello"}
logger::log_info("hello: {nrow(mtcars)}") # fashioned for formatter_glue
# INFO [2022-12-09 14:52:55] {"arg1":"hello: 32"}
logger::log_info(msg = "hello: {nrow(mtcars)}", n = nrow(mtcars))
# INFO [2022-12-09 14:52:55] {"msg":"hello: 32","n":"32"}
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.