How to Change LogLevel with Logging Package?


#1

Hi all,

I’m having issues understanding how to set the logging level with Logging. This is also my first post, so if this isn’t the right place to post, please just redirect me to the appropriate topic area.

I start with a setup of:

julia> io = open("log.txt", "w")
IOStream(<file log.txt>)

julia> logger = SimpleLogger(io)
SimpleLogger(IOStream(<file log.txt>), Info, Dict{Any,Int64}())

I want to be able to toggle between different logging levels like debug, info or warning and run some code with these macros to see the different outputs, but I can’t seem to get it to change from Info.

I then try to set the LogLevel variable/method (it’s unclear what it is) in multiple ways, as the documentation doesn’t seem to have an example of this and I get the following errors:

julia> LogLevel(Debug)
ERROR: UndefVarError: Debug not defined
Stacktrace:
 [1] top-level scope at none:0

or

julia> Logging.LogLevel(Debug)
ERROR: UndefVarError: Debug not defined
Stacktrace:
 [1] top-level scope at none:0

or

julia> Logging.LogLevel("Debug")
ERROR: MethodError: Cannot `convert` an object of type String to an object of type Int32
Closest candidates are:
  convert(::Type{T<:Number}, ::T<:Number) where T<:Number at number.jl:6
  convert(::Type{T<:Number}, ::Number) where T<:Number at number.jl:7
  convert(::Type{T<:Integer}, ::Ptr) where T<:Integer at pointer.jl:23
  ...
Stacktrace:
 [1] LogLevel(::String) at ./logging.jl:100
 [2] top-level scope at none:0

Playing a bit further I get:

julia> LogLevel(1)
LogLevel(1)

julia> LogLevel(0)
Info

Can anyone provide me an example?


#2

First of all, welcome! Yes, this is the right place for such a question. :slight_smile:

Logging in Julia works by having a Logger with certain properties do the actual logging. In case of the SimpleLogger from Base, you have to specify the minimum LogLevel at creation of the logger:

julia> using Logging

julia> logger = SimpleLogger(stdout, Logging.Debug)
SimpleLogger(Base.TTY(RawFD(0x0000000d) open, 0 bytes waiting), Debug, Dict{Any,Int64}())

julia> @info "info level!"
[ Info: info level!

julia> @debug "debug level!"

julia> old_logger = global_logger(logger)    # change the global logger to show debug output!
ConsoleLogger(Base.TTY(RawFD(0x0000000f) open, 0 bytes waiting), Info, Logging.default_metafmt, true, 0, Dict{Any,Int64}())

julia> @debug "debug level!"
┌ Debug: debug level!
└ @ Main REPL[7]:1

The predefined Loggers ConsoleLogger and SimpleLogger log messages with a LogLevel greater than or equal to the one specified during their creation - the default active logger only shows level Info and above:

julia> with_logger(old_logger) do
           @info "Info is here"
           @debug "Debug is not"
       end
[ Info: Info is here

Note also that Logging.Debug is a predefined LogLevel object:

help?> Logging.Debug
  No documentation found.

  Base.CoreLogging.Debug is of type LogLevel.

  Summary
  ≡≡≡≡≡≡≡≡≡

  struct LogLevel <: Any

  Fields
  ≡≡≡≡≡≡≡≡

  level :: Int32

There’s also a few packages providing more complex loggers, for example logging to any kind of IO based on the LogLevel (IOLogging.jl) or e.g. the FilteredLogger allowing better filtering of log messages when creating them (LoggingExtras.jl).


#3

This was a great help. Thank you very much for your time.


#4

No problem! If my post helped solve your problem, please consider marking it as the solution so others know that your question has been answered :slight_smile:


#5

My next questions were likely to be about a tool like IOLogging.jl, so thanks for that info too!