Skip to content

Commit 960f974

Browse files
c42fKristofferC
authored andcommitted
Reinstate statically computed log event ids (#29878)
* fix bug and add tests * Reinstate statically computed log record ids Log ids are meant to identify the location of the message in the source code and must be computed at compile time. fix #28786, fix #28400; closes #29355. * Clarify documentation regarding log record `id` (cherry picked from commit 51683c4)
1 parent ce1277f commit 960f974

File tree

4 files changed

+49
-17
lines changed

4 files changed

+49
-17
lines changed

base/logging.jl

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -222,17 +222,17 @@ macro error(exs...) logmsg_code((@_sourceinfo)..., :Error, exs...) end
222222
@eval @doc $_logmsg_docs :(@error)
223223

224224
_log_record_ids = Set{Symbol}()
225-
# Generate a unique, stable, short, human readable identifier for a logging
226-
# statement. The idea here is to have a key against which log records can be
227-
# filtered and otherwise manipulated. The key should uniquely identify the
228-
# source location in the originating module, but should be stable across
229-
# versions of the originating module, provided the log generating statement
230-
# itself doesn't change.
231-
function log_record_id(_module, level, message_ex)
225+
# Generate a unique, stable, short, somewhat human readable identifier for a
226+
# logging *statement*. The idea here is to have a key against which log events
227+
# can be filtered and otherwise manipulated. The key should uniquely identify
228+
# the source location in the originating module, but ideally should be stable
229+
# across versions of the originating module, provided the log generating
230+
# statement itself doesn't change.
231+
function log_record_id(_module, level, message, log_kws)
232232
modname = _module === nothing ? "" : join(fullname(_module), "_")
233-
# Use (1<<31) to fit well within an (arbitriraly chosen) eight hex digits,
234-
# as we increment h to resolve any collisions.
235-
h = hash(string(modname, level, message_ex)) % (1<<31)
233+
# Use an arbitriraly chosen eight hex digits here. TODO: Figure out how to
234+
# make the id exactly the same on 32 and 64 bit systems.
235+
h = UInt32(hash(string(modname, level, message, log_kws)) & 0xFFFFFFFF)
236236
while true
237237
id = Symbol(modname, '_', string(h, base = 16, pad = 8))
238238
# _log_record_ids is a registry of log record ids for use during
@@ -249,7 +249,7 @@ end
249249

250250
# Generate code for logging macros
251251
function logmsg_code(_module, file, line, level, message, exs...)
252-
id = nothing
252+
id = Expr(:quote, log_record_id(_module, level, message, exs))
253253
group = nothing
254254
kwargs = Any[]
255255
for ex in exs
@@ -289,8 +289,6 @@ function logmsg_code(_module, file, line, level, message, exs...)
289289
end
290290
end
291291

292-
# Note that it may be necessary to set `id` and `group` manually during bootstrap
293-
id = something(id, :(log_record_id(_module, level, $exs)))
294292
if group == nothing
295293
group = if isdefined(Base, :basename) && isa(file, String)
296294
# precompute if we can

stdlib/Logging/docs/src/index.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,10 @@ The system also generates some standard information for each event:
7777

7878
* The `module` in which the logging macro was expanded.
7979
* The `file` and `line` where the logging macro occurs in the source code.
80-
* A message `id` that is unique for each logging macro invocation. This is
81-
very useful as a key for caching information or actions associated with an
82-
event. For instance, it can be used to limit the number of times a message
83-
is presented to the user.
80+
* A message `id` that is a unique, fixed identifier for the *source code
81+
statement* where the logging macro appears. This identifier is designed to be
82+
fairly stable even if the source code of the file changes, as long as the
83+
logging statement itself remains the same.
8484
* A `group` for the event, which is set to the base name of the file by default,
8585
without extension. This can be used to group messages into categories more
8686
finely than the log level (for example, all deprecation warnings have group

stdlib/Logging/test/runtests.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,26 @@ import Logging: min_enabled_level, shouldlog, handle_message
2121
handle_message(logger, Logging.Info, "msg", Base, :group, :asdf, "somefile", 1, maxlog=2)
2222
@test shouldlog(logger, Logging.Info, Base, :group, :asdf) === false
2323

24+
# Check that maxlog works without an explicit ID (#28786)
25+
buf = IOBuffer()
26+
io = IOContext(buf, :displaysize=>(30,80), :color=>false)
27+
logger = ConsoleLogger(io)
28+
with_logger(logger) do
29+
for i in 1:2
30+
@info "test" maxlog=1
31+
end
32+
end
33+
@test String(take!(buf)) ==
34+
"""
35+
[ Info: test
36+
"""
37+
with_logger(logger) do
38+
for i in 1:2
39+
@info "test" maxlog=0
40+
end
41+
end
42+
@test String(take!(buf)) == ""
43+
2444
@testset "Default metadata formatting" begin
2545
@test Logging.default_metafmt(Logging.Debug, Base, :g, :i, expanduser("~/somefile.jl"), 42) ==
2646
(:blue, "Debug:", "@ Base ~/somefile.jl:42")

test/logging.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,4 +338,18 @@ end
338338
@test_logs (:warn, "a", Base) (@warn "a" _module=Base)
339339
end
340340

341+
# Issue #28786
342+
@testset "ID generation" begin
343+
logs,_ = collect_test_logs() do
344+
for i in 1:2
345+
@info "test"
346+
@info "test"
347+
end
348+
end
349+
@test length(logs) == 4
350+
@test logs[1].id == logs[3].id
351+
@test logs[2].id == logs[4].id
352+
@test logs[1].id != logs[2].id
353+
end
354+
341355
end

0 commit comments

Comments
 (0)