Skip to content

Commit bb9203e

Browse files
committed
add hidden .rawMsg property to LogEvent for storing msg without string interpolation
1 parent cd21d69 commit bb9203e

File tree

5 files changed

+99
-27
lines changed

5 files changed

+99
-27
lines changed

NEWS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
`{knitr}` rendering process, log messages are now output to `stderr` instead
55
of `stdout` by default, to avoid polluting markdown documents (#62, thx @gadenbuie).
66

7+
* added hidden `.rawMsg` property to LogEvents to store message without
8+
string interpolation (e.g. that still contains the placeholders from
9+
`sprintf()` or `glue()`) (#60)
10+
11+
712
# lgr 0.4.4
813

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

R/LogEvent.R

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ LogEvent <- R6::R6Class(
5353
timestamp = Sys.time(),
5454
caller = NA,
5555
msg = NA,
56+
.rawMsg = msg,
5657
...
5758
){
5859
assert(inherits(logger, "Logger"), "Logger must be a <Logger> object, not a ", class_fmt(logger))
@@ -64,6 +65,7 @@ LogEvent <- R6::R6Class(
6465
assign("timestamp", timestamp, self)
6566
assign("caller", caller, self)
6667
assign("msg", msg, self)
68+
assign(".rawMsg", .rawMsg, self)
6769

6870
# custom values
6971
if (!missing(...)){
@@ -94,18 +96,22 @@ LogEvent <- R6::R6Class(
9496

9597
#' @field .logger [Logger]. A reference to the Logger that created the
9698
#' event (equivalent to `get_logger(event$logger)`).
97-
.logger = NULL
99+
.logger = NULL,
100+
101+
#' @field .rawMsg `character`. The raw log message without string
102+
#' interpolation.
103+
.rawMsg = NULL
98104
),
99105

100106
active = list(
101107

102108
#' @field values `list`. All values stored in the `LogEvent`, including
103-
#' all *custom fields*, but not including `event$.logger`.
109+
#' all *custom fields*, but not including `event$.logger` and `event$.rawMsg`.
104110
values = function(){
105111
fixed_vals <- c("level", "timestamp", "logger", "caller", "msg")
106112
custom_vals <- setdiff(
107113
names(get(".__enclos_env__", self)[["self"]]),
108-
c(".__enclos_env__", "level_name", "initialize", "clone", "values",
114+
c(".__enclos_env__", "level_name", "initialize", "clone", "values", ".rawMsg",
109115
".logger")
110116
)
111117
valnames <- union(fixed_vals, custom_vals) # to enforce order of fixed_vals

R/Logger.R

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -226,14 +226,16 @@ Logger <- R6::R6Class(
226226
}
227227

228228
force(caller)
229+
rawMsg <- msg
229230

230231
if (missing(...)){
231232
vals <- list(
232233
logger = self,
233234
level = level,
234235
timestamp = timestamp,
235236
caller = caller,
236-
msg = msg
237+
msg = msg,
238+
.rawMsg = rawMsg
237239
)
238240
} else {
239241
dots <- list(...)
@@ -245,7 +247,8 @@ Logger <- R6::R6Class(
245247
level = level,
246248
timestamp = timestamp,
247249
caller = caller,
248-
msg = msg
250+
msg = msg,
251+
.rawMsg = rawMsg
249252
)
250253
} else {
251254
not_named <- vapply(names(dots), is_blank, TRUE, USE.NAMES = FALSE)
@@ -259,7 +262,8 @@ Logger <- R6::R6Class(
259262
level = level,
260263
timestamp = timestamp,
261264
caller = caller,
262-
msg = msg
265+
msg = msg,
266+
.rawMsg = rawMsg
263267
),
264268
dots[!not_named]
265269
)
@@ -882,6 +886,11 @@ LoggerGlue <- R6::R6Class(
882886
"Can only utilize vectorized logging if log level is the same for all entries"
883887
)
884888

889+
assert(
890+
!missing(...),
891+
"No log message or structured logging fields supplied"
892+
)
893+
885894
dots <- list(...)
886895

887896
if ("msg" %in% names(dots)){
@@ -909,6 +918,7 @@ LoggerGlue <- R6::R6Class(
909918
}
910919
})
911920

921+
rawMsg <- dots[[1]]
912922
msg <- do.call(glue::glue, args = c(dots_msg, list(.envir = .envir)))
913923

914924
# Check if LogEvent should be created
@@ -921,22 +931,21 @@ LoggerGlue <- R6::R6Class(
921931

922932
force(caller)
923933

924-
if (missing(...)){
925-
stop("No log message or structured logging fields supplied")
926-
} else {
927-
custom_fields <- !(grepl("^\\.", names(dots)) | is_blank(names(dots)))
934+
# Create list that contains all values equired for the log event
935+
custom_fields <- !(grepl("^\\.", names(dots)) | is_blank(names(dots)))
936+
937+
vals <- c(
938+
list(
939+
logger = self,
940+
level = level,
941+
timestamp = timestamp,
942+
caller = caller,
943+
msg = msg,
944+
.rawMsg = rawMsg
945+
),
946+
dots[custom_fields]
947+
)
928948

929-
vals <- c(
930-
list(
931-
logger = self,
932-
level = level,
933-
timestamp = timestamp,
934-
caller = caller,
935-
msg = msg
936-
),
937-
dots[custom_fields]
938-
)
939-
}
940949

941950
# This code looks really weird, but it really is just replacing all
942951
# instances of [[ with get() for minimal overhead. We want event

man/LogEvent.Rd

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

tests/testthat/test_Logger.R

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
context("Logger")
22

33

4+
# Logger ------------------------------------------------------------------
5+
6+
47

58
test_that("logging conditions works", {
69
e <- error("blahblah")
@@ -379,11 +382,17 @@ test_that("$config works with lists", {
379382

380383

381384

385+
# Multi-Logger tests -------------------------------------------------------------
382386

383387
test_that("Logger$log() dispatches to all appenders, even if some throw an error", {
384388
ln <- Logger$new("normal", propagate = FALSE)
385389
lg <- LoggerGlue$new("glue", propagate = FALSE)
386390

391+
on.exit({
392+
ln$config(NULL)
393+
lg$config(NULL)
394+
})
395+
387396
AppErr <- R6::R6Class(
388397
inherit = AppenderConsole,
389398
public = list(
@@ -416,6 +425,11 @@ test_that("Logger error contains useful call object", {
416425
l <- get_logger("test")
417426
g <- get_logger_glue("testglue")
418427

428+
on.exit({
429+
l$config(NULL)
430+
g$config(NULL)
431+
})
432+
419433
expect_warning(l$info("this will fail", e = stop()), "l\\$info")
420434
expect_warning(g$info("this will fail", e = stop()), "g\\$info")
421435
})
@@ -451,18 +465,52 @@ test_that("Appender error contains useful call object", {
451465
})
452466

453467

468+
test_that("Logger$log - with 'msg' argument - logs the message", {
469+
l <- get_logger("test")$set_propagate(FALSE)
470+
471+
on.exit({
472+
l$config(NULL)
473+
})
474+
475+
expect_silent(l$log(level = "fatal", msg = "test"))
476+
})
454477

455478

479+
test_that("LoggerGlue$log - with 'msg' argument - throws a warning", {
480+
l <- get_logger_glue("testglue")$set_propagate(FALSE)
456481

457-
test_that("Logger$log 'msg' argument works as expected", {
482+
on.exit({
483+
l$config(NULL)
484+
})
485+
486+
expect_warning(l$log(level = "fatal", msg = "test"), "does not support")
487+
})
488+
489+
490+
test_that("Logger$log - with string interpolation - adds .rawMsg to event", {
458491
l <- get_logger("test")$set_propagate(FALSE)
459-
g <- get_logger_glue("testglue")$set_propagate(FALSE)
460492

461493
on.exit({
462494
l$config(NULL)
463-
g$config(NULL)
464495
})
465496

466-
expect_silent(l$log(level = "fatal", msg = "test"))
467-
expect_warning(g$log(level = "fatal", msg = "test"), "does not support")
497+
l$info("foo %s", "bar")
498+
499+
expect_identical(l$last_event$msg, "foo bar")
500+
expect_identical(l$last_event$.rawMsg, "foo %s")
468501
})
502+
503+
504+
test_that("LoggerGlue$log - with string interpolation - adds .rawMsg to event", {
505+
l <- get_logger_glue("testglue")$set_propagate(FALSE)
506+
507+
on.exit({
508+
l$config(NULL)
509+
})
510+
511+
l$fatal("hash {x}", x = "baz")
512+
513+
expect_identical(as.character(l$last_event$msg), "hash baz")
514+
expect_identical(l$last_event$.rawMsg, "hash {x}")
515+
})
516+

0 commit comments

Comments
 (0)