Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
* `log_errors()` gains a `traceback` argument that toggles whether the error traceback should be logged along with the message (fix #86 via #223, @thomasp85)
* File and line location of the log call is now available to the layouts (fix #110 via #224, @thomasp85)
* New `formatter_cli()` allows you to use the syntax from the cli package to create log messages (fix #210 via #225, @thomasp85)
* New `log_chunk_time()` helper function to automatically log the execution time of knitr code chunks (fix #222 via ##227, @thomasp85)
* New `log_chunk_time()` helper function to automatically log the execution time of knitr code chunks (fix #222 via #227, @thomasp85)
* Allow user to overwrite the timestamp during logging if needed (fix #230, @thomasp85)

# logger 0.4.0 (2024-10-19)

Expand Down
6 changes: 4 additions & 2 deletions R/helpers.R
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ log_separator <- function(level = INFO,
width = 80,
.logcall = sys.call(),
.topcall = sys.call(-1),
.topenv = parent.frame()) {
.topenv = parent.frame(),
.timestamp = Sys.time()) {
stopifnot(length(separator) == 1, nchar(separator) == 1)

base_info_chars <- nchar(catch_base_log(level, namespace, .topcall = .topcall, .topenv = .topenv))
Expand All @@ -113,7 +114,8 @@ log_separator <- function(level = INFO,
namespace = namespace,
.logcall = .logcall,
.topcall = .topcall,
.topenv = .topenv
.topenv = .topenv,
.timestamp = .timestamp
)
}

Expand Down
41 changes: 26 additions & 15 deletions R/layouts.R
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@
namespace = NA_character_,
.logcall = sys.call(),
.topcall = sys.call(-1),
.topenv = parent.frame()) {
.topenv = parent.frame(),
.timestamp = Sys.time()) {
sysinfo <- Sys.info()
timestamp <- Sys.time()

list(
ns = namespace,
Expand All @@ -48,7 +48,7 @@
fn = deparse_to_one_line(.topcall[[1]]),
call = deparse_to_one_line(.topcall),
location = log_call_location(.logcall),
time = timestamp,
time = .timestamp,

Check warning on line 51 in R/layouts.R

View check run for this annotation

Codecov / codecov/patch

R/layouts.R#L51

Added line #L51 was not covered by tests
levelr = log_level,
level = attr(log_level, "level"),
pid = Sys.getpid(),
Expand Down Expand Up @@ -104,7 +104,8 @@
namespace = NA_character_,
.logcall = sys.call(),
.topcall = sys.call(-1),
.topenv = parent.frame()) {
.topenv = parent.frame(),
.timestamp = Sys.time()) {
fail_on_missing_package("glue")
if (!inherits(level, "loglevel")) {
stop("Invalid log level, see ?log_levels")
Expand All @@ -116,6 +117,7 @@
.logcall = .logcall,
.topcall = .topcall,
.topenv = .topenv,
.timestamp = .timestamp,
parent = environment()
)
glue::glue(format, .envir = meta)
Expand All @@ -135,7 +137,8 @@
namespace = NA_character_,
.logcall = sys.call(),
.topcall = sys.call(-1),
.topenv = parent.frame()) {
.topenv = parent.frame(),
.timestamp = Sys.time()) {
msg
}
attr(layout_blank, "generator") <- quote(layout_blank())
Expand All @@ -152,8 +155,9 @@
namespace = NA_character_,
.logcall = sys.call(),
.topcall = sys.call(-1),
.topenv = parent.frame()) {
paste0(attr(level, "level"), " [", format(Sys.time(), "%Y-%m-%d %H:%M:%S"), "] ", msg)
.topenv = parent.frame(),
.timestamp = Sys.time()) {
paste0(attr(level, "level"), " [", format(.timestamp, "%Y-%m-%d %H:%M:%S"), "] ", msg)
}
attr(layout_simple, "generator") <- quote(layout_simple())

Expand All @@ -179,16 +183,18 @@
namespace = NA_character_,
.logcall = sys.call(),
.topcall = sys.call(-1),
.topenv = parent.frame()) {
.topenv = parent.frame(),
.timestamp = Sys.time()) {
meta <- logger_meta_env(
log_level = level,
namespace = namespace,
.logcall = .logcall,
.topcall = .topcall,
.topenv = .topenv
.topenv = .topenv,
.timestamp = .timestamp
)
paste0(
format(Sys.time(), "%Y-%m-%d %H:%M:%S"), " ",
format(meta$time, "%Y-%m-%d %H:%M:%S"), " ",
attr(level, "level"), ":",
ifelse(meta$ns == "global", "", meta$ns), ":",
msg
Expand Down Expand Up @@ -267,15 +273,17 @@
namespace = NA_character_,
.logcall = sys.call(),
.topcall = sys.call(-1),
.topenv = parent.frame()) {
.topenv = parent.frame(),
.timestamp = Sys.time()) {
fail_on_missing_package("jsonlite")

meta <- logger_meta_env(
log_level = level,
namespace = namespace,
.logcall = .logcall,
.topcall = .topcall,
.topenv = .topenv
.topenv = .topenv,
.timestamp = .timestamp
)
json <- mget(fields, meta)
sapply(msg, function(msg) jsonlite::toJSON(c(json, list(msg = msg)), auto_unbox = TRUE))
Expand Down Expand Up @@ -317,15 +325,17 @@
namespace = NA_character_,
.logcall = sys.call(),
.topcall = sys.call(-1),
.topenv = parent.frame()) {
.topenv = parent.frame(),
.timestamp = Sys.time()) {
fail_on_missing_package("jsonlite")

meta <- logger_meta_env(
log_level = level,
namespace = namespace,
.logcall = .logcall,
.topcall = .topcall,
.topenv = .topenv
.topenv = .topenv,
.timestamp = .timestamp
)
meta <- mget(fields, meta)
field_names <- names(fields)
Expand Down Expand Up @@ -363,7 +373,8 @@
namespace = NA_character_,
.logcall = sys.call(),
.topcall = sys.call(-1),
.topenv = parent.frame()) {
.topenv = parent.frame(),
.timestamp = Sys.time()) {
ret <- paste(attr(level, "level"), msg)
attr(ret, "severity") <- switch(
attr(level, "level", exact = TRUE),
Expand Down
5 changes: 2 additions & 3 deletions R/logger-meta.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ logger_meta_env <- function(log_level = NULL,
.logcall = sys.call(),
.topcall = sys.call(-1),
.topenv = parent.frame(),
.timestamp = Sys.time(),
parent = emptyenv()) {
timestamp <- Sys.time()

env <- new.env(parent = parent)
env$ns <- namespace
env$ans <- fallback_namespace(namespace)
Expand All @@ -17,7 +16,7 @@ logger_meta_env <- function(log_level = NULL,
delayedAssign("topenv", top_env_name(.topenv), assign.env = env)
delayedAssign("location", log_call_location(.logcall), assign.env = env)

env$time <- timestamp
env$time <- .timestamp
env$levelr <- log_level
env$level <- attr(log_level, "level")

Expand Down
56 changes: 39 additions & 17 deletions R/logger.R
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ logger <- function(threshold, formatter, layout, appender) {
force(appender)

function(level, ..., namespace = NA_character_,
.logcall = sys.call(), .topcall = sys.call(-1), .topenv = parent.frame()) {
.logcall = sys.call(), .topcall = sys.call(-1),
.topenv = parent.frame(), .timestamp = Sys.time()) {
res <- list(
level = level,
namespace = namespace,
Expand Down Expand Up @@ -83,7 +84,10 @@ logger <- function(threshold, formatter, layout, appender) {
res$record <- layout(
level, res$message,
namespace = namespace,
.logcall = substitute(.logcall), .topcall = substitute(.topcall), .topenv = .topenv
.logcall = substitute(.logcall),
.topcall = substitute(.topcall),
.topenv = .topenv,
.timestamp = .timestamp
)

appender(res$record)
Expand Down Expand Up @@ -307,6 +311,8 @@ log_indices <- function(namespace = "global") {
#' @param .topenv original frame of the `.topcall` calling function
#' where the formatter function will be evaluated and that is used
#' to look up the `namespace` as well via `logger:::top_env_name`
#' @param .timestamp The time the logging occured. Defaults to the current time
#' but may be overwritten if the logging is delayed from the time it happend
#' @export
#' @examples
#' \dontshow{old <- logger:::namespaces_set()}
Expand All @@ -329,7 +335,8 @@ log_indices <- function(namespace = "global") {
#' \dontshow{logger:::namespaces_set(old)}
#' @return Invisible `list` of `logger` objects. See [logger()] for more details on the format.
log_level <- function(level, ..., namespace = NA_character_,
.logcall = sys.call(), .topcall = sys.call(-1), .topenv = parent.frame()) {
.logcall = sys.call(), .topcall = sys.call(-1),
.topenv = parent.frame(), .timestamp = Sys.time()) {
## guess namespace
if (is.na(namespace)) {
topenv <- top_env_name(.topenv)
Expand All @@ -354,6 +361,7 @@ log_level <- function(level, ..., namespace = NA_character_,
NA
}
log_arg$.topenv <- .topenv
log_arg$.timestamp <- .timestamp
log_arg$namespace <- namespace

invisible(lapply(definitions, function(definition) {
Expand Down Expand Up @@ -385,44 +393,58 @@ validate_log_level <- function(level) {
#' @export
#' @rdname log_level
log_fatal <- function(..., namespace = NA_character_,
.logcall = sys.call(), .topcall = sys.call(-1), .topenv = parent.frame()) {
log_level(FATAL, ..., namespace = namespace, .logcall = .logcall, .topcall = .topcall, .topenv = .topenv)
.logcall = sys.call(), .topcall = sys.call(-1),
.topenv = parent.frame(), .timestamp = Sys.time()) {
log_level(FATAL, ..., namespace = namespace, .logcall = .logcall,
.topcall = .topcall, .topenv = .topenv, .timestamp = .timestamp)
}
#' @export
#' @rdname log_level
log_error <- function(..., namespace = NA_character_,
.logcall = sys.call(), .topcall = sys.call(-1), .topenv = parent.frame()) {
log_level(ERROR, ..., namespace = namespace, .logcall = .logcall, .topcall = .topcall, .topenv = .topenv)
.logcall = sys.call(), .topcall = sys.call(-1),
.topenv = parent.frame(), .timestamp = Sys.time()) {
log_level(ERROR, ..., namespace = namespace, .logcall = .logcall,
.topcall = .topcall, .topenv = .topenv, .timestamp = .timestamp)
}
#' @export
#' @rdname log_level
log_warn <- function(..., namespace = NA_character_,
.logcall = sys.call(), .topcall = sys.call(-1), .topenv = parent.frame()) {
log_level(WARN, ..., namespace = namespace, .logcall = .logcall, .topcall = .topcall, .topenv = .topenv)
.logcall = sys.call(), .topcall = sys.call(-1),
.topenv = parent.frame(), .timestamp = Sys.time()) {
log_level(WARN, ..., namespace = namespace, .logcall = .logcall,
.topcall = .topcall, .topenv = .topenv, .timestamp = .timestamp)
}
#' @export
#' @rdname log_level
log_success <- function(..., namespace = NA_character_,
.logcall = sys.call(), .topcall = sys.call(-1), .topenv = parent.frame()) {
log_level(SUCCESS, ..., namespace = namespace, .logcall = .logcall, .topcall = .topcall, .topenv = .topenv)
.logcall = sys.call(), .topcall = sys.call(-1),
.topenv = parent.frame(), .timestamp = Sys.time()) {
log_level(SUCCESS, ..., namespace = namespace, .logcall = .logcall,
.topcall = .topcall, .topenv = .topenv, .timestamp = .timestamp)
}
#' @export
#' @rdname log_level
log_info <- function(..., namespace = NA_character_,
.logcall = sys.call(), .topcall = sys.call(-1), .topenv = parent.frame()) {
log_level(INFO, ..., namespace = namespace, .logcall = .logcall, .topcall = .topcall, .topenv = .topenv)
.logcall = sys.call(), .topcall = sys.call(-1),
.topenv = parent.frame(), .timestamp = Sys.time()) {
log_level(INFO, ..., namespace = namespace, .logcall = .logcall,
.topcall = .topcall, .topenv = .topenv, .timestamp = .timestamp)
}
#' @export
#' @rdname log_level
log_debug <- function(..., namespace = NA_character_,
.logcall = sys.call(), .topcall = sys.call(-1), .topenv = parent.frame()) {
log_level(DEBUG, ..., namespace = namespace, .logcall = .logcall, .topcall = .topcall, .topenv = .topenv)
.logcall = sys.call(), .topcall = sys.call(-1),
.topenv = parent.frame(), .timestamp = Sys.time()) {
log_level(DEBUG, ..., namespace = namespace, .logcall = .logcall,
.topcall = .topcall, .topenv = .topenv, .timestamp = .timestamp)
}
#' @export
#' @rdname log_level
log_trace <- function(..., namespace = NA_character_,
.logcall = sys.call(), .topcall = sys.call(-1), .topenv = parent.frame()) {
log_level(TRACE, ..., namespace = namespace, .logcall = .logcall, .topcall = .topcall, .topenv = .topenv)
.logcall = sys.call(), .topcall = sys.call(-1),
.topenv = parent.frame(), .timestamp = Sys.time()) {
log_level(TRACE, ..., namespace = namespace, .logcall = .logcall,
.topcall = .topcall, .topenv = .topenv, .timestamp = .timestamp)
}


Expand Down
6 changes: 5 additions & 1 deletion man/get_logger_meta_variables.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion man/layout_blank.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion man/layout_glue.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion man/layout_glue_colors.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading