From 7d9a9b7a480c90484a7fb43eff1b3ba52143763b Mon Sep 17 00:00:00 2001 From: Hadley Wickham Date: Thu, 1 Aug 2024 09:14:13 -0500 Subject: [PATCH 1/9] Make tests more self-contained By introduing a new local_test_logger() function that temporarily changes the default logger. --- R/logger.R | 2 - tests/testthat/helper.R | 22 +++++++ tests/testthat/test-CRANSKIP-appenders.R | 22 ++----- .../test-CRANSKIP-logger-namespaces.R | 3 +- tests/testthat/test-appender.R | 62 +++++++++---------- tests/testthat/test-eval.R | 20 ++---- tests/testthat/test-formatters.R | 44 +++++++------ tests/testthat/test-helpers.R | 21 ++----- tests/testthat/test-layout.R | 25 +++----- tests/testthat/test-logger.R | 47 +++++++------- tests/testthat/test-return.R | 15 +---- tests/testthat/test-utils.R | 21 +++---- 12 files changed, 128 insertions(+), 176 deletions(-) create mode 100644 tests/testthat/helper.R diff --git a/R/logger.R b/R/logger.R index ba1b8da0..deb79b0a 100644 --- a/R/logger.R +++ b/R/logger.R @@ -70,7 +70,6 @@ logger <- function(threshold, formatter, layout, appender) { } } - #' Checks if provided namespace exists and falls back to global if not #' @param namespace string #' @return string @@ -124,7 +123,6 @@ log_config_setter <- function(fun_name, arg, namespace, index) { assign(namespace, configs, envir = namespaces) } - #' Delete an index from a logger namespace #' @inheritParams log_threshold #' @export diff --git a/tests/testthat/helper.R b/tests/testthat/helper.R new file mode 100644 index 00000000..0e600211 --- /dev/null +++ b/tests/testthat/helper.R @@ -0,0 +1,22 @@ + +local_test_logger <- function(threshold = INFO, + formatter = formatter_glue, + layout = layout_simple, + appender = appender_stdout, + namespace = "global", + frame = parent.frame()) { + + old <- namespaces[[namespace]] + + namespaces[[namespace]] <- list( + default = list( + threshold = as.loglevel(threshold), + layout = layout, + formatter = formatter, + appender = appender + ) + ) + + withr::defer(namespaces[[namespace]] <- old, frame) + invisible() +} diff --git a/tests/testthat/test-CRANSKIP-appenders.R b/tests/testthat/test-CRANSKIP-appenders.R index 2cd50efe..0a0bf6e3 100644 --- a/tests/testthat/test-CRANSKIP-appenders.R +++ b/tests/testthat/test-CRANSKIP-appenders.R @@ -1,27 +1,17 @@ library(logger) library(testthat) -## save current settings so that we can reset later -threshold <- log_threshold() -layout <- log_layout() -appender <- log_appender() - context('CRAN skip: async appender') test_that('async logging', { - t <- tempfile() - my_appender <- appender_async(appender_file(file = t)) - log_appender(my_appender) - log_layout(layout_blank) + t <- withr::local_tempfile() + local_test_logger( + layout = layout_blank, + appender = appender_async(appender_file(file = t)) + ) + for (i in 1:5) log_info(i) Sys.sleep(0.25) expect_equal(readLines(t)[1], '1') expect_equal(length(readLines(t)), 5) - unlink(t) - rm(t) }) - -## reset settings -log_threshold(threshold) -log_layout(layout) -log_appender(appender) diff --git a/tests/testthat/test-CRANSKIP-logger-namespaces.R b/tests/testthat/test-CRANSKIP-logger-namespaces.R index 32fa264d..b95352dc 100644 --- a/tests/testthat/test-CRANSKIP-logger-namespaces.R +++ b/tests/testthat/test-CRANSKIP-logger-namespaces.R @@ -9,8 +9,7 @@ context('CRAN skip: logging from packages') test_that('called from package', { devtools::load_all(system.file('demo-packages/logger-tester-package', package = 'logger')) - log_layout(layout_simple) - log_appender(appender_stdout) + local_test_logger(layout = layout_simple) expect_output(logger_tester_function(INFO, 'x = '), 'INFO') expect_output(logger_info_tester_function('everything = '), 'INFO') }) diff --git a/tests/testthat/test-appender.R b/tests/testthat/test-appender.R index 31ed3847..9ddc7fbb 100644 --- a/tests/testthat/test-appender.R +++ b/tests/testthat/test-appender.R @@ -1,61 +1,62 @@ library(logger) library(testthat) -## save current settings so that we can reset later -threshold <- log_threshold() -layout <- log_layout() -appender <- log_appender() - context('appenders') test_that('append to file', { - log_layout(layout_glue_generator('{level} {msg}')) - log_threshold(TRACE) - t <- tempfile() - log_appender(appender_file(t)) + t <- withr::local_tempfile() + local_test_logger( + appender = appender_file(t), + layout = layout_glue_generator('{level} {msg}'), + threshold = TRACE + ) log_info('foobar') log_info('{1:2}') expect_equal(length(readLines(t)), 3) expect_equal(readLines(t)[1], 'INFO foobar') expect_equal(readLines(t)[3], 'INFO 2') - unlink(t) - rm(t) }) test_that('overwrite file', { - log_layout(layout_glue_generator('{level} {msg}')) - log_threshold(TRACE) - t <- tempfile() - log_appender(appender_file(t, append = FALSE)) + t <- withr::local_tempfile() + local_test_logger( + appender = appender_file(t, append = FALSE), + layout = layout_glue_generator('{level} {msg}'), + threshold = TRACE + ) + log_info('foobar') log_info('{1:2}') expect_equal(length(readLines(t)), 2) expect_equal(readLines(t), c('INFO 1', 'INFO 2')) + log_info('42') expect_equal(length(readLines(t)), 1) expect_equal(readLines(t), 'INFO 42') - unlink(t) - rm(t) }) test_that('append to file + print to console', { - t <- tempfile() - log_appender(appender_tee(t)) + t <- withr::local_tempfile() + local_test_logger( + appender = appender_tee(t), + layout = layout_glue_generator('{level} {msg}'), + ) + expect_equal(capture.output(log_info('foobar'), type = 'message'), 'INFO foobar') - devnull <- capture.output(log_info('{1:2}'), type = 'message') + capture.output(log_info('{1:2}'), type = 'message') expect_equal(length(readLines(t)), 3) expect_equal(readLines(t)[1], 'INFO foobar') - unlink(t) - rm(t) }) test_that('logrotate', { - log_layout(layout_glue_generator('{msg}')) - log_threshold(TRACE) - t <- tempfile() - dir.create(t) + t <- withr::local_tempdir() f <- file.path(t, 'log') - log_appender(appender_file(f, max_lines = 2, max_files = 5L)) + local_test_logger( + appender = appender_file(f, max_lines = 2, max_files = 5L), + layout = layout_glue_generator('{msg}'), + threshold = TRACE + ) + for (i in 1:24) log_info(i) expect_equal(length(readLines(f)), 2) expect_equal(length(list.files(t)), 5) @@ -63,11 +64,4 @@ test_that('logrotate', { log_info('42') expect_equal(length(readLines(f)), 1) expect_equal(readLines(f), '42') - unlink(t) - rm(t) }) - -## reset settings -log_threshold(threshold) -log_layout(layout) -log_appender(appender) diff --git a/tests/testthat/test-eval.R b/tests/testthat/test-eval.R index e66cbcf3..f4dea3ff 100644 --- a/tests/testthat/test-eval.R +++ b/tests/testthat/test-eval.R @@ -1,37 +1,29 @@ library(logger) library(testthat) -## save current settings so that we can reset later -layout <- log_layout() -threshold <- log_threshold() -appender <- log_appender() - -log_layout(layout_glue_generator('{level} {msg}')) -log_appender(appender_stdout) - context('log_eval') test_that('single line', { + local_test_logger(layout = layout_glue_generator('{level} {msg}')) + expect_output(log_eval(4, INFO), sprintf("INFO %s => %s", shQuote(4), shQuote(4))) }) test_that('multi line', { + local_test_logger(layout = layout_glue_generator('{level} {msg}')) + expect_output(log_eval(4, INFO, multiline = TRUE), "Running expression") expect_output(log_eval(4, INFO, multiline = TRUE), "Results:") expect_output(log_eval(4, INFO, multiline = TRUE), "INFO 4") }) test_that('invisible return', { + local_test_logger(layout = layout_glue_generator('{level} {msg}')) expect_output(log_eval(require(logger), INFO), sprintf("INFO %s => %s", shQuote('require\\(logger\\)'), shQuote(TRUE))) }) -log_threshold(TRACE) test_that('lower log level', { + local_test_logger(TRACE, layout = layout_glue_generator('{level} {msg}')) expect_output(log_eval(4), sprintf("TRACE %s => %s", shQuote(4), shQuote(4))) }) - -## reset settings -log_threshold(threshold) -log_layout(layout) -log_appender(appender) diff --git a/tests/testthat/test-formatters.R b/tests/testthat/test-formatters.R index df5df1ca..e337ad46 100644 --- a/tests/testthat/test-formatters.R +++ b/tests/testthat/test-formatters.R @@ -2,10 +2,6 @@ library(logger) library(testthat) library(jsonlite) -## save current settings so that we can reset later -formatter <- log_formatter() -appender <- log_appender() - context('formatters') everything <- 42 g <- function() { @@ -15,9 +11,8 @@ f <- function() { log_info("Hi %s", everything) } -log_formatter(formatter_glue) -log_appender(appender_stdout) test_that('glue works', { + local_test_logger(formatter = formatter_glue) expect_equal(formatter_glue("Hi"), "Hi") expect_equal(formatter_glue(" Hi"), " Hi") @@ -36,7 +31,10 @@ test_that('glue works', { expect_output(log_warn("Hi {everything}"), '42') expect_output(g(), '42') - log_appender(appender_void) + local_test_logger( + formatter = formatter_glue, + appender = appender_void, + ) expect_error(formatter_glue('malformed {')) expect_error(formatter_glue('malformed {{'), NA) @@ -44,12 +42,10 @@ test_that('glue works', { ## expect_warning(formatter_glue(NULL)) ## expect_warning(log_info(NULL)) ## expect_warning(log_info(a = 42, b = "foobar")) - log_appender(appender_stdout) - }) -log_formatter(formatter_glue_safe) test_that('glue_safe works', { + local_test_logger(formatter = formatter_glue_safe) expect_equal(formatter_glue_safe("Hi"), "Hi") expect_equal(formatter_glue_safe(" Hi"), " Hi") @@ -66,8 +62,8 @@ test_that('glue_safe works', { }) -log_formatter(formatter_sprintf) test_that('sprintf works', { + local_test_logger(formatter = formatter_sprintf) expect_equal(formatter_sprintf("Hi"), "Hi") expect_equal(formatter_sprintf("Hi %s", 42), "Hi 42") @@ -105,18 +101,18 @@ test_that('glue+sprintf works', { expect_equal(formatter_glue_or_sprintf('fun{fun}'), 'fun{fun}') for (fn in c(formatter_sprintf, formatter_glue_or_sprintf)) { - log_formatter(fn) - log_appender(appender_void) + local_test_logger(formatter = fn, appender = appender_void) expect_error(log_info(character(0)), NA) - log_appender(appender_stdout) + + local_test_logger(formatter = fn) expect_output(log_info(character(0)), 'INFO') } }) test_that('formatter_logging works', { + local_test_logger(formatter = formatter_logging) - log_formatter(formatter_logging) expect_output(log_info('42'), '42') expect_output(log_info(42), '42') expect_output(log_info(4+2), '4 \\+ 2') @@ -133,12 +129,17 @@ test_that('formatter_logging works', { test_that('special chars in the text work', { expect_equal(formatter_glue('JSON: {toJSON(1:4)}'), 'JSON: [1,2,3,4]') expect_equal(formatter_glue('JSON: {toJSON(iris[1:2, ], auto_unbox = TRUE)}'), 'JSON: [{"Sepal.Length":5.1,"Sepal.Width":3.5,"Petal.Length":1.4,"Petal.Width":0.2,"Species":"setosa"},{"Sepal.Length":4.9,"Sepal.Width":3,"Petal.Length":1.4,"Petal.Width":0.2,"Species":"setosa"}]') # nolint + + local_test_logger() expect_output(log_info('JSON: {toJSON(1:4)}'), '[1,2,3,4]') expect_output(log_info('JSON: {toJSON(iris[1:2, ], auto_unbox = TRUE)}'), '[{"Sepal.Length":5.1,"Sepal.Width":3.5,"Petal.Length":1.4,"Petal.Width":0.2,"Species":"setosa"},{"Sepal.Length":4.9,"Sepal.Width":3,"Petal.Length":1.4,"Petal.Width":0.2,"Species":"setosa"}]') # nolint }) -log_formatter(formatter_pander) test_that('pander formatter', { + local_test_logger(formatter = formatter_pander) + # pander partially matches coef to coefficient + withr::local_options(warnPartialMatchDollar = FALSE) + expect_output(log_info(42), '_42_') expect_output(log_info('42'), '42') expect_output(log_info(head(iris)), 'Sepal.Length') @@ -149,23 +150,20 @@ test_that('pander formatter', { rm(everything) rm(f) -log_formatter(formatter_paste) test_that('paste formatter in actual logs', { + local_test_logger(formatter = formatter_paste) expect_output(log_info('hi', 5), 'hi 5') }) -log_formatter(formatter_glue) test_that('skip formatter', { - expect_output(log_info(skip_formatter('hi {pi}')), 'hi \\{pi\\}') + local_test_logger(formatter = formatter_glue) + expect_output(log_info(skip_formatter('hi {pi}')), 'hi \\{pi\\}') expect_error(log_info(skip_formatter(mtcars))) expect_error(log_info(skip_formatter('hi {x}', x = 4))) }) -log_formatter(formatter_json) test_that('skip formatter', { + local_test_logger(formatter = formatter_json) expect_output(log_info(skip_formatter('hi {pi}')), 'hi \\{pi\\}') expect_output(log_info(x = 1), '\\{"x":1\\}') }) - -log_formatter(formatter) -log_appender(appender) diff --git a/tests/testthat/test-helpers.R b/tests/testthat/test-helpers.R index 210fc39c..7d92810d 100644 --- a/tests/testthat/test-helpers.R +++ b/tests/testthat/test-helpers.R @@ -1,42 +1,33 @@ library(logger) library(testthat) -## save current settings so that we can reset later -appender <- log_appender() - -log_appender(appender_stdout) - context('helpers') test_that('separator', { - original_layout <- log_layout() - log_layout(layout_blank) + local_test_logger(layout = layout_blank) expect_output(log_separator(), '={80,80}') - log_layout(original_layout) + + local_test_logger() expect_output(log_separator(separator = '-'), '---') expect_output(log_separator(), 'INFO') expect_output(log_separator(WARN), 'WARN') }) test_that('tictoc', { + local_test_logger() expect_output(log_tictoc(), 'timer') }) test_that('log with separator', { + local_test_logger() expect_output(log_with_separator(42), '===') - logger <- layout_glue_generator(format = '{node}/{pid}/{namespace}/{fn} {time} {level}: {msg}') - layout_original <- log_layout() - log_layout(logger) expect_output(log_with_separator('Boo!', level = FATAL, width = 120), width = 120) - log_layout(layout_original) }) test_that('log failure', { + local_test_logger() expect_output(log_failure("foobar"), NA) expect_output(try(log_failure(foobar), silent = TRUE), 'ERROR.*foobar') expect_error(log_failure('foobar'), NA) expect_match(capture.output(expect_error(log_failure(foobar))), 'not found') }) - -## reset settings -log_appender(appender) diff --git a/tests/testthat/test-layout.R b/tests/testthat/test-layout.R index cbf648ce..8606d2a8 100644 --- a/tests/testthat/test-layout.R +++ b/tests/testthat/test-layout.R @@ -2,22 +2,16 @@ library(logger) library(testthat) library(jsonlite) -## save current settings so that we can reset later -layout <- log_layout() -appender <- log_appender() - -log_appender(appender_stdout) - context('layouts') -log_layout(layout_blank) test_that('blank layout', { + local_test_logger(layout = layout_blank) expect_output(log_info('foobar'), 'foobar') expect_equal(capture.output(log_info('foobar')), 'foobar') }) -log_layout(layout_glue_colors) test_that('colorized layout', { + local_test_logger(layout = layout_glue_colors) expect_output(log_info('foobar'), 'INFO') expect_output(log_info('foobar'), 'foobar') expect_output(log_error('foobar'), 'ERROR') @@ -25,22 +19,23 @@ test_that('colorized layout', { }) test_that('metavars', { - log_layout(layout_glue_generator(format = '{level} {ans} {fn} {msg}')) + local_test_logger(layout = layout_glue_generator('{level} {ans} {fn} {msg}')) expect_output((function(){log_info(42)})(), 'INFO') expect_output((function(){log_warn(42)})(), 'WARN') expect_output((function(){log_info(42)})(), 'log_info') - log_layout(layout_glue_generator(format = '{fn}')) + + local_test_logger(layout = layout_glue_generator('{fn}')) expect_output({fun42<-function(){log_info(42)};fun42();rm(fun42)}, 'fun42') }) -log_layout(layout_json()) test_that('JSON layout', { + local_test_logger(layout = layout_json()) expect_equal(fromJSON(capture.output(log_info('foobar')))$level, 'INFO') expect_equal(fromJSON(capture.output(log_info('foobar')))$msg, 'foobar') }) -log_layout(layout_json_parser(fields = c())) test_that('JSON parser layout', { + local_test_logger(layout = layout_json_parser(fields = c())) expect_output(log_info(skip_formatter('{"x": 4}')), '\\{"x":4\\}') expect_equal(capture.output(log_info(skip_formatter('{"x": 4}'))), '{"x":4}') }) @@ -58,15 +53,11 @@ test_that('must throw errors', { }) -log_layout(layout_logging) test_that('logging layout', { + local_test_logger(layout = layout_logging) expect_output(log_level(INFO, 'foo', namespace = 'bar'), 'INFO:bar:foo') expect_output(log_info('foobar'), 'INFO') expect_output(log_info('foo', namespace = 'bar'), 'foo') expect_output(log_info('foo', namespace = 'bar'), 'bar') expect_output(log_info('foo', namespace = 'bar'), 'INFO:bar:foo') }) - -## reset settings -log_layout(layout) -log_appender(appender) diff --git a/tests/testthat/test-logger.R b/tests/testthat/test-logger.R index 5af12401..37a4ff8f 100644 --- a/tests/testthat/test-logger.R +++ b/tests/testthat/test-logger.R @@ -1,17 +1,11 @@ library(logger) library(testthat) -## save current settings so that we can reset later -threshold <- log_threshold() -appender <- log_appender() -layout <- log_layout() - context('loggers') -log_appender(appender_stdout) - -log_threshold(WARN) test_that('log levels', { + local_test_logger(WARN) + expect_output(log_fatal('foo'), 'FATAL.*foo') expect_output(log_error('foo'), 'ERROR.*foo') expect_output(log_warn('foo'), 'WARN.*foo') @@ -31,8 +25,8 @@ test_that('log levels', { expect_output(log_level(as.loglevel(600L), 'foo'), NA) }) -log_threshold(OFF) test_that('log levels - OFF', { + local_test_logger(OFF) expect_output(log_fatal('foo'), NA) expect_output(log_error('foo'), NA) expect_output(log_warn('foo'), NA) @@ -42,8 +36,8 @@ test_that('log levels - OFF', { expect_output(log_trace('foo'), NA) }) -log_threshold(TRACE) test_that('log thresholds', { + local_test_logger(TRACE) expect_output(log_fatal('foo'), 'FATAL.*foo') expect_output(log_error('foo'), 'ERROR.*foo') expect_output(log_warn('foo'), 'WARN.*foo') @@ -53,8 +47,8 @@ test_that('log thresholds', { expect_output(log_trace('foo'), 'TRACE.*foo') }) -log_threshold(WARN) test_that('with log thresholds', { + local_test_logger(WARN) expect_output(with_log_threshold(log_fatal('foo'), threshold = TRACE), 'FATAL.*foo') expect_output(with_log_threshold(log_error('foo'), threshold = TRACE), 'ERROR.*foo') expect_output(with_log_threshold(log_error('foo'), threshold = FATAL), NA) @@ -62,9 +56,9 @@ test_that('with log thresholds', { expect_output(with_log_threshold(log_debug('foo'), threshold = INFO), NA) }) -log_layout(layout_glue_generator('{level} {msg}')) -log_threshold(TRACE) test_that('simple glue layout with no threshold', { + local_test_logger(TRACE, layout = layout_glue_generator('{level} {msg}')) + expect_equal(capture.output(log_fatal('foobar')), 'FATAL foobar') expect_equal(capture.output(log_error('foobar')), 'ERROR foobar') expect_equal(capture.output(log_warn('foobar')), 'WARN foobar') @@ -73,8 +67,8 @@ test_that('simple glue layout with no threshold', { expect_equal(capture.output(log_trace('foobar')), 'TRACE foobar') }) -log_threshold(INFO) test_that('simple glue layout with threshold', { + local_test_logger(INFO, layout = layout_glue_generator('{level} {msg}')) expect_equal(capture.output(log_fatal('foobar')), 'FATAL foobar') expect_equal(capture.output(log_error('foobar')), 'ERROR foobar') expect_equal(capture.output(log_warn('foobar')), 'WARN foobar') @@ -84,20 +78,22 @@ test_that('simple glue layout with threshold', { }) test_that('namespaces', { - log_threshold(ERROR, namespace = 'custom') + local_test_logger(ERROR, namespace = 'custom', layout = layout_glue_generator('{level} {msg}')) expect_output(log_fatal('foobar', namespace = 'custom'), 'FATAL foobar') expect_output(log_error('foobar', namespace = 'custom'), 'ERROR foobar') expect_output(log_info('foobar', namespace = 'custom'), NA) expect_output(log_debug('foobar', namespace = 'custom'), NA) - log_threshold(INFO, namespace = 'custom') + + local_test_logger(INFO, namespace = 'custom', layout = layout_glue_generator('{level} {msg}')) expect_output(log_info('foobar', namespace = 'custom'), 'INFO foobar') expect_output(log_debug('foobar', namespace = 'custom'), NA) + log_threshold(TRACE, namespace = log_namespaces()) expect_output(log_debug('foobar', namespace = 'custom'), 'DEBUG foobar') - log_threshold(INFO) }) test_that('simple glue layout with threshold directly calling log', { + local_test_logger(layout = layout_glue_generator('{level} {msg}')) expect_equal(capture.output(log_level(FATAL, 'foobar')), 'FATAL foobar') expect_equal(capture.output(log_level(ERROR, 'foobar')), 'ERROR foobar') expect_equal(capture.output(log_level(WARN, 'foobar')), 'WARN foobar') @@ -107,12 +103,12 @@ test_that('simple glue layout with threshold directly calling log', { }) test_that('built in variables: pid', { - log_layout(layout_glue_generator('{pid}')) + local_test_logger(layout = layout_glue_generator('{pid}')) expect_equal(capture.output(log_info('foobar')), as.character(Sys.getpid())) }) test_that('built in variables: fn and call', { - log_layout(layout_glue_generator('{fn} / {call}')) + local_test_logger(layout = layout_glue_generator('{fn} / {call}')) f <- function() log_info('foobar') expect_output(f(), 'f / f()') g <- function() f() @@ -122,9 +118,10 @@ test_that('built in variables: fn and call', { }) test_that('built in variables: namespace', { - log_layout(layout_glue_generator('{ns}')) + local_test_logger(layout = layout_glue_generator('{ns}')) expect_output(log_info('bar', namespace = 'foo'), 'foo') - log_layout(layout_glue_generator('{ans}')) + + local_test_logger(layout = layout_glue_generator('{ans}')) expect_output(log_info('bar', namespace = 'foo'), 'global') }) @@ -133,6 +130,8 @@ test_that('print.level', { }) test_that('config setter called from do.call', { + local_test_logger() + t <- tempfile() expect_error(do.call(log_appender, list(appender_file(t))), NA) log_info(42) @@ -150,10 +149,6 @@ test_that('config setter called from do.call', { }) test_that('providing log_level() args to wrappers diretly is OK', { + local_test_logger(WARN) expect_silent(log_info('{Sepal.Length}', .topenv = iris)) }) - -## reset settings -log_threshold(threshold) -log_layout(layout) -log_appender(appender) diff --git a/tests/testthat/test-return.R b/tests/testthat/test-return.R index 611e22f2..053d3730 100644 --- a/tests/testthat/test-return.R +++ b/tests/testthat/test-return.R @@ -1,20 +1,15 @@ library(logger) library(testthat) -## save current settings so that we can reset later -formatter <- log_formatter() -appender <- log_appender() - context('return value') -t <- tempfile() -log_appender(appender_file(t)) - glue_or_sprintf_result <- c( "Hi foo, did you know that 2*4=8?", "Hi bar, did you know that 2*4=8?") test_that("return value is formatted string", { + local_test_logger(appender = appender_file(withr::local_tempfile())) + log_formatter(formatter_glue) expect_equal(log_info('pi is {round(pi, 2)}')[[1]]$message, 'pi is 3.14') expect_match(log_info('pi is {round(pi, 2)}')[[1]]$record, 'INFO [[0-9: -]*] pi is 3.14') @@ -22,9 +17,3 @@ test_that("return value is formatted string", { expect_equal(log_info('pi is {round(pi, 2)}')[[1]]$message, 'pi is 3.14') expect_equal(log_info('pi is {round(pi, 2)}')[[2]]$message, 'pi is {round(pi, 2)}') }) - -## reset settings -unlink(t) -delete_logger_index(index = 2) -log_formatter(formatter) -log_appender(appender) diff --git a/tests/testthat/test-utils.R b/tests/testthat/test-utils.R index 3217d594..960aaae2 100644 --- a/tests/testthat/test-utils.R +++ b/tests/testthat/test-utils.R @@ -1,10 +1,6 @@ library(logger) library(testthat) -## save current settings so that we can reset later -appender <- log_appender() -log_appender(appender_stdout) - context('utils') test_that('fail_on_missing_package', { @@ -14,6 +10,7 @@ test_that('fail_on_missing_package', { }) test_that('except helper', { + local_test_logger() expect_equal(FunDoesNotExist(1:10) %except% sum(1:10) / length(1:10), 5.5) expect_output(FunDoesNotExist(1:10) %except% sum(1:10) / length(1:10), 'WARN') }) @@ -27,17 +24,13 @@ test_that('validate_log_level', { test_that('catch_base_log', { expect_true(nchar(logger:::catch_base_log(ERROR, NA_character_)) == 28) expect_true(nchar(logger:::catch_base_log(INFO, NA_character_)) == 27) - layout_original <- log_layout() - log_layout(layout_blank) + local_test_logger(layout = layout_blank) expect_true(nchar(logger:::catch_base_log(INFO, NA_character_)) == 0) - log_layout(layout_original) - layout_original <- log_layout(namespace = 'TEMP') - logger <- layout_glue_generator(format = '{namespace}/{fn} {level}: {msg}') - log_layout(logger, namespace = 'TEMP') + + local_test_logger( + layout = layout_glue_generator(format = '{namespace}/{fn} {level}: {msg}'), + namespace = "TEMP" + ) expect_true(nchar(logger:::catch_base_log(INFO, 'TEMP', .topcall = NA)) == 14) expect_true(nchar(logger:::catch_base_log(INFO, 'TEMP', .topcall = call('5char'))) == 17) - log_layout(layout_original) }) - -## reset settings -log_appender(appender) From abcae89f7efccf72f65d268b749d74a5ebb20446 Mon Sep 17 00:00:00 2001 From: Hadley Wickham Date: Thu, 1 Aug 2024 09:15:08 -0500 Subject: [PATCH 2/9] Revert accidental change --- R/logger.R | 2 ++ 1 file changed, 2 insertions(+) diff --git a/R/logger.R b/R/logger.R index deb79b0a..ba1b8da0 100644 --- a/R/logger.R +++ b/R/logger.R @@ -70,6 +70,7 @@ logger <- function(threshold, formatter, layout, appender) { } } + #' Checks if provided namespace exists and falls back to global if not #' @param namespace string #' @return string @@ -123,6 +124,7 @@ log_config_setter <- function(fun_name, arg, namespace, index) { assign(namespace, configs, envir = namespaces) } + #' Delete an index from a logger namespace #' @inheritParams log_threshold #' @export From 4dc8422a947e15086f7c7c9293c3b74391853cff Mon Sep 17 00:00:00 2001 From: Hadley Wickham Date: Fri, 2 Aug 2024 07:38:47 -0500 Subject: [PATCH 3/9] Add withr dep --- DESCRIPTION | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index df5cccd2..3397518a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -14,7 +14,7 @@ Encoding: UTF-8 RoxygenNote: 7.3.2 License: AGPL-3 Imports: - utils + utils Suggests: glue, pander, @@ -36,7 +36,8 @@ Suggests: txtq, botor, R.utils, - syslognet + syslognet, + withr Enhances: logging, futile.logger, From 6f3a8d81167e7791447d1b6259dd8e028d9ff1fe Mon Sep 17 00:00:00 2001 From: Hadley Wickham Date: Sun, 4 Aug 2024 17:08:40 -0500 Subject: [PATCH 4/9] Fix accidental WS --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index b1a1689b..e112b4aa 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -14,7 +14,7 @@ Encoding: UTF-8 RoxygenNote: 7.3.2 License: AGPL-3 Imports: - utils + utils Suggests: glue, pander, From a21dc18906a0d77ff052ca9d7cd974a3f5b61efc Mon Sep 17 00:00:00 2001 From: "Gergely Daroczi (@daroczig)" Date: Mon, 5 Aug 2024 21:28:27 +0200 Subject: [PATCH 5/9] add img for pkgdown --- vignettes/anatomy.Rmd | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vignettes/anatomy.Rmd b/vignettes/anatomy.Rmd index a8141153..3396ab73 100644 --- a/vignettes/anatomy.Rmd +++ b/vignettes/anatomy.Rmd @@ -5,6 +5,8 @@ vignette: > %\VignetteIndexEntry{The Anatomy of a Log Request} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} +resource_files: + - logger_structure.svg --- ```{r setup, include = FALSE} From 59d7388840b79c607f3fae3ac7a791be71145d5a Mon Sep 17 00:00:00 2001 From: Hadley Wickham Date: Mon, 5 Aug 2024 16:05:44 -0500 Subject: [PATCH 6/9] Polish color docs * Eliminate demo in favour of a runnable example (since pkgdown captures the colours) * Document `colorize_` and `grayscale_` together * Use `appender_stdout()` inside of pkgdown so that the logs are shown in the examples --- .gitignore | 2 ++ R/color.R | 35 +++++++++++++++------------------ R/layouts.R | 8 ++++++-- R/utils.R | 4 ++++ R/zzz.R | 2 +- README.Rmd | 2 +- README.md | 37 +++++++++++++++++------------------ _pkgdown.yml | 1 - demo/00Index | 1 - demo/colors.R | 11 ----------- man/colorize_by_log_level.Rd | 21 ++++++++++++++++---- man/grayscale_by_log_level.Rd | 30 ---------------------------- man/layout_glue_colors.Rd | 8 +++++--- 13 files changed, 70 insertions(+), 92 deletions(-) delete mode 100644 demo/00Index delete mode 100644 demo/colors.R delete mode 100644 man/grayscale_by_log_level.Rd diff --git a/.gitignore b/.gitignore index 0906bc7e..35dc13a4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ docs/ README.html + +/.quarto/ diff --git a/R/color.R b/R/color.R index 78994bfc..6ef91e99 100644 --- a/R/color.R +++ b/R/color.R @@ -1,9 +1,12 @@ -#' Colorize string by the related log level +#' Color string by the related log level #' -#' Adding color to a string to be used in terminal output. Supports ANSI standard colors 8 or 256. -#' @param msg string +#' Color log messages according to their severity with either a rainbow +#' or grayscale color scheme. The greyscale theme assumes a dark background on +#' the terminal. +#' +#' @param msg String to color. #' @param level see [log_levels()] -#' @return string with ANSI escape code +#' @return A string with ANSI escape codes. #' @export #' @examplesIf requireNamespace("crayon") #' cat(colorize_by_log_level('foobar', FATAL), '\n') @@ -13,6 +16,14 @@ #' cat(colorize_by_log_level('foobar', INFO), '\n') #' cat(colorize_by_log_level('foobar', DEBUG), '\n') #' cat(colorize_by_log_level('foobar', TRACE), '\n') +#' +#' cat(grayscale_by_log_level('foobar', FATAL), '\n') +#' cat(grayscale_by_log_level('foobar', ERROR), '\n') +#' cat(grayscale_by_log_level('foobar', WARN), '\n') +#' cat(grayscale_by_log_level('foobar', SUCCESS), '\n') +#' cat(grayscale_by_log_level('foobar', INFO), '\n') +#' cat(grayscale_by_log_level('foobar', DEBUG), '\n') +#' cat(grayscale_by_log_level('foobar', TRACE), '\n') colorize_by_log_level <- function(msg, level) { fail_on_missing_package('crayon') @@ -33,22 +44,8 @@ colorize_by_log_level <- function(msg, level) { } - -#' Render a string with light/dark gray based on the related log level -#' -#' Adding color to a string to be used in terminal output. Supports ANSI standard colors 8 or 256. -#' @param msg string -#' @param level see [log_levels()] -#' @return string with ANSI escape code #' @export -#' @examplesIf requireNamespace("crayon") -#' cat(grayscale_by_log_level('foobar', FATAL), '\n') -#' cat(grayscale_by_log_level('foobar', ERROR), '\n') -#' cat(grayscale_by_log_level('foobar', WARN), '\n') -#' cat(grayscale_by_log_level('foobar', SUCCESS), '\n') -#' cat(grayscale_by_log_level('foobar', INFO), '\n') -#' cat(grayscale_by_log_level('foobar', DEBUG), '\n') -#' cat(grayscale_by_log_level('foobar', TRACE), '\n') +#' @rdname colorize_by_log_level grayscale_by_log_level <- function(msg, level) { fail_on_missing_package('crayon') diff --git a/R/layouts.R b/R/layouts.R index 74149540..7c5fa439 100644 --- a/R/layouts.R +++ b/R/layouts.R @@ -168,10 +168,15 @@ layout_glue <- layout_glue_generator() #' Format a log message with `glue` and ANSI escape codes to add colors +#' +#' Colour log levels based on their severity. Log levels are coloured +#' with [colorize_by_log_level()] and the messages are coloured with +#' [grayscale_by_log_level()]. +#' #' @inheritParams layout_simple #' @return character vector #' @export -#' @examples \dontrun{ +#' @examplesIf requireNamespace("crayon") #' log_layout(layout_glue_colors) #' log_threshold(TRACE) #' log_info('Starting the script...') @@ -182,7 +187,6 @@ layout_glue <- layout_glue_generator() #' log_debug('Getting an error is usually bad') #' log_error('This is another problem') #' log_fatal('The last problem.') -#' } #' @seealso This is a [log_layout()], for alternatives, see [layout_blank()], [layout_simple()], [layout_glue()], [layout_json()], [layout_json_parser()], or generator functions such as [layout_glue_generator()] #' @note This functionality depends on the \pkg{crayon} package. layout_glue_colors <- layout_glue_generator( diff --git a/R/utils.R b/R/utils.R index 61972994..62dc9292 100644 --- a/R/utils.R +++ b/R/utils.R @@ -92,3 +92,7 @@ catch_base_log <- function( log_appender(orginal_appender, namespace = namespace) res } + +in_pkgdown <- function() { + identical(Sys.getenv("IN_PKGDOWN"), "true") +} diff --git a/R/zzz.R b/R/zzz.R index f6b58bd1..7d108136 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -10,7 +10,7 @@ namespaces <- new.env() threshold = as.loglevel(Sys.getenv('LOGGER_LOG_LEVEL', unset = 'INFO')), layout = layout_simple, formatter = formatter_sprintf, - appender = appender_console)) + appender = if (in_pkgdown()) appender_stdout else appender_console)) if (requireNamespace('glue', quietly = TRUE)) { log_formatter(formatter_glue, namespace = 'global', index = 1) diff --git a/README.Rmd b/README.Rmd index a9af716a..f496522a 100644 --- a/README.Rmd +++ b/README.Rmd @@ -67,7 +67,7 @@ for (letter in letters) { 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, as you can see in `demo(colors, package = 'logger', echo = FALSE)`: +You can even use a custom log layout to render the log records with colors, as you can see in `layout_glue_colors()`: colored log output diff --git a/README.md b/README.md index fa22a5d6..a9926104 100644 --- a/README.md +++ b/README.md @@ -46,11 +46,11 @@ messages in ad-hoc and programmatic ways: library(logger) log_threshold(DEBUG) log_info('Script starting up...') -#> INFO [2024-07-31 08:26:30] Script starting up... +#> INFO [2024-08-05 16:05:22] Script starting up... pkgs <- available.packages() log_info('There are {nrow(pkgs)} R packages hosted on CRAN!') -#> INFO [2024-07-31 08:26:30] There are 21122 R packages hosted on CRAN! +#> INFO [2024-08-05 16:05:23] There are 21132 R packages hosted on CRAN! for (letter in letters) { lpkgs <- sum(grepl(letter, pkgs[, 'Package'], ignore.case = TRUE)) @@ -59,28 +59,27 @@ for (letter in letters) { '{lpkgs} R packages including the {shQuote(letter)} letter' ) } -#> DEBUG [2024-07-31 08:26:30] 10188 R packages including the 'a' letter -#> DEBUG [2024-07-31 08:26:30] 7013 R packages including the 'c' letter -#> DEBUG [2024-07-31 08:26:30] 5750 R packages including the 'd' letter -#> DEBUG [2024-07-31 08:26:30] 10902 R packages including the 'e' letter -#> DEBUG [2024-07-31 08:26:30] 8821 R packages including the 'i' letter -#> DEBUG [2024-07-31 08:26:30] 7055 R packages including the 'l' letter -#> DEBUG [2024-07-31 08:26:30] 7039 R packages including the 'm' letter -#> DEBUG [2024-07-31 08:26:30] 6661 R packages including the 'n' letter -#> DEBUG [2024-07-31 08:26:30] 7859 R packages including the 'o' letter -#> DEBUG [2024-07-31 08:26:30] 6579 R packages including the 'p' letter -#> DEBUG [2024-07-31 08:26:31] 11224 R packages including the 'r' letter -#> DEBUG [2024-07-31 08:26:31] 10292 R packages including the 's' letter -#> DEBUG [2024-07-31 08:26:31] 9526 R packages including the 't' letter +#> DEBUG [2024-08-05 16:05:23] 10194 R packages including the 'a' letter +#> DEBUG [2024-08-05 16:05:23] 7016 R packages including the 'c' letter +#> DEBUG [2024-08-05 16:05:23] 5751 R packages including the 'd' letter +#> DEBUG [2024-08-05 16:05:23] 10908 R packages including the 'e' letter +#> DEBUG [2024-08-05 16:05:23] 8825 R packages including the 'i' letter +#> DEBUG [2024-08-05 16:05:23] 7060 R packages including the 'l' letter +#> DEBUG [2024-08-05 16:05:23] 7045 R packages including the 'm' letter +#> DEBUG [2024-08-05 16:05:23] 6665 R packages including the 'n' letter +#> DEBUG [2024-08-05 16:05:23] 7863 R packages including the 'o' letter +#> DEBUG [2024-08-05 16:05:23] 6582 R packages including the 'p' letter +#> DEBUG [2024-08-05 16:05:23] 11230 R packages including the 'r' letter +#> DEBUG [2024-08-05 16:05:23] 10296 R packages including the 's' letter +#> DEBUG [2024-08-05 16:05:23] 9531 R packages including the 't' letter log_warn('There might be many, like {1:2} or more warnings!!!') -#> WARN [2024-07-31 08:26:31] There might be many, like 1 or more warnings!!! -#> WARN [2024-07-31 08:26:31] There might be many, like 2 or more warnings!!! +#> WARN [2024-08-05 16:05:23] There might be many, like 1 or more warnings!!! +#> WARN [2024-08-05 16:05:23] There might be many, like 2 or more warnings!!! ``` You can even use a custom log layout to render the log records with -colors, as you can see in -`demo(colors, package = 'logger', echo = FALSE)`: +colors, as you can see in `layout_glue_colors()`: colored log output diff --git a/_pkgdown.yml b/_pkgdown.yml index df07a0aa..f6ffac89 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -61,7 +61,6 @@ reference: - title: Other helpers contents: - colorize_by_log_level - - grayscale_by_log_level - logger - delete_logger_index - "%except%" diff --git a/demo/00Index b/demo/00Index deleted file mode 100644 index d522594d..00000000 --- a/demo/00Index +++ /dev/null @@ -1 +0,0 @@ -colors Using a colored layout diff --git a/demo/colors.R b/demo/colors.R deleted file mode 100644 index c8a3d9b4..00000000 --- a/demo/colors.R +++ /dev/null @@ -1,11 +0,0 @@ -suppressWarnings(suppressMessages(library(logger))) -log_layout(layout_glue_colors) -log_threshold(TRACE) -log_info('Starting the script...') -log_debug('This is the second line') -log_trace('That is being placed right after the first one.') -log_warn('Some errors might come!') -log_error('This is a problem') -log_debug('Getting an error is usually bad') -log_error('This is another problem') -log_fatal('The last problem.') \ No newline at end of file diff --git a/man/colorize_by_log_level.Rd b/man/colorize_by_log_level.Rd index dcbe6652..727c9dff 100644 --- a/man/colorize_by_log_level.Rd +++ b/man/colorize_by_log_level.Rd @@ -2,20 +2,25 @@ % Please edit documentation in R/color.R \name{colorize_by_log_level} \alias{colorize_by_log_level} -\title{Colorize string by the related log level} +\alias{grayscale_by_log_level} +\title{Color string by the related log level} \usage{ colorize_by_log_level(msg, level) + +grayscale_by_log_level(msg, level) } \arguments{ -\item{msg}{string} +\item{msg}{String to color.} \item{level}{see \code{\link[=log_levels]{log_levels()}}} } \value{ -string with ANSI escape code +A string with ANSI escape codes. } \description{ -Adding color to a string to be used in terminal output. Supports ANSI standard colors 8 or 256. +Color log messages according to their severity with either a rainbow +or grayscale color scheme. The greyscale theme assumes a dark background on +the terminal. } \examples{ \dontshow{if (requireNamespace("crayon")) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} @@ -26,5 +31,13 @@ cat(colorize_by_log_level('foobar', SUCCESS), '\n') cat(colorize_by_log_level('foobar', INFO), '\n') cat(colorize_by_log_level('foobar', DEBUG), '\n') cat(colorize_by_log_level('foobar', TRACE), '\n') + +cat(grayscale_by_log_level('foobar', FATAL), '\n') +cat(grayscale_by_log_level('foobar', ERROR), '\n') +cat(grayscale_by_log_level('foobar', WARN), '\n') +cat(grayscale_by_log_level('foobar', SUCCESS), '\n') +cat(grayscale_by_log_level('foobar', INFO), '\n') +cat(grayscale_by_log_level('foobar', DEBUG), '\n') +cat(grayscale_by_log_level('foobar', TRACE), '\n') \dontshow{\}) # examplesIf} } diff --git a/man/grayscale_by_log_level.Rd b/man/grayscale_by_log_level.Rd deleted file mode 100644 index 22d777e5..00000000 --- a/man/grayscale_by_log_level.Rd +++ /dev/null @@ -1,30 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/color.R -\name{grayscale_by_log_level} -\alias{grayscale_by_log_level} -\title{Render a string with light/dark gray based on the related log level} -\usage{ -grayscale_by_log_level(msg, level) -} -\arguments{ -\item{msg}{string} - -\item{level}{see \code{\link[=log_levels]{log_levels()}}} -} -\value{ -string with ANSI escape code -} -\description{ -Adding color to a string to be used in terminal output. Supports ANSI standard colors 8 or 256. -} -\examples{ -\dontshow{if (requireNamespace("crayon")) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} -cat(grayscale_by_log_level('foobar', FATAL), '\n') -cat(grayscale_by_log_level('foobar', ERROR), '\n') -cat(grayscale_by_log_level('foobar', WARN), '\n') -cat(grayscale_by_log_level('foobar', SUCCESS), '\n') -cat(grayscale_by_log_level('foobar', INFO), '\n') -cat(grayscale_by_log_level('foobar', DEBUG), '\n') -cat(grayscale_by_log_level('foobar', TRACE), '\n') -\dontshow{\}) # examplesIf} -} diff --git a/man/layout_glue_colors.Rd b/man/layout_glue_colors.Rd index ca595d8d..03307afc 100644 --- a/man/layout_glue_colors.Rd +++ b/man/layout_glue_colors.Rd @@ -30,13 +30,15 @@ layout_glue_colors( character vector } \description{ -Format a log message with \code{glue} and ANSI escape codes to add colors +Colour log levels based on their severity. Log levels are coloured +with \code{\link[=colorize_by_log_level]{colorize_by_log_level()}} and the messages are coloured with +\code{\link[=grayscale_by_log_level]{grayscale_by_log_level()}}. } \note{ This functionality depends on the \pkg{crayon} package. } \examples{ -\dontrun{ +\dontshow{if (requireNamespace("crayon")) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} log_layout(layout_glue_colors) log_threshold(TRACE) log_info('Starting the script...') @@ -47,7 +49,7 @@ log_error('This is a problem') log_debug('Getting an error is usually bad') log_error('This is another problem') log_fatal('The last problem.') -} +\dontshow{\}) # examplesIf} } \seealso{ This is a \code{\link[=log_layout]{log_layout()}}, for alternatives, see \code{\link[=layout_blank]{layout_blank()}}, \code{\link[=layout_simple]{layout_simple()}}, \code{\link[=layout_glue]{layout_glue()}}, \code{\link[=layout_json]{layout_json()}}, \code{\link[=layout_json_parser]{layout_json_parser()}}, or generator functions such as \code{\link[=layout_glue_generator]{layout_glue_generator()}} From 52d1c981f2b25cc812cb558be0ed2b71edfd0d35 Mon Sep 17 00:00:00 2001 From: Hadley Wickham Date: Mon, 5 Aug 2024 16:18:17 -0500 Subject: [PATCH 7/9] Require R 4.0.0 or later Please let me know if you think this is too aggressive a move for logger, but we're seeing very little usage of R 3.6.0 these days. --- DESCRIPTION | 1 + R/hooks.R | 90 ++++++++++++++++------------------------------------- 2 files changed, 28 insertions(+), 63 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index e112b4aa..f489bdf8 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -15,6 +15,7 @@ RoxygenNote: 7.3.2 License: AGPL-3 Imports: utils +Depends: R (>= 4.0.0) Suggests: glue, pander, diff --git a/R/hooks.R b/R/hooks.R index d41dba9d..83a7b30a 100644 --- a/R/hooks.R +++ b/R/hooks.R @@ -1,12 +1,3 @@ -#' Warn to update R to 4+ -#' @keywords internal -warn_if_globalCallingHandlers_is_not_available <- function() { - log_warn( - 'Using legacy version of global message/warning/error hook, ', - 'please update your R installation to at least 4.0.0 ', - 'to make use of the much more elegant globalCallingHandlers approach.') -} - #' Injects a logger call to standard messages #' @@ -17,23 +8,14 @@ warn_if_globalCallingHandlers_is_not_available <- function() { #' message('hi there') #' } log_messages <- function() { - if (R.Version()$major >= 4) { - if (any(sapply(globalCallingHandlers()[names(globalCallingHandlers()) == 'message'], - attr, which = 'implements') == 'log_messages')) { - warning('Ignoring this call to log_messages as it was registered previously.') - } else { - globalCallingHandlers( - message = structure(function(m) { - logger::log_level(logger::INFO, m$message, .topcall = m$call) - }, implements = 'log_messages')) - } + if (any(sapply(globalCallingHandlers()[names(globalCallingHandlers()) == 'message'], + attr, which = 'implements') == 'log_messages')) { + warning('Ignoring this call to log_messages as it was registered previously.') } else { - warn_if_globalCallingHandlers_is_not_available() - invisible(suppressMessages(trace( - what = 'message', - exit = substitute(logger::log_info(logger::skip_formatter(cond$message))), - print = FALSE, - where = baseenv()))) + globalCallingHandlers( + message = structure(function(m) { + logger::log_level(logger::INFO, m$message, .topcall = m$call) + }, implements = 'log_messages')) } } @@ -48,26 +30,17 @@ log_messages <- function() { #' for (i in 1:5) { Sys.sleep(runif(1)); warning(i) } #' } log_warnings <- function(muffle = getOption('logger_muffle_warnings', FALSE)) { - if (R.Version()$major >= 4) { - if (any(sapply(globalCallingHandlers()[names(globalCallingHandlers()) == 'warning'], - attr, which = 'implements') == 'log_warnings')) { - warning('Ignoring this call to log_warnings as it was registered previously.') - } else { - globalCallingHandlers( - warning = structure(function(m) { - logger::log_level(logger::WARN, m$message, .topcall = m$call) - if (isTRUE(muffle)) { - invokeRestart('muffleWarning') - } - }, implements = 'log_warnings')) - } + if (any(sapply(globalCallingHandlers()[names(globalCallingHandlers()) == 'warning'], + attr, which = 'implements') == 'log_warnings')) { + warning('Ignoring this call to log_warnings as it was registered previously.') } else { - warn_if_globalCallingHandlers_is_not_available() - invisible(suppressMessages(trace( - what = 'warning', - tracer = substitute(logger::log_warn(logger::skip_formatter(paste(list(...), collapse = '')))), - print = FALSE, - where = baseenv()))) + globalCallingHandlers( + warning = structure(function(m) { + logger::log_level(logger::WARN, m$message, .topcall = m$call) + if (isTRUE(muffle)) { + invokeRestart('muffleWarning') + } + }, implements = 'log_warnings')) } } @@ -82,26 +55,17 @@ log_warnings <- function(muffle = getOption('logger_muffle_warnings', FALSE)) { #' stop('foobar') #' } log_errors <- function(muffle = getOption('logger_muffle_errors', FALSE)) { - if (R.Version()$major >= 4) { - if (any(sapply(globalCallingHandlers()[names(globalCallingHandlers()) == 'error'], - attr, which = 'implements') == 'log_errors')) { - warning('Ignoring this call to log_errors as it was registered previously.') - } else { - globalCallingHandlers( - error = structure(function(m) { - logger::log_level(logger::ERROR, m$message, .topcall = m$call) - if (isTRUE(muffle)) { - invokeRestart('abort') - } - }, implements = 'log_errors')) - } + if (any(sapply(globalCallingHandlers()[names(globalCallingHandlers()) == 'error'], + attr, which = 'implements') == 'log_errors')) { + warning('Ignoring this call to log_errors as it was registered previously.') } else { - warn_if_globalCallingHandlers_is_not_available() - invisible(suppressMessages(trace( - what = 'stop', - tracer = substitute(logger::log_error(logger::skip_formatter(paste(list(...), collapse = '')))), - print = FALSE, - where = baseenv()))) + globalCallingHandlers( + error = structure(function(m) { + logger::log_level(logger::ERROR, m$message, .topcall = m$call) + if (isTRUE(muffle)) { + invokeRestart('abort') + } + }, implements = 'log_errors')) } } From d2ebdb4c7faa22013d51866261ee010cd62fd2fe Mon Sep 17 00:00:00 2001 From: "Gergely Daroczi (@daroczig)" Date: Mon, 5 Aug 2024 23:58:25 +0200 Subject: [PATCH 8/9] reference the video recording of the RStudio::conf(2020) talk --- README.Rmd | 8 ++++++-- README.md | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/README.Rmd b/README.Rmd index a9af716a..3132c6ce 100644 --- a/README.Rmd +++ b/README.Rmd @@ -100,10 +100,10 @@ Why use logger? I decided to write the `n+1`th extensible `log4j` logger that fi 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? +::: .pkgdown-hide + Check out the main documentation site at or the vignettes on the below topics: * [Introduction to logger](https://daroczig.github.io/logger/articles/Intro.html) @@ -115,3 +115,7 @@ Check out the main documentation site at or * [Simple Benchmarks on Performance](https://daroczig.github.io/logger/articles/performance.html) ::: + +If you prefer visual content, you can watch the video recording of the "Getting things logged" talk at RStudio::conf(2020): + +[![Gergely Daroczi presenting "Getting things logged" on using the `logger` R package at the RStudio conference in 2020](https://img.youtube.com/vi/_rUuBbml9dU/0.jpg)](https://www.youtube.com/watch?v=_rUuBbml9dU) diff --git a/README.md b/README.md index fa22a5d6..07f27fee 100644 --- a/README.md +++ b/README.md @@ -137,10 +137,10 @@ Welcome to the you already use any of the above packages for logging, you might find `vignette("migration")` useful. -
- ## Interested in more details? +
+ Check out the main documentation site at or the vignettes on the below topics: @@ -161,3 +161,7 @@ topics: Performance](https://daroczig.github.io/logger/articles/performance.html)
+ +If you prefer visual content, you can watch the video recording of the "Getting things logged" talk at RStudio::conf(2020): + +[![Gergely Daroczi presenting "Getting things logged" on using the `logger` R package at the RStudio conference in 2020](https://img.youtube.com/vi/_rUuBbml9dU/0.jpg)](https://www.youtube.com/watch?v=_rUuBbml9dU) From cf1aba5fa1ee3f85e632b1282c3562f2069dcc90 Mon Sep 17 00:00:00 2001 From: Hadley Wickham Date: Tue, 6 Aug 2024 07:15:44 -0500 Subject: [PATCH 9/9] Redocument --- ...warn_if_globalCallingHandlers_is_not_available.Rd | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 man/warn_if_globalCallingHandlers_is_not_available.Rd diff --git a/man/warn_if_globalCallingHandlers_is_not_available.Rd b/man/warn_if_globalCallingHandlers_is_not_available.Rd deleted file mode 100644 index 97ef5164..00000000 --- a/man/warn_if_globalCallingHandlers_is_not_available.Rd +++ /dev/null @@ -1,12 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/hooks.R -\name{warn_if_globalCallingHandlers_is_not_available} -\alias{warn_if_globalCallingHandlers_is_not_available} -\title{Warn to update R to 4+} -\usage{ -warn_if_globalCallingHandlers_is_not_available() -} -\description{ -Warn to update R to 4+ -} -\keyword{internal}