Skip to content

Commit

Permalink
Logging: enable configuration via ENV
Browse files Browse the repository at this point in the history
This restores the functionality we had previously to set JULIA_DEBUG_LOADING=1 to activate logging;
now the equivalent would be to set JULIA_DEBUG=loading. But with the new infrastructure, this is also
generalized to allow filtering on any key (module, root-module, or filename), or "all".
This sits between the global disable (which still provides a fast-path to skip everything),
and the default min-level for a logger (which will be overridden by the environment variable).

This also tries to move a bit more work into non-inlined helper functions,
rather than inlining that code directly, to slightly reduce the size of
the emitted code.

As a possible future improvement, we could allow specifying specific
levels (such as `loading=MaxLevel` or `all=Debug`), to provide even more
fine-grained control.

fix JuliaLang#25549
  • Loading branch information
vtjnash committed Apr 6, 2018
1 parent b89e012 commit 9a0864e
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 13 deletions.
72 changes: 59 additions & 13 deletions base/logging.jl
Original file line number Diff line number Diff line change
Expand Up @@ -298,24 +298,20 @@ function logmsg_code(_module, file, line, level, message, exs...)
level = $level
std_level = convert(LogLevel, level)
if std_level >= getindex(_min_enabled_level)
logstate = current_logstate()
if std_level >= logstate.min_enabled_level
logger = logstate.logger
_module = $_module
group = $group
_module = $_module
logger = current_logger_for_env(std_level, group, _module)
if !(logger === nothing)
id = $id
group = $group
# Second chance at an early bail-out, based on arbitrary
# logger-specific logic.
# Second chance at an early bail-out (before computing the message),
# based on arbitrary logger-specific logic.
if shouldlog(logger, level, _module, group, id)
file = $file
line = $line
try
msg = $(esc(message))
handle_message(logger, level, msg, _module, group, id, file, line; $(kwargs...))
catch err
if !catch_exceptions(logger)
rethrow(err)
end
logging_error(logger, level, _module, group, id, file, line, err)
end
end
Expand All @@ -327,7 +323,10 @@ end

# Report an error in log message creation (or in the logger itself).
@noinline function logging_error(logger, level, _module, group, id,
filepath, line, err)
filepath, line, @nospecialize(err))
if !catch_exceptions(logger)
rethrow(err)
end
try
msg = "Exception while generating log record in module $_module at $filepath:$line"
handle_message(logger, Error, msg, _module, :logevent_error, id, filepath, line; exception=(err,catch_backtrace()))
Expand Down Expand Up @@ -369,7 +368,16 @@ LogState(logger) = LogState(LogLevel(min_enabled_level(logger)), logger)

function current_logstate()
logstate = current_task().logstate
(logstate != nothing ? logstate : _global_logstate)::LogState
return (logstate !== nothing ? logstate : _global_logstate)::LogState
end

# helper function to get the current logger, if enabled for the specified message type
@noinline function current_logger_for_env(std_level::LogLevel, group, _module)
logstate = current_logstate()
if std_level >= logstate.min_enabled_level || env_override_minlevel(group, _module)
return logstate.logger
end
return nothing
end

function with_logstate(f::Function, logstate)
Expand Down Expand Up @@ -398,6 +406,44 @@ function disable_logging(level::LogLevel)
_min_enabled_level[] = level + 1
end

let _debug_groups = Symbol[],
_debug_str::String = ""
global function env_override_minlevel(group, _module)
debug = get(ENV, "JULIA_DEBUG", "")
if !(debug === _debug_str)
_debug_str = debug
empty!(_debug_groups)
for g in split(debug, ',')
isempty(g) && continue
if g == "all"
empty!(_debug_groups)
push!(_debug_groups, :all)
break
end
push!(_debug_groups, Symbol(g))
end
end
if isempty(_debug_groups)
return false
end
if _debug_groups[1] == :all
return true
end
if isa(group, Symbol) && group in _debug_groups
return true
end
if isa(_module, Module)
if nameof(_module) in _debug_groups
return true
end
if nameof(Base.moduleroot(_module)) in _debug_groups
return true
end
end
return false
end
end


"""
global_logger()
Expand Down Expand Up @@ -483,7 +529,7 @@ function handle_message(logger::SimpleLogger, level, message, _module, group, id
for i in 2:length(msglines)
println(iob, "", msglines[i])
end
for (key,val) in pairs(kwargs)
for (key, val) in kwargs
println(iob, "", key, " = ", val)
end
println(iob, "└ @ ", _module, " ", filepath, ":", line)
Expand Down
27 changes: 27 additions & 0 deletions test/logging.jl
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,33 @@ end
# Reset to default
disable_logging(BelowMinLevel)
end

@testset "Log level filtering - ENV" begin
logger = TestLogger()
with_logger(logger) do
for (e, r) in (("", false),
(",,,,", false),
("al", false),
("all", true),
("a,b,all,c", true),
("a,b,,c", false),
("Mainb", false),
("aMain", false),
("Main", true),
("a,b,Main,c", true),
("Base", true),
("a,b,Base,c", true),
("Filesystem", true),
("a,b,Filesystem,c", true),
("a,b,Base.Filesystem,c", false))
ENV["JULIA_DEBUG"] = e
@test CoreLogging.env_override_minlevel(:Main, Base.Filesystem) === r
@test CoreLogging.current_logger_for_env(BelowMinLevel, :Main, Base.Filesystem) === (r ? logger : nothing)
@test CoreLogging.current_logger_for_env(Info, :Main, Base.Filesystem) === logger
end
end
end
ENV["JULIA_DEBUG"] = ""
end

#-------------------------------------------------------------------------------
Expand Down

0 comments on commit 9a0864e

Please sign in to comment.