From 91671eea62a81fce23e22c08956bd953bb66ccc8 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Thu, 16 Nov 2023 13:47:32 -0500 Subject: [PATCH 1/3] make custom log macros work --- base/logging.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/base/logging.jl b/base/logging.jl index 7150299efa647..df9ef48d01018 100644 --- a/base/logging.jl +++ b/base/logging.jl @@ -370,23 +370,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 Base.CoreLogging.LogLevel ? level : convert(Base.CoreLogging.LogLevel, level)::Base.CoreLogging.LogLevel)) + if std_level >= Base.CoreLogging._min_enabled_level[] group = $(log_data._group) _module = $(log_data._module) - logger = current_logger_for_env(std_level, group, _module) + logger = Base.CoreLogging.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(Base.CoreLogging.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(Base.CoreLogging.handle_message, logger, level, msg, _module, group, id, file, line; kwargs...) end From 6cf75fdacba0127577b37af3a8c16896e0ce535f Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Sun, 19 Nov 2023 21:29:02 -0500 Subject: [PATCH 2/3] add test --- stdlib/Logging/test/runtests.jl | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) 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 From 3a798c4560e166abcfd4c692c70caab79f808207 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Fri, 1 Dec 2023 08:19:26 -0500 Subject: [PATCH 3/3] interpolate symbols instead --- base/logging.jl | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/base/logging.jl b/base/logging.jl index df9ef48d01018..f6a34aee2f516 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 Base.CoreLogging.LogLevel ? level : convert(Base.CoreLogging.LogLevel, level)::Base.CoreLogging.LogLevel)) - if std_level >= Base.CoreLogging._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 = Base.CoreLogging.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(Base.CoreLogging.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(Base.CoreLogging.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 @@ -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()) #-------------------------------------------------------------------------------