diff --git a/R/handlers.R b/R/handlers.R index 695e939..acf3672 100644 --- a/R/handlers.R +++ b/R/handlers.R @@ -20,7 +20,7 @@ #' message("Don't say such silly things!", appendLF = FALSE, echo = FALSE) #' } #' @export -message <- function(..., domain = NULL, appendLF = TRUE, .loggit = NA, echo = TRUE) { +message <- function(..., domain = NULL, appendLF = TRUE, .loggit = NA, echo = get_echo()) { # If the input is a condition, the base function does not allow additional input # If the input is not a condition, the call of the message must be set manually # to avoid loggit2::message being displayed as a call @@ -71,7 +71,7 @@ message <- function(..., domain = NULL, appendLF = TRUE, .loggit = NA, echo = TR #' #' @export warning <- function(..., call. = TRUE, immediate. = FALSE, noBreaks. = FALSE, - domain = NULL, .loggit = NA, echo = TRUE) { + domain = NULL, .loggit = NA, echo = get_echo()) { # If the input is a condition, the base function does not allow additional input # If the input is not a condition, the call of the warning must be set manually # to avoid loggit2::warning being displayed as a call @@ -122,7 +122,7 @@ warning <- function(..., call. = TRUE, immediate. = FALSE, noBreaks. = FALSE, #' } #' #' @export -stop <- function(..., call. = TRUE, domain = NULL, .loggit = NA, echo = TRUE) { +stop <- function(..., call. = TRUE, domain = NULL, .loggit = NA, echo = get_echo()) { # If the input is a condition, the base function does not allow additional input # If the input is not a condition, the call of the error must be set manually # to avoid loggit2::stop being displayed as a call @@ -183,7 +183,7 @@ stop <- function(..., call. = TRUE, domain = NULL, .loggit = NA, echo = TRUE) { #' } #' #' @export -stopifnot <- function(..., exprs, exprObject, local, .loggit = NA, echo = TRUE) { +stopifnot <- function(..., exprs, exprObject, local, .loggit = NA, echo = get_echo()) { # Since no calling function can be detected within tryCatch from base::stopifnot call <- if (p <- sys.parent(1L)) sys.call(p) # Required to avoid early (and simultaneous) evaluation of the arguments. diff --git a/man/message.Rd b/man/message.Rd index 00b3082..3a747ef 100644 --- a/man/message.Rd +++ b/man/message.Rd @@ -4,7 +4,7 @@ \alias{message} \title{Message Log Handler} \usage{ -message(..., domain = NULL, appendLF = TRUE, .loggit = NA, echo = TRUE) +message(..., domain = NULL, appendLF = TRUE, .loggit = NA, echo = get_echo()) } \arguments{ \item{...}{zero or more objects which can be coerced to character diff --git a/man/stop.Rd b/man/stop.Rd index 7b9b71e..193aeef 100644 --- a/man/stop.Rd +++ b/man/stop.Rd @@ -4,7 +4,7 @@ \alias{stop} \title{Stop Log Handler} \usage{ -stop(..., call. = TRUE, domain = NULL, .loggit = NA, echo = TRUE) +stop(..., call. = TRUE, domain = NULL, .loggit = NA, echo = get_echo()) } \arguments{ \item{...}{zero or more objects which can be coerced to character diff --git a/man/stopifnot.Rd b/man/stopifnot.Rd index b932940..aff5726 100644 --- a/man/stopifnot.Rd +++ b/man/stopifnot.Rd @@ -4,7 +4,7 @@ \alias{stopifnot} \title{Conditional Stop Log Handler} \usage{ -stopifnot(..., exprs, exprObject, local, .loggit = NA, echo = TRUE) +stopifnot(..., exprs, exprObject, local, .loggit = NA, echo = get_echo()) } \arguments{ \item{..., exprs}{any number of \code{R} expressions, which should each evaluate to (a logical vector of all) \code{TRUE}. diff --git a/man/warning.Rd b/man/warning.Rd index 09706ab..a149e7e 100644 --- a/man/warning.Rd +++ b/man/warning.Rd @@ -11,7 +11,7 @@ warning( noBreaks. = FALSE, domain = NULL, .loggit = NA, - echo = TRUE + echo = get_echo() ) } \arguments{ diff --git a/vignettes/further_configurations.rmd b/vignettes/further_configurations.rmd new file mode 100644 index 0000000..a3f55a6 --- /dev/null +++ b/vignettes/further_configurations.rmd @@ -0,0 +1,124 @@ +--- +title: "Further Configurations" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Further Configurations} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( #nolint + collapse = TRUE, + comment = "#>" +) +old <- options(width = 200L) +``` + + +`loggit2` can be used immediately and fully without configuration after installation. However, to fully utilize the potential of `loggit2`, some configurations can be made. + +## Configuration System + +`loggit2` uses a three-tier configuration system: + +1. Meta/System-wide Configuration +2. Global/Session-wide[^1] Configuration +3. Local/Function-specific Configuration + +The first tier is the Meta or System-wide Configuration. It is defined by environment variables that are read by `loggit2` when the package is loaded. These settings then serve as default values for the session-wide configuration. + +The second tier is the Global or Session-wide Configuration. It is defined by the `set_*()` functions of `loggit2`. + +The third tier is the Local or Function-specific Configuration, implemented through the arguments of the functions. For a quick overview of the functions, refer to the [Getting Started Vignette](loggit2.html). + +Each time a function of `loggit2` is called, the settings from the three tiers are combined. A higher tier/specificity configuration always takes precedence over a lower tier/specificity configuration. + +## Configuration Options + +The configuration options of `loggit2` are described below. For details, refer to the function documentation. + +### Log file +The log file can be set either via the environment variable `FILE_LOGGIT2`, the function `set_log_file()`, or the `logfile` argument of the logging functions `loggit()` and `with_loggit()`. The wrappers of the base R condition handler always use the session-wide configuration. + + +```{r, echo = -1} +setwd(tempdir()) +old_log <- loggit2::set_logfile("logfile.log") +loggit2::loggit(log_lvl = "DEBUG", "This message will be logged to `logfile.log`.") + + +loggit2::loggit( + log_lvl = "DEBUG", + log_msg = "This message will be logged to `otherlogfile.log`.", + logfile = "otherlogfile.log" +) + + +loggit2::with_loggit(logfile = "logfile2.log", { + base::warning("This warning message will be logged to `logfile2.log`.") +}) + +loggit2::set_logfile(old_log) +``` + +### Log level +The log level can be set either via the environment variable `LEVEL_LOGGIT2` or the function `set_log_level()`. The `.loggit` argument can also be passed to the wrappers of the base R condition handler to enforce logging (`TRUE`) or suppress it (`FALSE`). The logging function `loggit()` can enforce logging through the `ignore_log_level` argument. `with_loggit()` allows setting a log level for the code block being executed. +```{r, error = TRUE} +old_log_lvl <- loggit2::set_log_level("INFO") +loggit2::message("This message will be logged because the log level is set to INFO.") +loggit2::loggit(log_lvl = "DEBUG", "This message will not be logged because the log level is set to INFO.") +loggit2::loggit(log_lvl = "DEBUG", "This message will be logged because the log level is ignored.", ignore_log_level = TRUE) +loggit2::warning("This warning message will not be logged because .loggit is set to FALSE.", .loggit = FALSE) + +loggit2::set_log_level("ERROR") +loggit2::warning("This warning message will not be logged because the log level is set to ERROR.") +loggit2::message("This message will be logged because .loggit is set to TRUE.", .loggit = TRUE) +loggit2::stop("This error message will be logged because the log level is set to ERROR.") + +loggit2::with_loggit(log_level = "DEBUG", { + base::message("This message will be logged because the log level is set to DEBUG.") +}) + +loggit2::set_log_level(old_log_lvl) +``` + +### Echo +Whether log messages should also be output to `stdout` can be controlled via the environment variable `ECHO_LOGGIT2` or the function `set_echo()`. Additionally, all logging functions and wrappers of the base R condition handler allow direct control via the `echo` argument. +```{r} +old_echo <- loggit2::set_echo(FALSE) +loggit2::message("This message will not be logged, but it will be output to the console.") +loggit2::message("This message will be logged and output to the console.", echo = TRUE) + +loggit2::set_echo(TRUE, confirm = FALSE) +loggit2::message("This message will be logged and output to the console.") +loggit2::message("This message will be logged, but it will not be output to the console.", echo = FALSE) + +loggit2::with_loggit(echo = FALSE, { + base::message("This message will be logged, but it will not be output to the console.") +}) + +loggit2::set_echo(old_echo) +``` +### Timestamp format +The format of the timestamp can be controlled via the environment variable `TIMESTAMP_LOGGIT2` or the function `set_timestamp_format()`. + +```{r} +old_ts <- loggit2::set_timestamp_format("%H:%M:%S") +loggit2::message("This message will be logged with a timestamp in the format HH:MM:SS.") + +loggit2::set_timestamp_format(old_ts) +``` + +## Temporary Configuration +Depending on the use case, it may be useful to change temporary configurations, e.g., to log to a different file in a specific code block or to log a particular part of the code with more details (higher log level). + +One way is to manually set and reset the configurations (e.g., by using `on.exit()`), but this is cumbersome and error-prone. + +An alternative is to use `with_loggit()`. As mentioned above, almost all configurations can be adjusted directly in `with_loggit()`. + +[^1]: Note: "Session-wide" means that (unless locally configured otherwise) calls to `loggit2` functions in other packages will use the same settings. Consider this when using `loggit2` in a package that will be used elsewhere. + +```{r, include = FALSE} +options(old) +``` diff --git a/vignettes/loggit2.Rmd b/vignettes/loggit2.Rmd index 7b0635d..c4edd79 100644 --- a/vignettes/loggit2.Rmd +++ b/vignettes/loggit2.Rmd @@ -23,6 +23,9 @@ straightforward or as integral as you want to make it. No preparations are needed to use `loggit2`. However, it is recommended to explicitly set a log file using `loggit2::set_logfile("path/to/your/file")`, as `loggit2` defaults to creating a file in your temporary directory.[^1] +In order to use the full potential of `loggit2`, it is advisable to take a look at the +[further configurations](further_configurations.html) after reading this vignette. + ## Logging There are three ways to populate the log in `loggit2`. First, through wrapper functions of the base `R` condition handler, second, via the `loggit()` log function, and third, by logging (external) expressions using `with_loggit()`.