Skip to content

Commit

Permalink
ground-up rewrite of the dynamic logging dispatch
Browse files Browse the repository at this point in the history
see release notes for more detail about the changes
  • Loading branch information
bmoretz committed Mar 12, 2022
1 parent 0e46346 commit 3aa0841
Show file tree
Hide file tree
Showing 27 changed files with 452 additions and 326 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: dyn.log
Type: Package
Title: Dynamic Logging for R Inspired by Configuration Driven Development
Version: 0.3.3
Version: 0.4.0
Authors@R:
c(person(given = "Brandon",
family = "Moretz",
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export(display_log_levels)
export(ensure_logger)
export(evaluate_layout)
export(exec_context)
export(get_active_settings)
export(get_configurations)
export(init_logger)
export(level_description)
Expand Down
18 changes: 17 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Release Summaries <img src="man/figures/hex.png" width = "175" height = "200" align="right" />

# dyn.log 0.4.0

## What's Changed

* New Features
+ Ground-up rewrite of the dynamic log dispatch mechanics, to make them:
+ Simpler. There were areas of the old implementation that were incredibly hard to follow (log levels and log messages, in particular).
+ Consistent. Every format object that needs contextual information now gets it injected via the context list in the dispatch function.
+ Cleaner. Now leverages even more awesomeness from [rlang](https://github.com/r-lib/rlang), specifically 'rlang::new_function' to dynamically create the log dispatch routines & 'rlang::pairlist2' to handle completely dynamic & non-defaulted parameters (msg).
+ Testable. The new mechanics are much more unit testable, and once the code is cleaned up more (and simplified further), will focus on this area.

* Enhancements
+ updated the README.md to be more reflective of the overall goal of the package.
+ streamlined the configuration (in init_logger) to have clear separation of concerns.
+ added a 'default' logger method that is based on the attached level with the highest severity, so in areas where you always want the lowest possible information logged (even if configurations change) then you can just use 'Logger$default.' Useful for packages that might be attached by multiple downstream packages with different level definitions.

# dyn.log 0.3.3

## What's Changed
Expand All @@ -17,7 +33,7 @@

* Other
+ vscode support
+ moved the development configuration that supports vscode into a separate branch and cleaned up all the additional dependencies.
+ moved the development configuration that supports vscode into a separate branch and cleaned up all the additional dependencies.

# dyn.log 0.3.2

Expand Down
72 changes: 68 additions & 4 deletions R/config.R
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,18 @@ init_logger <- function(file_path = NULL) {
config <- yaml::read_yaml(config_file, eval.expr = TRUE)
config_name <- tools::file_path_sans_ext(basename(config_file))

log_levels <- create_log_levels(config$levels)
apply_active_settings(config$settings)

ensure_logger(config$variable)

if (!identical(active$config, config_name)) {
logger <- LogDispatch$new()

logger$set_settings(config$settings)
logger$attach_log_levels(config$levels)
sapply(log_levels, function(level) {
logger$attach_log_level(level)
})

logger$default("dyn.log loaded '{config_name}' configuration successfully.")

active$config <- config_name
Expand Down Expand Up @@ -127,6 +132,62 @@ wipe_logger <- function() {
}
}

#' @title Apply Active Logger Settings
#'
#' @description
#' Parses and loads the settings specified
#' in the logger configuration and ensures
#' they are active in the environment.
#'
#' @param settings defined in the configuration
#'
#' @family Configuration
apply_active_settings = function(settings) {

threshold_level <- log_levels(settings$threshold)

active$threshold <- list()
active$threshold$name <- level_name(threshold_level)
active$threshold$severity <- level_severity(threshold_level)

active$callstack <- list()
active$callstack$max <- settings$callstack$max
active$callstack$start <- settings$callstack$start
active$callstack$stop <- settings$callstack$stop
}

#' @title Active Logger Settings
#'
#' @description
#' Gets the active global settings
#' for the logger.
#'
#' @family Configuration
#' @export
get_active_settings = function() {
as.list(active)
}

#' @title Attach Log Levels
#'
#' @description
#' Parses and loads the levels specified in the
#' logging configuration and registers them with the
#' dispatcher via the \code{log_levels} active
#' binding.
#'
#' @param definitions defined in the configuration
#' @family Configuration
create_log_levels = function(definitions) {
sapply(definitions, function(level) {
new_log_level(name = level$name,
description = level$description,
severity = as.integer(level$severity),
log_style = level$log_style,
msg_style = level$msg_style)
})
}

#' @title Load Log Layouts
#'
#' @description
Expand All @@ -142,7 +203,7 @@ wipe_logger <- function() {
#' @returns None.
load_log_layouts <- function(layouts) {

invisible(sapply(layouts, function(layout) {
sapply(layouts, function(layout) {
if (identical(class(layout$format), "character")) {

parsed <- stringr::str_split(layout$formats,
Expand All @@ -162,7 +223,9 @@ load_log_layouts <- function(layouts) {
new_line = layout$new_line,
association = layout$association
)
}))
})

invisible()
}

#' @title Display Log Levels
Expand All @@ -177,6 +240,7 @@ load_log_layouts <- function(layouts) {
#'
#' @export
display_log_levels <- function() {

sapply(log_levels(), function(level) {
info <- level_info(level)
logger <- LogDispatch$new()
Expand Down
Loading

0 comments on commit 3aa0841

Please sign in to comment.