Skip to content

Avoid creating a closure for each log message #25922

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 16, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 21 additions & 32 deletions base/logging.jl
Original file line number Diff line number Diff line change
Expand Up @@ -307,50 +307,39 @@ function logmsg_code(_module, file, line, level, message, exs...)
# Second chance at an early bail-out, based on arbitrary
# logger-specific logic.
if shouldlog(logger, level, _module, group, id)
# Bind log record generation into a closure, allowing us to
# defer creation of the records until after filtering.
create_msg = function cm(logger, level, _module, group, id, file, line)
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
file = $file
line = $line
dispatch_message(logger, level, _module, group, id, file, line, create_msg)
end
end
end
nothing
end
end

# Call the log message creation function, and dispatch the result to `logger`.
# TODO: Consider some @nospecialize annotations here
# TODO: The `logger` is loaded from global state and inherently non-inferrable,
# so it might be nice to sever all back edges from `dispatch_message` to
# functions which call it. This function should always return `nothing`.
@noinline function dispatch_message(logger, level, _module, group, id,
filepath, line, create_msg)
# Report an error in log message creation (or in the logger itself).
@noinline function logging_error(logger, level, _module, group, id,
filepath, line, err)
try
create_msg(logger, level, _module, group, id, filepath, line)
catch err
if !catch_exceptions(logger)
rethrow(err)
end
# Try really hard to get the message to the logger, with
# progressively less information.
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()))
catch err2
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 err2
try
# Give up and write to STDERR, in three independent calls to
# increase the odds of it getting through.
print(STDERR, "Exception handling log message: ")
println(STDERR, err)
println(STDERR, " module=$_module file=$filepath line=$line")
println(STDERR, " Second exception: ", err2)
catch
end
# Give up and write to STDERR, in three independent calls to
# increase the odds of it getting through.
print(STDERR, "Exception handling log message: ")
println(STDERR, err)
println(STDERR, " module=$_module file=$filepath line=$line")
println(STDERR, " Second exception: ", err2)
catch
end
end
nothing
Expand Down