@@ -75,12 +75,20 @@ catch_exceptions(logger) = true
75
75
# Using invoke in combination with @nospecialize eliminates backedges to these methods
76
76
function _invoked_shouldlog (logger, level, _module, group, id)
77
77
@nospecialize
78
- invoke (shouldlog, Tuple{typeof (logger), typeof (level), typeof (_module), typeof (group), typeof (id)}, logger, level, _module, group, id)
78
+ return invoke (
79
+ shouldlog,
80
+ Tuple{typeof (logger), typeof (level), typeof (_module), typeof (group), typeof (id)},
81
+ logger, level, _module, group, id
82
+ )
79
83
end
80
84
81
- _invoked_min_enabled_level (@nospecialize (logger)) = invoke (min_enabled_level, Tuple{typeof (logger)}, logger)
85
+ function _invoked_min_enabled_level (@nospecialize (logger))
86
+ return invoke (min_enabled_level, Tuple{typeof (logger)}, logger)
87
+ end
82
88
83
- _invoked_catch_exceptions (@nospecialize (logger)) = invoke (catch_exceptions, Tuple{typeof (logger)}, logger)
89
+ function _invoked_catch_exceptions (@nospecialize (logger))
90
+ return invoke (catch_exceptions, Tuple{typeof (logger)}, logger)
91
+ end
84
92
85
93
"""
86
94
NullLogger()
@@ -247,7 +255,7 @@ _log_record_ids = Set{Symbol}()
247
255
# statement itself doesn't change.
248
256
function log_record_id (_module, level, message, log_kws)
249
257
modname = _module === nothing ? " " : join (fullname (_module), " _" )
250
- # Use an arbitriraly chosen eight hex digits here. TODO : Figure out how to
258
+ # Use an arbitrarily chosen eight hex digits here. TODO : Figure out how to
251
259
# make the id exactly the same on 32 and 64 bit systems.
252
260
h = UInt32 (hash (string (modname, level, message, log_kws)) & 0xFFFFFFFF )
253
261
while true
@@ -268,85 +276,89 @@ default_group(file) = Symbol(splitext(basename(file))[1])
268
276
269
277
# Generate code for logging macros
270
278
function logmsg_code (_module, file, line, level, message, exs... )
271
- id = Expr (:quote , log_record_id (_module, level, message, exs))
272
- group = nothing
279
+ log_data = process_logmsg_exs (_module, file, line, level, message, exs... )
280
+ quote
281
+ level = $ level
282
+ std_level = convert (LogLevel, level)
283
+ if std_level >= getindex (_min_enabled_level)
284
+ group = $ (log_data. _group)
285
+ _module = $ (log_data. _module)
286
+ logger = current_logger_for_env (std_level, group, _module)
287
+ if ! (logger === nothing )
288
+ id = $ (log_data. _id)
289
+ # Second chance at an early bail-out (before computing the message),
290
+ # based on arbitrary logger-specific logic.
291
+ if _invoked_shouldlog (logger, level, _module, group, id)
292
+ file = $ (log_data. _file)
293
+ line = $ (log_data. _line)
294
+ try
295
+ msg = $ (esc (message))
296
+ handle_message (
297
+ logger, level, msg, _module, group, id, file, line;
298
+ $ (log_data. kwargs... )
299
+ )
300
+ catch err
301
+ logging_error (logger, level, _module, group, id, file, line, err)
302
+ end
303
+ end
304
+ end
305
+ end
306
+ nothing
307
+ end
308
+ end
309
+
310
+ function process_logmsg_exs (_orig_module, _file, _line, level, message, exs... )
311
+ local _group, _id
312
+ _module = _orig_module
273
313
kwargs = Any[]
274
314
for ex in exs
275
315
if ex isa Expr && ex. head === :(= ) && ex. args[1 ] isa Symbol
276
316
k,v = ex. args
277
317
if ! (k isa Symbol)
278
318
throw (ArgumentError (" Expected symbol for key in key value pair `$ex `" ))
279
319
end
280
- k = ex . args[ 1 ]
320
+
281
321
# Recognize several special keyword arguments
282
- if k === :_id
283
- # id may be overridden if you really want several log
284
- # statements to share the same id (eg, several pertaining to
285
- # the same progress step). In those cases it may be wise to
286
- # manually call log_record_id to get a unique id in the same
287
- # format.
288
- id = esc (v)
322
+ if k === :_group
323
+ _group = esc (v)
324
+ elseif k === :_id
325
+ _id = esc (v)
289
326
elseif k === :_module
290
327
_module = esc (v)
291
- elseif k === :_line
292
- line = esc (v)
293
328
elseif k === :_file
294
- file = esc (v)
295
- elseif k === :_group
296
- group = esc (v)
329
+ _file = esc (v)
330
+ elseif k === :_line
331
+ _line = esc (v)
297
332
else
298
333
# Copy across key value pairs for structured log records
299
334
push! (kwargs, Expr (:kw , k, esc (v)))
300
335
end
301
- elseif ex isa Expr && ex. head === :...
302
- # Keyword splatting
336
+ elseif ex isa Expr && ex. head === :... # Keyword splatting
303
337
push! (kwargs, esc (ex))
304
- else
305
- # Positional arguments - will be converted to key value pairs
306
- # automatically.
338
+ else # Positional arguments - will be converted to key value pairs automatically.
307
339
push! (kwargs, Expr (:kw , Symbol (ex), esc (ex)))
308
340
end
309
341
end
310
342
311
- if group === nothing
312
- group = if isdefined (Base, :basename ) && isa (file, String)
313
- # precompute if we can
314
- QuoteNode (default_group (file))
315
- else
316
- # memoized run-time execution
317
- ref = Ref {Symbol} ()
318
- :(isassigned ($ ref) ? $ ref[]
319
- : $ ref[] = default_group (something ($ file, " " )))
320
- end
343
+ if ! @isdefined (_group)
344
+ _group = default_group_code (_file)
345
+ end
346
+ if ! @isdefined (_id)
347
+ _id = Expr (:quote , log_record_id (_orig_module, level, message, exs))
321
348
end
349
+ return (;_module, _group, _id, _file, _line, kwargs)
350
+ end
322
351
323
- quote
324
- level = $ level
325
- std_level = convert (LogLevel, level)
326
- if std_level >= getindex (_min_enabled_level)
327
- group = $ group
328
- _module = $ _module
329
- logger = current_logger_for_env (std_level, group, _module)
330
- if ! (logger === nothing )
331
- id = $ id
332
- # Second chance at an early bail-out (before computing the message),
333
- # based on arbitrary logger-specific logic.
334
- if _invoked_shouldlog (logger, level, _module, group, id)
335
- file = $ file
336
- line = $ line
337
- try
338
- msg = $ (esc (message))
339
- handle_message (logger, level, msg, _module, group, id, file, line; $ (kwargs... ))
340
- catch err
341
- logging_error (logger, level, _module, group, id, file, line, err)
342
- end
343
- end
344
- end
345
- end
346
- nothing
352
+ function default_group_code (file)
353
+ if file isa String && isdefined (Base, :basename )
354
+ QuoteNode (default_group (file)) # precompute if we can
355
+ else
356
+ ref = Ref {Symbol} () # memoized run-time execution
357
+ :(isassigned ($ ref) ? $ ref[] : $ ref[] = default_group (something ($ file, " " )))
347
358
end
348
359
end
349
360
361
+
350
362
# Report an error in log message creation (or in the logger itself).
351
363
@noinline function logging_error (logger, level, _module, group, id,
352
364
filepath, line, @nospecialize (err))
355
367
end
356
368
try
357
369
msg = " Exception while generating log record in module $_module at $filepath :$line "
358
- handle_message (logger, Error, msg, _module, :logevent_error , id, filepath, line; exception= (err,catch_backtrace ()))
370
+ handle_message (
371
+ logger, Error, msg, _module, :logevent_error , id, filepath, line;
372
+ exception= (err,catch_backtrace ())
373
+ )
359
374
catch err2
360
375
try
361
376
# Give up and write to stderr, in three independent calls to
@@ -379,12 +394,10 @@ function logmsg_shim(level, message, _module, group, id, file, line, kwargs)
379
394
_file= String (file), _line= line, real_kws... )
380
395
end
381
396
382
- # Global log limiting mechanism for super fast but inflexible global log
383
- # limiting.
397
+ # Global log limiting mechanism for super fast but inflexible global log limiting.
384
398
const _min_enabled_level = Ref (Debug)
385
399
386
- # LogState - a concretely typed cache of data extracted from the logger, plus
387
- # the logger itself.
400
+ # LogState - a cache of data extracted from the logger, plus the logger itself.
388
401
struct LogState
389
402
min_enabled_level:: LogLevel
390
403
logger:: AbstractLogger
@@ -523,7 +536,9 @@ with_logger(logger) do
523
536
end
524
537
```
525
538
"""
526
- with_logger (@nospecialize (f:: Function ), logger:: AbstractLogger ) = with_logstate (f, LogState (logger))
539
+ function with_logger (@nospecialize (f:: Function ), logger:: AbstractLogger )
540
+ with_logstate (f, LogState (logger))
541
+ end
527
542
528
543
"""
529
544
current_logger()
0 commit comments