Types and composition in logging

I am very excited about the new logging interface, as I think it would allow numerical algorithms to emit debugging information in a way that does not interrupt the process, but should allow the user to examine parts of a calculation with the exact same input.

Eg a concrete use case, consider a log-likelihood that should always evaluate to -Inf or a finite real number. If that’s not the case (eg NaN), the logger could emit the parameters. I have some questions on practice though:

  1. Is it OK to pass composite types that are defined in a specific module to the logger? This would allow eg a custom show method that would just print a small summary, instead of dumping 50 lines of numbers, yet also contain detailed information for inspection. My concern is that this would be opaque to other packages.

  2. If the package defines a specific logger to filter its own debug messages, what’s the best way to compose such loggers, so that multiple packages can cooperate smoothly?

Pointers to examples, if any, would also be appreciated.

That’s a bit tricky with the current design, unfortunately. You’ll get the best results by caching the previously used logger in your custom logger (see e.g. here), and then do something like

function loglikelihood(x)
  Logging.with_logger(MyCustomLogger(Base.CoreLogging.current_logger()) do
    compute_log_likelihood(x)
  end
end

Also make sure to properly define shouldlog and min_enabled_level.

This depends on how the logger implements printing of log messages, but it shouldn’t be a problem in general.

Why not use a custom log level instead? They are going to work on pretty much any logger, regardless of origin. Some packages (shameless plug: e.g. my IOLogging.jl) allow for log message filtering based on the log level.