Skip to content

Commit

Permalink
make custom log macros work (#52359)
Browse files Browse the repository at this point in the history
  • Loading branch information
IanButterworth committed Dec 2, 2023
1 parent aef528d commit 641f717
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 17 deletions.
34 changes: 17 additions & 17 deletions base/logging.jl
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ Alias for [`LogLevel(2000)`](@ref LogLevel).
const Error = LogLevel( 2000)
const AboveMaxLevel = LogLevel( 1000001)

# Global log limiting mechanism for super fast but inflexible global log limiting.
const _min_enabled_level = Ref{LogLevel}(Debug)

function show(io::IO, level::LogLevel)
if level == BelowMinLevel print(io, "BelowMinLevel")
elseif level == Debug print(io, "Debug")
Expand Down Expand Up @@ -319,6 +322,15 @@ function issimplekw(@nospecialize val)
return false
end

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

# Generate code for logging macros
function logmsg_code(_module, file, line, level, message, exs...)
@nospecialize
Expand Down Expand Up @@ -370,23 +382,23 @@ function logmsg_code(_module, file, line, level, message, exs...)
let
level = $level
# simplify std_level code emitted, if we know it is one of our global constants
std_level = $(level isa Symbol ? :level : :(level isa LogLevel ? level : convert(LogLevel, level)::LogLevel))
if std_level >= _min_enabled_level[]
std_level = $(level isa Symbol ? :level : :(level isa $LogLevel ? level : convert($LogLevel, level)::$LogLevel))
if std_level >= $(_min_enabled_level)[]
group = $(log_data._group)
_module = $(log_data._module)
logger = current_logger_for_env(std_level, group, _module)
logger = $(current_logger_for_env)(std_level, group, _module)
if !(logger === nothing)
id = $(log_data._id)
# Second chance at an early bail-out (before computing the message),
# based on arbitrary logger-specific logic.
if invokelatest(shouldlog, logger, level, _module, group, id)
if invokelatest($shouldlog, logger, level, _module, group, id)
file = $(log_data._file)
if file isa String
file = Base.fixup_stdlib_path(file)
end
line = $(log_data._line)
local msg, kwargs
$(logrecord) && invokelatest(handle_message,
$(logrecord) && invokelatest($handle_message,
logger, level, msg, _module, group, id, file, line;
kwargs...)
end
Expand Down Expand Up @@ -481,9 +493,6 @@ function logmsg_shim(level, message, _module, group, id, file, line, kwargs)
nothing
end

# Global log limiting mechanism for super fast but inflexible global log limiting.
const _min_enabled_level = Ref{LogLevel}(Debug)

# LogState - a cache of data extracted from the logger, plus the logger itself.
struct LogState
min_enabled_level::LogLevel
Expand All @@ -499,15 +508,6 @@ function current_logstate()
return something(maybe, _global_logstate)::LogState
end

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

with_logstate(f::Function, logstate) = @with(CURRENT_LOGSTATE => logstate, f())

#-------------------------------------------------------------------------------
Expand Down
17 changes: 17 additions & 0 deletions stdlib/Logging/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import Logging: min_enabled_level, shouldlog, handle_message

@noinline func1() = backtrace()

# see "custom log macro" testset
CustomLog = LogLevel(-500)
macro customlog(exs...) Base.CoreLogging.logmsg_code((Base.CoreLogging.@_sourceinfo)..., esc(CustomLog), exs...) end

@testset "Logging" begin

@testset "Core" begin
Expand Down Expand Up @@ -275,4 +279,17 @@ end
@test m.run()
end

@testset "custom log macro" begin
@test_logs (CustomLog, "a") min_level=CustomLog @customlog "a"

buf = IOBuffer()
io = IOContext(buf, :displaysize=>(30,80), :color=>false)
logger = ConsoleLogger(io, CustomLog)

with_logger(logger) do
@customlog "a"
end
@test occursin("LogLevel(-500): a", String(take!(buf)))
end

end

0 comments on commit 641f717

Please sign in to comment.