logger-36 2025.23__py3-none-any.whl → 2025.25__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- logger_36/api/{gpu.py → chronos.py} +1 -1
- logger_36/api/memory.py +0 -9
- logger_36/api/storage.py +0 -1
- logger_36/catalog/handler/console.py +1 -1
- logger_36/catalog/handler/console_rich.py +33 -22
- logger_36/catalog/handler/file.py +1 -2
- logger_36/catalog/handler/generic.py +24 -10
- logger_36/catalog/handler/memory.py +31 -6
- logger_36/catalog/logger/chronos.py +10 -2
- logger_36/catalog/logger/memory.py +1 -1
- logger_36/catalog/logger/system.py +6 -5
- logger_36/config/message.py +1 -4
- logger_36/{api/system.py → config/rule.py} +2 -1
- logger_36/constant/chronos.py +50 -0
- logger_36/constant/error.py +2 -0
- logger_36/constant/html.py +2 -0
- logger_36/constant/message.py +7 -7
- logger_36/constant/path.py +8 -7
- logger_36/constant/record.py +2 -0
- logger_36/constant/rule.py +2 -2
- logger_36/{api/time.py → extension/file.py} +18 -2
- logger_36/{task → extension}/inspection.py +15 -29
- logger_36/extension/line.py +1 -1
- logger_36/task/format/memory.py +1 -1
- logger_36/task/format/message.py +7 -5
- logger_36/task/measure/chronos.py +21 -13
- logger_36/task/storage.py +32 -48
- logger_36/type/handler.py +26 -32
- logger_36/type/issue.py +7 -4
- logger_36/type/logger.py +164 -88
- logger_36/version.py +1 -1
- {logger_36-2025.23.dist-info → logger_36-2025.25.dist-info}/METADATA +30 -44
- logger_36-2025.25.dist-info/RECORD +53 -0
- logger_36/extension/html_.py +0 -93
- logger_36-2025.23.dist-info/RECORD +0 -53
- /logger_36/api/{type.py → logger.py} +0 -0
- /logger_36/api/{content.py → message.py} +0 -0
- /logger_36/{constant/generic.py → extension/sentinel.py} +0 -0
- {logger_36-2025.23.dist-info → logger_36-2025.25.dist-info}/WHEEL +0 -0
- {logger_36-2025.23.dist-info → logger_36-2025.25.dist-info}/top_level.txt +0 -0
logger_36/type/logger.py
CHANGED
@@ -7,6 +7,7 @@ SEE COPYRIGHT NOTICE BELOW
|
|
7
7
|
import dataclasses as d
|
8
8
|
import inspect as e
|
9
9
|
import logging as l
|
10
|
+
import multiprocessing as prll
|
10
11
|
import sys as s
|
11
12
|
import textwrap as text
|
12
13
|
import threading as thrd
|
@@ -15,7 +16,8 @@ import types as t
|
|
15
16
|
import typing as h
|
16
17
|
from datetime import date as date_t
|
17
18
|
from datetime import datetime as date_time_t
|
18
|
-
from
|
19
|
+
from logging.handlers import QueueHandler as queue_handler_t
|
20
|
+
from logging.handlers import QueueListener as log_server_t
|
19
21
|
from pathlib import Path as path_t
|
20
22
|
from traceback import TracebackException as traceback_t
|
21
23
|
|
@@ -27,26 +29,35 @@ from logger_36.catalog.config.optional import (
|
|
27
29
|
)
|
28
30
|
from logger_36.catalog.handler.console import console_handler_t
|
29
31
|
from logger_36.catalog.handler.file import file_handler_t
|
32
|
+
from logger_36.catalog.handler.memory import memory_handler_t, records_h
|
30
33
|
from logger_36.config.issue import ISSUE_CONTEXT_END, ISSUE_CONTEXT_SEPARATOR
|
31
34
|
from logger_36.config.message import (
|
32
35
|
DATE_FORMAT,
|
33
|
-
ELAPSED_TIME_SEPARATOR,
|
34
36
|
LONG_ENOUGH,
|
35
37
|
TIME_FORMAT,
|
36
38
|
WHERE_SEPARATOR,
|
37
39
|
)
|
38
|
-
from logger_36.constant.
|
40
|
+
from logger_36.constant.chronos import DATE_ORIGIN, DATE_TIME_ORIGIN
|
39
41
|
from logger_36.constant.issue import ISSUE_LEVEL_SEPARATOR, ORDER, order_h
|
40
42
|
from logger_36.constant.logger import WARNING_LOGGER_NAME, WARNING_TYPE_COMPILED_PATTERN
|
41
43
|
from logger_36.constant.memory import UNKNOWN_MEMORY_USAGE
|
42
|
-
from logger_36.constant.message import LINE_INDENT,
|
43
|
-
from logger_36.constant.path import
|
44
|
-
from logger_36.constant.record import
|
44
|
+
from logger_36.constant.message import LINE_INDENT, expected_op_h
|
45
|
+
from logger_36.constant.path import USER_FOLDER, LAUNCH_ROOT_FILE_relative
|
46
|
+
from logger_36.constant.record import (
|
47
|
+
HAS_ACTUAL_EXPECTED_ATTR,
|
48
|
+
SHOW_W_RULE_ATTR,
|
49
|
+
SHOW_WHEN_ATTR,
|
50
|
+
SHOW_WHERE_ATTR,
|
51
|
+
WHEN_OR_ELAPSED_ATTR,
|
52
|
+
WHERE_ATTR,
|
53
|
+
)
|
54
|
+
from logger_36.extension.file import NewTemporaryFile
|
55
|
+
from logger_36.extension.sentinel import NOT_PASSED
|
45
56
|
from logger_36.task.format.message import MessageWithActualExpected
|
46
|
-
from logger_36.task.measure.chronos import
|
57
|
+
from logger_36.task.measure.chronos import FormattedElapsedTime
|
47
58
|
from logger_36.task.measure.memory import CurrentUsage as CurrentMemoryUsage
|
48
|
-
from logger_36.type.handler import any_handler_t as base_handler_t
|
49
59
|
from logger_36.type.handler import extension_t as handler_extension_t
|
60
|
+
from logger_36.type.handler import handler_h as base_handler_h
|
50
61
|
from logger_36.type.issue import NewIssue, issue_t
|
51
62
|
|
52
63
|
if RICH_IS_AVAILABLE:
|
@@ -62,8 +73,7 @@ logger_handle_raw_h = h.Callable[[l.LogRecord], None]
|
|
62
73
|
logger_handle_with_self_h = h.Callable[[l.Logger, l.LogRecord], None]
|
63
74
|
logger_handle_h = logger_handle_raw_h | logger_handle_with_self_h
|
64
75
|
|
65
|
-
|
66
|
-
_DATE_ORIGIN = _DATE_TIME_ORIGIN.date()
|
76
|
+
MAIN_PROCESS_NAME = "MainProcess"
|
67
77
|
|
68
78
|
|
69
79
|
@d.dataclass(slots=True, repr=False, eq=False)
|
@@ -85,26 +95,51 @@ class logger_t(base_t):
|
|
85
95
|
history: dict[date_time_t, str] = d.field(init=False, default_factory=dict)
|
86
96
|
n_events: dict[int, int] = d.field(init=False, default_factory=dict)
|
87
97
|
|
88
|
-
last_message_now: date_time_t = d.field(init=False, default=
|
89
|
-
last_message_date: date_t = d.field(init=False, default=
|
98
|
+
last_message_now: date_time_t = d.field(init=False, default=DATE_TIME_ORIGIN)
|
99
|
+
last_message_date: date_t = d.field(init=False, default=DATE_ORIGIN)
|
90
100
|
memory_usages: list[tuple[str, int]] = d.field(init=False, default_factory=list)
|
91
101
|
context_levels: list[str] = d.field(init=False, default_factory=list)
|
92
|
-
staged_issues: list[issue_t] = d.field(
|
102
|
+
staged_issues: list[tuple[issue_t, bool]] = d.field(
|
103
|
+
init=False, default_factory=list
|
104
|
+
)
|
93
105
|
intercepted_wrn_handle: logger_handle_h | None = d.field(init=False, default=None)
|
94
106
|
intercepted_log_handles: dict[str, logger_handle_h] = d.field(
|
95
107
|
init=False, default_factory=dict
|
96
108
|
)
|
97
109
|
intercepts_exceptions: bool = d.field(init=False, default=False)
|
98
110
|
|
99
|
-
# Used only until the
|
111
|
+
# Used only until the first handler is added (see AddHandler).
|
100
112
|
_should_activate_log_interceptions: bool = d.field(init=False, default=False)
|
101
113
|
|
114
|
+
log_server: log_server_t | None = d.field(init=False, default=None)
|
115
|
+
|
102
116
|
name_: d.InitVar[str | None] = None
|
103
117
|
level_: d.InitVar[int] = l.NOTSET
|
104
118
|
activate_wrn_interceptions: d.InitVar[bool] = True
|
105
119
|
activate_log_interceptions: d.InitVar[bool] = True
|
106
120
|
activate_exc_interceptions: d.InitVar[bool] = True
|
107
121
|
|
122
|
+
@property
|
123
|
+
def formatted_history(self) -> str:
|
124
|
+
""""""
|
125
|
+
FormattedEntry = lambda _: f"{_[0]}: {_[1].replace('\n', '↲ ')}"
|
126
|
+
return "\n".join(map(FormattedEntry, self.history.items()))
|
127
|
+
|
128
|
+
@property
|
129
|
+
def records(self) -> records_h | None:
|
130
|
+
""""""
|
131
|
+
return logger_t.Records(self)
|
132
|
+
|
133
|
+
@staticmethod
|
134
|
+
def Records(logger: base_t | l.Logger, /) -> records_h | None:
|
135
|
+
""""""
|
136
|
+
for handler in logger.handlers:
|
137
|
+
output = getattr(handler, "records", None)
|
138
|
+
if memory_handler_t.AreRecords(output):
|
139
|
+
return output
|
140
|
+
|
141
|
+
return None
|
142
|
+
|
108
143
|
@property
|
109
144
|
def intercepts_warnings(self) -> bool:
|
110
145
|
""""""
|
@@ -152,9 +187,15 @@ class logger_t(base_t):
|
|
152
187
|
activate_exc_interceptions: bool,
|
153
188
|
) -> None:
|
154
189
|
""""""
|
190
|
+
assert prll.current_process().name == MAIN_PROCESS_NAME
|
191
|
+
|
155
192
|
if name_ is None:
|
156
193
|
name_ = f"{type(self).__name__}:{hex(id(self))[2:]}"
|
157
194
|
|
195
|
+
self.history[date_time_t.now()] = (
|
196
|
+
f'Logger "{name_}" instantiation for "{LAUNCH_ROOT_FILE_relative}"'
|
197
|
+
)
|
198
|
+
|
158
199
|
base_t.__init__(self, name_)
|
159
200
|
self.setLevel(level_)
|
160
201
|
self.propagate = False # Part of base_t.
|
@@ -175,44 +216,41 @@ class logger_t(base_t):
|
|
175
216
|
if self.should_monitor_memory_usage:
|
176
217
|
self.ActivateMemoryUsageMonitoring()
|
177
218
|
|
178
|
-
self.history[date_time_t.now()] = (
|
179
|
-
f'Logger "{self.name}" instantiation for "{PROJECT_FILE_RELATIVE}"'
|
180
|
-
)
|
181
|
-
|
182
219
|
def handle(self, record: l.LogRecord, /) -> None:
|
183
220
|
""""""
|
184
|
-
|
185
|
-
|
221
|
+
now = date_time_t.now()
|
186
222
|
if (date := now.date()) != self.last_message_date:
|
187
223
|
self._AcknowledgeDateChange(date)
|
188
224
|
|
225
|
+
level = record.levelno
|
226
|
+
|
189
227
|
# When.
|
190
|
-
if
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
228
|
+
if getattr(record, SHOW_WHEN_ATTR, True):
|
229
|
+
if now - self.last_message_now > LONG_ENOUGH:
|
230
|
+
w_or_e = f"{now:{TIME_FORMAT}}"
|
231
|
+
else:
|
232
|
+
w_or_e = FormattedElapsedTime(now) # or: f"{[...]:.<{TIME_LENGTH}}".
|
233
|
+
setattr(record, WHEN_OR_ELAPSED_ATTR, w_or_e)
|
195
234
|
self.last_message_now = now
|
196
235
|
|
197
236
|
# Where.
|
198
|
-
should_show_where = getattr(record, SHOW_WHERE_ATTR,
|
237
|
+
should_show_where = getattr(record, SHOW_WHERE_ATTR, level != l.INFO)
|
199
238
|
if should_show_where or self.should_monitor_memory_usage:
|
200
|
-
where =
|
201
|
-
|
202
|
-
|
239
|
+
where = f"{record.pathname}:{record.funcName}:{record.lineno}"
|
240
|
+
if should_show_where:
|
241
|
+
setattr(record, WHERE_ATTR, where)
|
242
|
+
if self.should_monitor_memory_usage:
|
243
|
+
self.memory_usages.append((where, CurrentMemoryUsage()))
|
203
244
|
|
204
245
|
# What.
|
205
246
|
if not isinstance(record.msg, str):
|
206
247
|
record.msg = str(record.msg)
|
207
248
|
|
208
249
|
base_t.handle(self, record)
|
209
|
-
self.n_events[
|
250
|
+
self.n_events[level] += 1
|
210
251
|
|
211
|
-
if self.
|
212
|
-
self.
|
213
|
-
|
214
|
-
if (self.exit_on_critical and (record.levelno is l.CRITICAL)) or (
|
215
|
-
self.exit_on_error and (record.levelno is l.ERROR)
|
252
|
+
if (self.exit_on_critical and (level is l.CRITICAL)) or (
|
253
|
+
self.exit_on_error and (level is l.ERROR)
|
216
254
|
):
|
217
255
|
# Also works if self.exit_on_error and record.levelno is l.CRITICAL since
|
218
256
|
# __post_init__ set self.exit_on_critical if self.exit_on_error.
|
@@ -226,7 +264,7 @@ class logger_t(base_t):
|
|
226
264
|
{
|
227
265
|
"name": self.name,
|
228
266
|
"levelno": l.INFO, # For management by logging.Logger.handle.
|
229
|
-
"msg": f"DATE: {date
|
267
|
+
"msg": f"DATE: {date:{DATE_FORMAT}}",
|
230
268
|
SHOW_W_RULE_ATTR: True,
|
231
269
|
}
|
232
270
|
)
|
@@ -332,8 +370,8 @@ class logger_t(base_t):
|
|
332
370
|
|
333
371
|
def AddHandler(
|
334
372
|
self,
|
335
|
-
handler_t_or_handler: type[
|
336
|
-
|
|
373
|
+
handler_t_or_handler: type[base_handler_h]
|
374
|
+
| base_handler_h
|
337
375
|
| l.Handler
|
338
376
|
| l.FileHandler,
|
339
377
|
/,
|
@@ -386,6 +424,27 @@ class logger_t(base_t):
|
|
386
424
|
""""""
|
387
425
|
self.AddHandler(file_handler_t, path=path)
|
388
426
|
|
427
|
+
def MakeMultiSafe(self) -> None:
|
428
|
+
"""
|
429
|
+
Should not be called until after all desired handlers have been added (as a
|
430
|
+
better-then-nothing check, it is checked that the logger has at least one
|
431
|
+
handler). If handlers are added passed this call, execution might freeze or
|
432
|
+
crash.
|
433
|
+
"""
|
434
|
+
assert self.log_server is None
|
435
|
+
assert self.hasHandlers()
|
436
|
+
|
437
|
+
handlers = tuple(self.handlers) # Making a copy is necessary.
|
438
|
+
for handler in handlers:
|
439
|
+
self.removeHandler(handler)
|
440
|
+
|
441
|
+
queue = prll.Queue()
|
442
|
+
|
443
|
+
self.addHandler(queue_handler_t(queue))
|
444
|
+
|
445
|
+
self.log_server = log_server_t(queue, *handlers)
|
446
|
+
self.log_server.start()
|
447
|
+
|
389
448
|
def __call__(self, *args, **kwargs) -> None:
|
390
449
|
"""
|
391
450
|
For a print-like calling for print-based debugging.
|
@@ -397,7 +456,7 @@ class logger_t(base_t):
|
|
397
456
|
path = path_t(details.filename)
|
398
457
|
if path.is_relative_to(USER_FOLDER):
|
399
458
|
path = path.relative_to(USER_FOLDER)
|
400
|
-
where = f"{str(path.with_suffix(''))}
|
459
|
+
where = f"{str(path.with_suffix(''))}:{details.function}:{details.lineno}"
|
401
460
|
|
402
461
|
self.info(separator.join(map(str, args)) + f"\n{WHERE_SEPARATOR} " + where)
|
403
462
|
|
@@ -416,7 +475,7 @@ class logger_t(base_t):
|
|
416
475
|
""""""
|
417
476
|
if isinstance(level, str):
|
418
477
|
level = l.getLevelNamesMapping()[level.upper()]
|
419
|
-
message = MessageWithActualExpected(
|
478
|
+
message, has_actual_expected = MessageWithActualExpected(
|
420
479
|
message,
|
421
480
|
actual=actual,
|
422
481
|
expected=expected,
|
@@ -424,7 +483,25 @@ class logger_t(base_t):
|
|
424
483
|
expected_op=expected_op,
|
425
484
|
with_final_dot=with_final_dot,
|
426
485
|
)
|
427
|
-
|
486
|
+
if has_actual_expected:
|
487
|
+
extra = {HAS_ACTUAL_EXPECTED_ATTR: True}
|
488
|
+
else:
|
489
|
+
extra = {}
|
490
|
+
self.log(level, message, extra=extra)
|
491
|
+
|
492
|
+
def LogAsIs(self, message: str, /, *, indented: bool = False) -> None:
|
493
|
+
""""""
|
494
|
+
if indented:
|
495
|
+
message = text.indent(message, LINE_INDENT)
|
496
|
+
|
497
|
+
for handler in self.handlers:
|
498
|
+
EmitMessage = getattr(
|
499
|
+
handler, handler_extension_t.EmitMessage.__name__, None
|
500
|
+
)
|
501
|
+
if EmitMessage is not None:
|
502
|
+
EmitMessage(message)
|
503
|
+
|
504
|
+
info_raw = LogAsIs # To follow the convention of the logging methods info, error...
|
428
505
|
|
429
506
|
def LogException(
|
430
507
|
self,
|
@@ -454,25 +531,9 @@ class logger_t(base_t):
|
|
454
531
|
self.LogException(exception, level=l.CRITICAL)
|
455
532
|
s.exit(1)
|
456
533
|
|
457
|
-
def DealWithExceptionInThread(
|
458
|
-
self, exc_type, exc_value, exc_traceback, _, /
|
459
|
-
) -> None:
|
534
|
+
def DealWithExceptionInThread(self, args, /) -> None:
|
460
535
|
""""""
|
461
|
-
self.DealWithException(exc_type, exc_value, exc_traceback)
|
462
|
-
|
463
|
-
def LogAsIs(self, message: str, /, *, indented: bool = False) -> None:
|
464
|
-
""""""
|
465
|
-
if indented:
|
466
|
-
message = text.indent(message, LINE_INDENT)
|
467
|
-
|
468
|
-
for handler in self.handlers:
|
469
|
-
EmitMessage = getattr(
|
470
|
-
handler, handler_extension_t.EmitMessage.__name__, None
|
471
|
-
)
|
472
|
-
if EmitMessage is not None:
|
473
|
-
EmitMessage(message)
|
474
|
-
|
475
|
-
info_raw = LogAsIs # To follow the convention of the logging methods info, error...
|
536
|
+
self.DealWithException(args.exc_type, args.exc_value, args.exc_traceback)
|
476
537
|
|
477
538
|
def DisplayRule(
|
478
539
|
self, /, *, message: str | None = None, color: str = "white"
|
@@ -523,7 +584,9 @@ class logger_t(base_t):
|
|
523
584
|
)
|
524
585
|
self.staged_issues.append(issue)
|
525
586
|
|
526
|
-
def PopIssues(
|
587
|
+
def PopIssues(
|
588
|
+
self, /, *, should_remove_context: bool = False
|
589
|
+
) -> list[tuple[str, bool]]:
|
527
590
|
""""""
|
528
591
|
if not self.has_staged_issues:
|
529
592
|
return []
|
@@ -535,10 +598,10 @@ class logger_t(base_t):
|
|
535
598
|
else:
|
536
599
|
separator = ISSUE_LEVEL_SEPARATOR
|
537
600
|
separator_length = separator.__len__()
|
538
|
-
for issue in self.staged_issues:
|
601
|
+
for issue, has_actual_expected in self.staged_issues:
|
539
602
|
start_idx = issue.find(separator)
|
540
603
|
issue = issue[(start_idx + separator_length) :]
|
541
|
-
output.append(issue)
|
604
|
+
output.append((issue, has_actual_expected))
|
542
605
|
|
543
606
|
self.staged_issues.clear()
|
544
607
|
|
@@ -560,13 +623,16 @@ class logger_t(base_t):
|
|
560
623
|
"Invalid commit order",
|
561
624
|
actual=order,
|
562
625
|
expected=f"One of {str(ORDER)[1:-1]}",
|
563
|
-
)
|
626
|
+
)[0]
|
564
627
|
)
|
565
628
|
|
566
629
|
if order == "when":
|
567
630
|
issues = self.staged_issues
|
568
631
|
else: # order == "context"
|
569
|
-
issues = sorted(
|
632
|
+
issues = sorted(
|
633
|
+
self.staged_issues,
|
634
|
+
key=lambda _: _[0].split(ISSUE_LEVEL_SEPARATOR, maxsplit=1)[1],
|
635
|
+
)
|
570
636
|
"""
|
571
637
|
Format issues as an exception:
|
572
638
|
try:
|
@@ -578,20 +644,43 @@ class logger_t(base_t):
|
|
578
644
|
formatted = "\n".join(lines)
|
579
645
|
"""
|
580
646
|
|
581
|
-
|
647
|
+
extra = {SHOW_WHERE_ATTR: False}
|
582
648
|
if unified:
|
583
|
-
level, _ = issues[0].split(ISSUE_LEVEL_SEPARATOR, maxsplit=1)
|
649
|
+
level, _ = issues[0][0].split(ISSUE_LEVEL_SEPARATOR, maxsplit=1)
|
584
650
|
wo_level = []
|
585
|
-
|
651
|
+
any_has_actual_expected = False
|
652
|
+
for issue, has_actual_expected in issues:
|
586
653
|
_, issue = issue.split(ISSUE_LEVEL_SEPARATOR, maxsplit=1)
|
654
|
+
if has_actual_expected:
|
655
|
+
any_has_actual_expected = True
|
587
656
|
wo_level.append(issue)
|
588
|
-
|
657
|
+
if any_has_actual_expected:
|
658
|
+
extra[HAS_ACTUAL_EXPECTED_ATTR] = True
|
659
|
+
self.log(int(level), "\n".join(wo_level), stacklevel=2, extra=extra)
|
589
660
|
else:
|
590
|
-
for issue in issues:
|
661
|
+
for issue, has_actual_expected in issues:
|
591
662
|
level, issue = issue.split(ISSUE_LEVEL_SEPARATOR, maxsplit=1)
|
592
|
-
|
663
|
+
if has_actual_expected:
|
664
|
+
extra[HAS_ACTUAL_EXPECTED_ATTR] = True
|
665
|
+
self.log(int(level), issue, stacklevel=2, extra=extra)
|
666
|
+
if has_actual_expected:
|
667
|
+
del extra[HAS_ACTUAL_EXPECTED_ATTR]
|
593
668
|
self.staged_issues.clear()
|
594
669
|
|
670
|
+
def StoragePath(self, suffix: str, /) -> path_t:
|
671
|
+
"""
|
672
|
+
Use as staticmethod if needed.
|
673
|
+
"""
|
674
|
+
for handler in self.handlers:
|
675
|
+
if (path := getattr(handler, "baseFilename", None)) is not None:
|
676
|
+
output = path_t(path).with_suffix(suffix)
|
677
|
+
if output.exists():
|
678
|
+
output = NewTemporaryFile(suffix)
|
679
|
+
|
680
|
+
return output
|
681
|
+
|
682
|
+
return NewTemporaryFile(suffix)
|
683
|
+
|
595
684
|
def __enter__(self) -> None:
|
596
685
|
""""""
|
597
686
|
pass
|
@@ -607,25 +696,12 @@ class logger_t(base_t):
|
|
607
696
|
_ = self.context_levels.pop()
|
608
697
|
return False
|
609
698
|
|
699
|
+
def __del__(self) -> None:
|
700
|
+
""""""
|
701
|
+
assert prll.current_process().name == MAIN_PROCESS_NAME
|
610
702
|
|
611
|
-
|
612
|
-
|
613
|
-
module = path_t(record.pathname)
|
614
|
-
for path in s.path:
|
615
|
-
if module.is_relative_to(path):
|
616
|
-
module = module.relative_to(path).with_suffix("")
|
617
|
-
module = str(module).replace(FOLDER_SEPARATOR, ".")
|
618
|
-
break
|
619
|
-
else:
|
620
|
-
if module.is_relative_to(USER_FOLDER):
|
621
|
-
module = module.relative_to(USER_FOLDER)
|
622
|
-
|
623
|
-
output = f"{module}:{record.funcName}:{record.lineno}"
|
624
|
-
|
625
|
-
if should_also_store:
|
626
|
-
record.where = output
|
627
|
-
|
628
|
-
return output
|
703
|
+
if self.log_server is not None:
|
704
|
+
self.log_server.stop()
|
629
705
|
|
630
706
|
|
631
707
|
def _HandleForWarnings(interceptor: base_t, /) -> logger_handle_h:
|
logger_36/version.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: logger-36
|
3
|
-
Version: 2025.
|
3
|
+
Version: 2025.25
|
4
4
|
Summary: Simple logger with a catalog of handlers
|
5
5
|
Home-page: https://src.koda.cnrs.fr/eric.debreuve/logger-36/
|
6
6
|
Author: Eric Debreuve
|
@@ -109,46 +109,32 @@ The code is formatted by `Black <https://github.com/psf/black/>`_, *The Uncompro
|
|
109
109
|
The imports are ordered by `isort <https://github.com/timothycrosley/isort/>`_... *your imports, so you don't have to*.
|
110
110
|
|
111
111
|
..
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
This software is being developed by Eric Debreuve, a CNRS employee and
|
143
|
-
member of team Morpheme.
|
144
|
-
Team Morpheme is a joint team between Inria, CNRS, and UniCA.
|
145
|
-
It is hosted by the Centre Inria d'Université Côte d'Azur, Laboratory
|
146
|
-
I3S, and Laboratory iBV.
|
147
|
-
|
148
|
-
CNRS: https://www.cnrs.fr/index.php/en
|
149
|
-
Inria: https://www.inria.fr/en/
|
150
|
-
UniCA: https://univ-cotedazur.eu/
|
151
|
-
Centre Inria d'Université Côte d'Azur: https://www.inria.fr/en/centre/sophia/
|
152
|
-
I3S: https://www.i3s.unice.fr/en/
|
153
|
-
iBV: http://ibv.unice.fr/
|
154
|
-
Team Morpheme: https://team.inria.fr/morpheme/
|
112
|
+
COPYRIGHT NOTICE
|
113
|
+
|
114
|
+
This software is governed by the CeCILL license under French law and
|
115
|
+
abiding by the rules of distribution of free software. You can use,
|
116
|
+
modify and/ or redistribute the software under the terms of the CeCILL
|
117
|
+
license as circulated by CEA, CNRS and INRIA at the following URL
|
118
|
+
"http://www.cecill.info".
|
119
|
+
|
120
|
+
As a counterpart to the access to the source code and rights to copy,
|
121
|
+
modify and redistribute granted by the license, users are provided only
|
122
|
+
with a limited warranty and the software's author, the holder of the
|
123
|
+
economic rights, and the successive licensors have only limited
|
124
|
+
liability.
|
125
|
+
|
126
|
+
In this respect, the user's attention is drawn to the risks associated
|
127
|
+
with loading, using, modifying and/or developing or reproducing the
|
128
|
+
software by the user in light of its specific status of free software,
|
129
|
+
that may mean that it is complicated to manipulate, and that also
|
130
|
+
therefore means that it is reserved for developers and experienced
|
131
|
+
professionals having in-depth computer knowledge. Users are therefore
|
132
|
+
encouraged to load and test the software's suitability as regards their
|
133
|
+
requirements in conditions enabling the security of their systems and/or
|
134
|
+
data to be ensured and, more generally, to use and operate it in the
|
135
|
+
same conditions as regards security.
|
136
|
+
|
137
|
+
The fact that you are presently reading this means that you have had
|
138
|
+
knowledge of the CeCILL license and that you accept its terms.
|
139
|
+
|
140
|
+
SEE LICENCE NOTICE: file README-LICENCE-utf8.txt at project source root.
|
@@ -0,0 +1,53 @@
|
|
1
|
+
logger_36/__init__.py,sha256=mK6AD0eWI2Sk42oxleTvsxzYJ28FbHK5WNkpLgAhnNE,2129
|
2
|
+
logger_36/version.py,sha256=gqr9_xGceDfeDrDRv0O1e-8Rn6mXcEV_iFdCtiuTyAk,1680
|
3
|
+
logger_36/api/chronos.py,sha256=o_UMZbeExjb01aNURmzIjOMAHhI9e90nyvJJYcJR6VQ,1739
|
4
|
+
logger_36/api/logger.py,sha256=eLZ2yuH-sYeh4Z2KnAwTRJEbmkmgzBPMncdqXfFUTG8,1760
|
5
|
+
logger_36/api/memory.py,sha256=U4mMEkx8WRHk9q2d3SCFGt2EJaBuflOXw2bGbAxOnSc,1828
|
6
|
+
logger_36/api/message.py,sha256=DuT4UX4r_1DTXzuuRD-tvsTZk5X-Nj11loBKhuWOMw0,1791
|
7
|
+
logger_36/api/storage.py,sha256=S1fVzrMp-_zlhg27fRPddWCFQRyvbpFwSreALOeoNFI,1713
|
8
|
+
logger_36/catalog/config/console_rich.py,sha256=t9p9-AkSgPiLAsm1evAdbz77g7JcVLePhUJ1FzNi3cY,2330
|
9
|
+
logger_36/catalog/config/optional.py,sha256=8d8HdpE07gHfsdoL8mVAlRlh9AgLcb4z7I7h6ob7CfU,2174
|
10
|
+
logger_36/catalog/handler/console.py,sha256=XIyO_8MrzaTlihDbFhIzRk47HjxMH4gV2Zqp0-1oMsU,2320
|
11
|
+
logger_36/catalog/handler/console_rich.py,sha256=RXLu8AQxAmyec1bXUc99Mabp7BjZc-lKEfwrCzMPkZA,6662
|
12
|
+
logger_36/catalog/handler/file.py,sha256=5GR_aACDEBXuZ-pUH9P0OCaXbCf-aLPmsz-XrGCAIgE,2434
|
13
|
+
logger_36/catalog/handler/generic.py,sha256=kwr7x7GWLmWvT7niHGW7OqlMotvTQNuNEwQGfKh_nhU,7040
|
14
|
+
logger_36/catalog/handler/memory.py,sha256=pJwKOlCm8Ej8ipDI00-FfX4qJjMPXJb-DucD1ukIQOU,4057
|
15
|
+
logger_36/catalog/logger/chronos.py,sha256=MDAx_NRRcRZcQYDDjVCRcu87SDP-rPYjX0-10KNcMnk,2216
|
16
|
+
logger_36/catalog/logger/gpu.py,sha256=Py5YY0nD_pqJzJsEKQYoOGHcPqyNVJ3J2noOS3hDL6g,2890
|
17
|
+
logger_36/catalog/logger/memory.py,sha256=pa-9pkvDGdf52giwL3Zi1mjWNFE_NVzBGdjwcfeIDNc,4256
|
18
|
+
logger_36/catalog/logger/system.py,sha256=zEbHirATqZAVYFmHLd0pppeuRhka1ucWwyHRq0afQNE,2593
|
19
|
+
logger_36/config/issue.py,sha256=QOkVRPSLZC_2mfcFpad-pcSXJXfLHdWUAXiMbTWlZTg,1741
|
20
|
+
logger_36/config/memory.py,sha256=bZmNYsD2goVdkraS1v_t2OqAJo86jKMtP311kIVURDk,1691
|
21
|
+
logger_36/config/message.py,sha256=bDAW4hZdsHBTYlCA7IZbL1FxGPwjX9Khmw0d21VHGs0,1968
|
22
|
+
logger_36/config/rule.py,sha256=BqOb4SWKgT0YQZ-DtOzkLNZNWZVZkl5GN3lMoWoPrKw,1702
|
23
|
+
logger_36/config/system.py,sha256=YRSa2eN_SoTnTXWUXAcpKt4JXifabzMR0eXwjUYlA_A,1951
|
24
|
+
logger_36/constant/chronos.py,sha256=JJvBN_skqRdUgnuWhMqG0gZ3_ZkXmAz1syEixfu4lCM,2131
|
25
|
+
logger_36/constant/error.py,sha256=FinnCcwGGH2oiXX3aw2uxKYvR3d5Tkb9rlNhNjyuoF8,2354
|
26
|
+
logger_36/constant/html.py,sha256=w8gttc1XBSMpdKRolnXAVJ5x_hOAIsVsUyELCXJYdWU,2011
|
27
|
+
logger_36/constant/issue.py,sha256=0EmcsRmSxktFUJR0qOU0PnKG-gfbLDOULH6sSRHFOcc,1789
|
28
|
+
logger_36/constant/logger.py,sha256=ZQYX9JiPsoivwRgYNtdEqRKCagSKD88lRqvxP8MX1ZE,1942
|
29
|
+
logger_36/constant/memory.py,sha256=Q_E5tTWa-cGaNwrE_xmKa3BxQG6oJO6DHczrxc_M4sE,1817
|
30
|
+
logger_36/constant/message.py,sha256=TdsZXWO2UmlG3a0ia3UsUCxtVUa8GNferi69pO4A9TM,2301
|
31
|
+
logger_36/constant/path.py,sha256=r-vx5ztGhcpYfg37kw0oaxBYdTSkWOJuToTmexaW8tE,2265
|
32
|
+
logger_36/constant/record.py,sha256=70JO2LYL-1Eg-vLD3N7nUoYALp6ji7-b3DLxCHTc7iQ,1881
|
33
|
+
logger_36/constant/rule.py,sha256=ul-MqOdHBGBC5Nwn05EUnz2T__7VEs82qiH7Fzs5qCk,1804
|
34
|
+
logger_36/constant/system.py,sha256=pLlLXG5sepQlSUOo3TphaGrHg8xzJBp-GxpL2NPP47k,1904
|
35
|
+
logger_36/extension/file.py,sha256=ClY8k805DnB6Vy0LEQIhlO0MavP91Y-CEjHjFepyROE,2034
|
36
|
+
logger_36/extension/inspection.py,sha256=LoHXi4wsIgHKrq_7GYkVcfJ9rnBG16pLKMpAoHNwJiY,3922
|
37
|
+
logger_36/extension/line.py,sha256=9BgxnY6wiyc44Ari5rkvqbvz9ao4sNs39u8k7sY6vFc,2611
|
38
|
+
logger_36/extension/sentinel.py,sha256=SQgkQiRcTIjCRvbxiOb6TEm59BC0FNMcjYoIShpcwLo,1718
|
39
|
+
logger_36/instance/logger.py,sha256=X_U10RYU1h2Aa70D8hBnmFyJZtRILK16KN-GB4xkHMU,1782
|
40
|
+
logger_36/instance/loggers.py,sha256=inBk4KKrQ-z3szaopQ29-qQwh1iSc842sWo5J6zJoiM,1725
|
41
|
+
logger_36/task/storage.py,sha256=L93v5w9p_7MoiagEr3d6QSYEQxX42DxmZ-BJTCuLpgQ,3915
|
42
|
+
logger_36/task/format/memory.py,sha256=xcWwbUnl1BxH7RVBHyhp1RlbT2n370PzoFLLLd3dtlU,3726
|
43
|
+
logger_36/task/format/message.py,sha256=Q9QkyUAU47Nj606zsvq0gNyso8Vk9G9OaqG9Em5FjKg,3575
|
44
|
+
logger_36/task/measure/chronos.py,sha256=fZKK16LwlLzRRAP-gfF1uy6gFCL33gR7LZ4Xs_nXdVY,2612
|
45
|
+
logger_36/task/measure/memory.py,sha256=kkPHEIUTUhkCOLrAt01eLJLnsnkl0nFPNhFZdIB_JAw,1991
|
46
|
+
logger_36/type/handler.py,sha256=bDsCFYpevCJBV7Vc9jovttapjU-7GXI1_TDbmOf2kN4,6660
|
47
|
+
logger_36/type/issue.py,sha256=M2KeQwzDG9yqgdtbyWk5Y-ier7c71TuAKlNCf5QCGzY,2770
|
48
|
+
logger_36/type/logger.py,sha256=0OjqyMcBAyS0qUUeEzweALrs0m5rVqZF3e6R1b8B4RA,27358
|
49
|
+
logger_36/type/loggers.py,sha256=7EX7Sg_RlduBjdfFlNZmUfNeDloH1xU30Rdkg_-rXh8,3172
|
50
|
+
logger_36-2025.25.dist-info/METADATA,sha256=Uchfn7mGuqLow-qAR-TejGvwkXNns2N7XnpLbgHeGFE,5980
|
51
|
+
logger_36-2025.25.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
52
|
+
logger_36-2025.25.dist-info/top_level.txt,sha256=sM95BTMWmslEEgR_1pzwZsOeSp8C_QBiu8ImbFr0XLc,10
|
53
|
+
logger_36-2025.25.dist-info/RECORD,,
|