From c61b27f02d03e8d0c9eef13f337c966e7771758e Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Sat, 2 Dec 2023 09:36:18 -0500 Subject: [PATCH] make custom log macros work (#52359) (cherry picked from commit 641f717a15cf89964db446c1bb32d0d672763786) --- base/logging.jl | 34 ++++++++++++++++----------------- stdlib/Logging/test/runtests.jl | 17 +++++++++++++++++ 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/base/logging.jl b/base/logging.jl index c42af08d8f4ae..96c133a239cc0 100644 --- a/base/logging.jl +++ b/base/logging.jl @@ -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") @@ -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 @@ -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 @@ -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 @@ -497,15 +506,6 @@ function current_logstate() return (logstate !== nothing ? logstate : _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 = 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) @nospecialize t = current_task() diff --git a/stdlib/Logging/test/runtests.jl b/stdlib/Logging/test/runtests.jl index b6b4813964536..3a793c4e0bc33 100644 --- a/stdlib/Logging/test/runtests.jl +++ b/stdlib/Logging/test/runtests.jl @@ -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 @@ -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