105105NULL
106106
107107
108-
108+ # Logger ------------------------------------------------------------------
109109
110110# ' @export
111111Logger <- R6 :: R6Class(
@@ -148,7 +148,8 @@ Logger <- R6::R6Class(
148148 threshold = NULL ,
149149 filters = list (),
150150 exception_handler = default_exception_handler ,
151- propagate = TRUE
151+ propagate = TRUE ,
152+ replace_empty = " <NULL>"
152153 ){
153154 # fields
154155 # threshold must be set *after* the logging functions have been initalized
@@ -167,6 +168,7 @@ Logger <- R6::R6Class(
167168 self $ set_propagate(propagate )
168169 self $ set_filters(filters )
169170 self $ set_exception_handler(exception_handler )
171+ self $ set_replace_empty(replace_empty )
170172
171173 invisible (self )
172174 },
@@ -241,7 +243,9 @@ Logger <- R6::R6Class(
241243 dots <- list (... )
242244
243245 if (is.null(names(dots ))){
244- msg <- sprintf(msg , ... )
246+ dots <- replace_empty(dots , get(" replace_empty" , self ))
247+
248+ msg <- do.call(sprintf , args = c(list (msg ), dots ))
245249 vals <- list (
246250 logger = self ,
247251 level = level ,
@@ -252,8 +256,11 @@ Logger <- R6::R6Class(
252256 )
253257 } else {
254258 not_named <- vapply(names(dots ), is_blank , TRUE , USE.NAMES = FALSE )
259+ unnamed_dots <- dots [not_named ]
260+ unnamed_dots <- replace_empty(unnamed_dots , get(" replace_empty" , self ))
261+
255262 if (any(not_named )){
256- msg <- do.call(sprintf , c(list (msg ), dots [ not_named ] ))
263+ msg <- do.call(sprintf , c(list (msg ), unnamed_dots ))
257264 }
258265
259266 vals <- c(
@@ -559,6 +566,8 @@ Logger <- R6::R6Class(
559566 },
560567
561568
569+ # .. setters --------------------------------------------------------------
570+
562571 # ' @description Set the exception handler of a logger
563572 # '
564573 # ' @param fun a `function` with the single argument `e` (an error [condition])
@@ -611,6 +620,17 @@ Logger <- R6::R6Class(
611620 invisible (self )
612621 },
613622
623+ # ' @description Set the replacement for empty values (`NULL` or empty
624+ # ' vectors)
625+ # '
626+ # ' @param x should be a `character` vector, but other types of values are
627+ # ' supported. use wisely.
628+ set_replace_empty = function (x ){
629+ private [[" .replace_empty" ]] <- x
630+
631+ invisible (self )
632+ },
633+
614634
615635 # ' @description Spawn a child Logger.
616636 # ' This is very similar to using [get_logger()], but
@@ -625,7 +645,7 @@ Logger <- R6::R6Class(
625645 ),
626646
627647
628- # active bindings ---------------------------------------------------------
648+ # .. active bindings ---------------------------------------------------------
629649 active = list (
630650
631651 # ' @field name A `character` scalar. The unique name of each logger,
@@ -716,6 +736,9 @@ Logger <- R6::R6Class(
716736 }
717737 },
718738
739+ replace_empty = function () {
740+ get(" .replace_empty" , envir = private )
741+ },
719742
720743 # ' @field exception_handler a `function`. See `$set_exception_handler` and
721744 # ' `$handle_exception`
@@ -725,7 +748,7 @@ Logger <- R6::R6Class(
725748 ),
726749
727750
728- # private -----------------------------------------------------------------
751+ # .. private -----------------------------------------------------------------
729752 private = list (
730753 set_name = function (x ){
731754 assert(is_scalar_character(x ))
@@ -747,13 +770,13 @@ Logger <- R6::R6Class(
747770 invisible ()
748771 },
749772
750- # +- fields ---------------------------------------------------------------
751773 .propagate = NULL ,
752774 .exception_handler = NULL ,
753775 .name = NULL ,
754776 .appenders = NULL ,
755777 .threshold = NULL ,
756- .last_event = NULL
778+ .last_event = NULL ,
779+ .replace_empty = NULL
757780 )
758781)
759782
@@ -784,6 +807,40 @@ LoggerGlue <- R6::R6Class(
784807
785808 public = list (
786809
810+ initialize = function (
811+ name = " (unnamed logger)" ,
812+ appenders = list (),
813+ threshold = NULL ,
814+ filters = list (),
815+ exception_handler = default_exception_handler ,
816+ propagate = TRUE ,
817+ replace_empty = " <NULL>" ,
818+ transformer = NULL
819+ ){
820+ # fields
821+ # threshold must be set *after* the logging functions have been initalized
822+ if (identical(name , " (unnamed logger)" )){
823+ warning(
824+ " When creating a new Logger, you should assign it a unique `name`. " ,
825+ " Please see ?Logger for more infos." , call. = FALSE
826+ )
827+ }
828+
829+ private $ set_name(name )
830+ private $ .last_event <- LogEvent $ new(self )
831+
832+ self $ set_threshold(threshold )
833+ self $ set_appenders(appenders )
834+ self $ set_propagate(propagate )
835+ self $ set_filters(filters )
836+ self $ set_exception_handler(exception_handler )
837+ self $ set_replace_empty(replace_empty )
838+ self $ set_transformer(transformer )
839+
840+ invisible (self )
841+ },
842+
843+ # .. methods --------------------------------------------------------------
787844 fatal = function (... , caller = get_caller(- 8L ), .envir = parent.frame()){
788845 if (isTRUE(get(" threshold" , envir = self ) < 100L ))
789846 return (invisible ())
@@ -918,8 +975,18 @@ LoggerGlue <- R6::R6Class(
918975 }
919976 })
920977
978+ dots_msg <- replace_empty(dots_msg , get(" replace_empty" , self ))
921979 rawMsg <- dots [[1 ]]
922- msg <- do.call(glue :: glue , args = c(dots_msg , list (.envir = .envir )))
980+
981+ glue_args <- list (.envir = .envir )
982+
983+ transformer <- get(" transformer" , self )
984+
985+ if (! is.null(transformer )){
986+ glue_args [[" .transformer" ]] <- transformer
987+ }
988+
989+ msg <- do.call(glue :: glue , args = c(dots_msg , glue_args ))
923990
924991 # Check if LogEvent should be created
925992 if (
@@ -992,7 +1059,31 @@ LoggerGlue <- R6::R6Class(
9921059
9931060 spawn = function (name ){
9941061 get_logger_glue(c(private [[" .name" ]], name ))
1062+ },
1063+
1064+ # .. setters -----------------------------------------------------------------
1065+
1066+ # ' @description Set the transformer for glue string interpolation
1067+ # '
1068+ # ' @param x single [function] taking two arguments. See [glue::glue()].
1069+ set_transformer = function (x ){
1070+ private [[" .transformer" ]] <- x
1071+
1072+ invisible (self )
1073+ }
1074+ ),
1075+
1076+ # .. active bindings ---------------------------------------------------
1077+ active = list (
1078+ transformer = function () {
1079+ get(" .transformer" , envir = private )
9951080 }
1081+ ),
1082+
1083+
1084+ # . private ------------------------------------
1085+ private = list (
1086+ .transformer = NULL
9961087 )
9971088)
9981089
0 commit comments