Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Print the name of the logger in the log #41

Closed
Fuco1 opened this issue Dec 6, 2020 · 5 comments
Closed

Print the name of the logger in the log #41

Fuco1 opened this issue Dec 6, 2020 · 5 comments

Comments

@Fuco1
Copy link

Fuco1 commented Dec 6, 2020

I'm quite fond of using "complicated" logger hierarchies for tracing complicated algorithms, where I can enable/disable parts of the code selectively (by rising/lowering the log levels of various sub-loggers).

However sometimes I get lost in where the messages are coming from. It would be nice if I could log the logger name in the output (mostly using the format layout). I'm used to this from log4j and miss it a little.

Since I ship all my logs to elastic it would also enable me to filter only logs related to a specific part of the application in a very simple way (granted, adding some meta-data directly as asked in #40 would maybe serve this purpose better). But as a low-effort solution it would be sufficient.

@s-fleck
Copy link
Owner

s-fleck commented Dec 6, 2020

I'm honestly kinda surprised that I didn't include that in format.LogEvent. Not sure yet how to include it in JSON logging (API-wise), so give me some time to think about it.

Meanwhile, Filters are again an easy workaround to this problem:

library(lgr)
lg <- get_logger("test/logger")
f <- function(event) {
  event[["lgr"]] <- event$logger
  TRUE
} 
lg$add_filter(f)
lg$info("test")

Sadly you can not use the name logger for the custom field.
A nicer solution would be subclassing LayoutJson:

LayoutJson2 <- R6::R6Class(
  inherit = lgr::LayoutJson
  ,
  public = list(
    format_event = function(event) {
      vals <- c(get("values", event), logger = get("logger", event))   # here is where the magic happens
      fmt  <- get("timestamp_fmt", self)

      if (!is.null(fmt)){
        vals[["timestamp"]] <- fmt_timestamp(vals[["timestamp"]], fmt)
      }

      do.call(
        jsonlite::toJSON,
        args = c(list(x = vals), get(".toJSON_args", private))
      )
    }
  )
)

lg <- get_logger("test/logger")
lg$add_appender(AppenderConsole$new(layou = LayoutJson2$new()))

lg$info("test")

Might be that this will be the default behaviour in future versions anyways

@s-fleck
Copy link
Owner

s-fleck commented Dec 6, 2020

Ah! format.LogEvent() alread DOES support what you are requesting, its just missing from the documentation! The token you need is %g:

lg <- lgr::get_logger("test/logger")
basic_config(console_fmt = "%g ~ %L [%t] %m")
lg$info("test")

@Fuco1
Copy link
Author

Fuco1 commented Dec 6, 2020

Oh, nice! I think I was mostly interested in this for the interactive case (i.e. format logger), but the json extra field would be nice as well.

I haven't yet worked with the R6 system so the code is a bit magical to me, but it seems like a good investment to spent one hour to read around. There's more packages around using it.

@s-fleck
Copy link
Owner

s-fleck commented Dec 6, 2020

R6 is pretty cool if you need an object system with mutable objects, so if you have used Java before, R6 classes should be pretty familiar.

the internal code of lgr uses get() instead of $ a lot in places where performance is important. That makes some part of the code a bit confusing/obscure. In the example above get("values", event) is the same as just event$values, but a few ms faster.

@s-fleck
Copy link
Owner

s-fleck commented Jul 22, 2021

Seems that i forgot to close this one

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants