|
| 1 | +function restore_callsite_source_position!(expr, src) |
| 2 | + @assert expr.head == :escape |
| 3 | + @assert expr.args[1].head == :macrocall |
| 4 | + @assert expr.args[1].args[2] isa LineNumberNode |
| 5 | + # used to fix the logging source file + line |
| 6 | + # since we're lowering our verbose logging macros to the |
| 7 | + # Logging.jl macros; otherwise, they would always report this (verbosity.jl) |
| 8 | + # file as the logging callsite |
| 9 | + expr.args[1].args[2] = src |
| 10 | + return expr |
| 11 | +end |
| 12 | + |
| 13 | +vlogmacrodocs = """ |
| 14 | + @debugv N msg args... |
| 15 | + @infov N msg args... |
| 16 | + @warnv N msg args... |
| 17 | + @errorv N msg args... |
| 18 | +
|
| 19 | +"Verbose" logging macros. Drop in replacements of standard logging macros, but an |
| 20 | +additional verbosity level `N` is passed to indicate differing verbosity levels |
| 21 | +for a given log level. The verbosity argument is subtracted from the base log level when passed down |
| 22 | +to the core logging logic, so `@debugv 1 msg` will essentially call `@logmsg Debug-1 msg`. |
| 23 | +
|
| 24 | +An `LoggingExtras.LevelOverrideLogger`can then be used to filter on the `level` argument. |
| 25 | +For convenience, the |
| 26 | +[`LoggintExtras.with(f; level, verbosity)`](@ref) function is provided to temporarily |
| 27 | +wrap the current logger with a log level and verbosity subtracted to filter while `f` is executed. |
| 28 | +""" |
| 29 | + |
| 30 | +"$vlogmacrodocs" |
| 31 | +macro debugv(verbosity::Int, msg, exs...) |
| 32 | + return restore_callsite_source_position!( |
| 33 | + esc(:($Base.@logmsg (Logging.Debug - $verbosity) $msg $(exs...))), |
| 34 | + __source__, |
| 35 | + ) |
| 36 | +end |
| 37 | + |
| 38 | +"$vlogmacrodocs" |
| 39 | +macro infov(verbosity::Int, msg, exs...) |
| 40 | + return restore_callsite_source_position!( |
| 41 | + esc(:($Base.@logmsg (Logging.Info - $verbosity) $msg $(exs...))), |
| 42 | + __source__, |
| 43 | + ) |
| 44 | +end |
| 45 | + |
| 46 | +"$vlogmacrodocs" |
| 47 | +macro warnv(verbosity::Int, msg, exs...) |
| 48 | + return restore_callsite_source_position!( |
| 49 | + esc(:($Base.@logmsg (Logging.Warn - $verbosity) $msg $(exs...))), |
| 50 | + __source__, |
| 51 | + ) |
| 52 | +end |
| 53 | + |
| 54 | +"$vlogmacrodocs" |
| 55 | +macro errorv(verbosity::Int, msg, exs...) |
| 56 | + return restore_callsite_source_position!( |
| 57 | + esc(:($Base.@logmsg (Logging.Error - $verbosity) $msg $(exs...))), |
| 58 | + __source__, |
| 59 | + ) |
| 60 | +end |
| 61 | + |
| 62 | +"$vlogmacrodocs" |
| 63 | +macro logmsgv(verbosity::Int, level, msg, exs...) |
| 64 | + return restore_callsite_source_position!( |
| 65 | + esc(:($Base.@logmsg ($level - $verbosity) $msg $(exs...))), |
| 66 | + __source__, |
| 67 | + ) |
| 68 | +end |
| 69 | + |
| 70 | +""" |
| 71 | + LoggingExtras.withlevel(f, level; verbosity::Integer=0) |
| 72 | +
|
| 73 | +Convenience function like `Logging.with_logger` to temporarily wrap |
| 74 | +the current logger with a level filter while `f` is executed. |
| 75 | +That is, the current logger will still be used for actual logging, but |
| 76 | +log messages will first be checked that they meet the `level` |
| 77 | +log level before being passed on to be logged. |
| 78 | +""" |
| 79 | +function withlevel(f, level::Union{Int, LogLevel}=Info; verbosity::Integer=0) |
| 80 | + lvl = Base.CoreLogging._min_enabled_level[] |
| 81 | + try |
| 82 | + # by default, this global filter is Debug, but for debug logging |
| 83 | + # we want to enable sub-Debug levels |
| 84 | + Base.CoreLogging._min_enabled_level[] = BelowMinLevel |
| 85 | + with_logger(LevelOverrideLogger(level - verbosity, current_logger())) do |
| 86 | + f() |
| 87 | + end |
| 88 | + finally |
| 89 | + Base.CoreLogging._min_enabled_level[] = lvl |
| 90 | + end |
| 91 | +end |
0 commit comments