daroczig / logger

A lightweight, modern and flexible, log4j and futile.logger inspired logging utility for R
https://daroczig.github.io/logger
249 stars 38 forks source link

Functions of `log_level()` fail in Shiny context (objects are not found by `glue`) #115

Closed GitHunter0 closed 4 months ago

GitHunter0 commented 1 year ago

logger is an amazing package, the only issue I'm having is that I can't create custom functions using it in Shiny context.

Please, consider this MWE, while log_level() works, custom_log_level() fails:

library(shiny)
library(logger)

custom_log_level <- function(level, ...){
  txt <- toString( list(...) )
  logger::log_level(txt, level=level)
}

ui <- fluidPage(

  shiny::numericInput(
    inputId = "in_numeric",
    label = "Choose number",
    value = 1
  ),

  shiny::actionButton("msg_trigger", "See message")

)

server <- function(input, output, session) {

  observeEvent(input$msg_trigger, {

    log_level("This works: {input$in_numeric}", level="INFO")

    custom_log_level("This fails: {input$in_numeric}", level="INFO") |> 
      tryCatch(error = function(e) print(e))

    .m <- "This works"
    log_level("{.m}", level="INFO")    

    .m <- "But this also fails"
    custom_log_level("{.m}", level="INFO") |> 
      tryCatch(error = function(e) print(e))

  })

}

shinyApp(ui, server)

The errors messages were:

<simpleError in value[[3L]](cond): `glue` failed in `formatter_glue` on:

  chr "This fails: {input$in_numeric}" 

Raw error message:

 object 'input' not found 

Please consider using another `log_formatter` or `skip_formatter` on strings with curly braces.>
<simpleError in value[[3L]](cond): `glue` failed in `formatter_glue` on:

  chr "{.m}" 

Raw error message:

 object '.m' not found 

Please consider using another `log_formatter` or `skip_formatter` on strings with curly braces.>

Thank you

R version 4.2.1 (2022-06-23 ucrt)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19044)

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.utf8 
[2] LC_CTYPE=English_United States.utf8   
[3] LC_MONETARY=English_United States.utf8
[4] LC_NUMERIC=C                          
[5] LC_TIME=English_United States.utf8    

attached base packages:
[1] stats     graphics  grDevices
[4] utils     datasets  methods  
[7] base     

other attached packages:
[1] logger_0.2.2      
[2] shinyWidgets_0.7.4
[3] shiny_1.7.3   
daroczig commented 4 months ago

This is a scoping issue -- if you are writing your own logger wrapper, you would need to pass down properly the calling frame, call etc, e.g.:

custom_log_level <- function(level, ...){
    txt <- toString(list(...))
    log_level(txt, level=level, .logcall = sys.call(), .topcall = sys.call(-1), .topenv = parent.frame())
}