logger-36 2025.27__tar.gz → 2025.29__tar.gz
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-2025.27 → logger_36-2025.29}/PKG-INFO +1 -1
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/catalog/logger/chronos.py +34 -6
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/task/measure/chronos.py +7 -2
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/type/logger.py +37 -18
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/version.py +1 -1
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36.egg-info/PKG-INFO +1 -1
- {logger_36-2025.27 → logger_36-2025.29}/MANIFEST.in +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/README-COPYRIGHT-utf8.txt +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/README-LICENCE-utf8.txt +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/README.rst +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/documentation/wiki/description.asciidoc +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/__init__.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/api/chronos.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/api/logger.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/api/memory.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/api/message.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/api/storage.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/catalog/config/console_rich.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/catalog/config/optional.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/catalog/handler/console.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/catalog/handler/console_rich.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/catalog/handler/file.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/catalog/handler/generic.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/catalog/handler/memory.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/catalog/logger/gpu.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/catalog/logger/memory.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/catalog/logger/system.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/config/issue.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/config/memory.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/config/message.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/config/rule.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/config/system.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/constant/chronos.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/constant/error.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/constant/html.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/constant/issue.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/constant/logger.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/constant/memory.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/constant/message.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/constant/path.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/constant/record.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/constant/rule.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/constant/system.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/extension/file.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/extension/inspection.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/extension/line.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/extension/sentinel.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/instance/logger.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/instance/loggers.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/task/format/memory.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/task/format/message.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/task/measure/memory.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/task/storage.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/type/handler.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/type/issue.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36/type/loggers.py +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36.egg-info/SOURCES.txt +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36.egg-info/dependency_links.txt +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/package/logger_36.egg-info/top_level.txt +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/pyproject.toml +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/setup.cfg +0 -0
- {logger_36-2025.27 → logger_36-2025.29}/setup.py +0 -0
@@ -6,20 +6,48 @@ SEE COPYRIGHT NOTICE BELOW
|
|
6
6
|
|
7
7
|
from datetime import datetime as date_time_t
|
8
8
|
|
9
|
-
from logger_36.constant.chronos import FORMATTED_START_DATE_TIME
|
10
|
-
from logger_36.constant.record import SHOW_WHEN_ATTR
|
9
|
+
from logger_36.constant.chronos import FORMATTED_START_DATE_TIME, START_DATE_TIME
|
10
|
+
from logger_36.constant.record import SHOW_WHEN_ATTR, SHOW_WHERE_ATTR
|
11
11
|
from logger_36.instance.logger import L
|
12
12
|
from logger_36.task.measure.chronos import FormattedElapsedTime
|
13
13
|
from logger_36.type.logger import logger_t
|
14
14
|
|
15
15
|
|
16
|
+
_START_NAME = "START"
|
17
|
+
_START_PLACEHOLDER = "..." # Must not be longer than _START_NAME.
|
18
|
+
_END_NAME = "END"
|
19
|
+
|
20
|
+
|
16
21
|
def LogElapsedTime(*, logger: logger_t = L) -> None:
|
17
22
|
""""""
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
23
|
+
now = date_time_t.now()
|
24
|
+
|
25
|
+
message = (
|
26
|
+
f"Elapsed Time: {FormattedElapsedTime(now, with_separator=False)} "
|
27
|
+
f"(since {FORMATTED_START_DATE_TIME})"
|
22
28
|
)
|
29
|
+
if logger.intermediate_times.__len__() > 0:
|
30
|
+
intermediate_e_times = []
|
31
|
+
for (start_name, start_time), (end_name, end_time) in zip(
|
32
|
+
[(_START_NAME, START_DATE_TIME)] + logger.intermediate_times,
|
33
|
+
logger.intermediate_times + [(_END_NAME, now)],
|
34
|
+
strict=True,
|
35
|
+
):
|
36
|
+
if start_name != _START_NAME:
|
37
|
+
start_name = _START_PLACEHOLDER
|
38
|
+
e_time = FormattedElapsedTime(
|
39
|
+
end_time, reference=start_time, with_separator=False
|
40
|
+
)
|
41
|
+
intermediate_e_times.append((start_name, end_name, e_time))
|
42
|
+
max_length_end = max(map(len, (_[1] for _ in intermediate_e_times)))
|
43
|
+
intermediate_e_times = "\n ".join(
|
44
|
+
f"{_: <{_START_NAME.__len__()}} → {__: <{max_length_end}} +{___}"
|
45
|
+
for _, __, ___ in intermediate_e_times
|
46
|
+
)
|
47
|
+
message += "\n " + intermediate_e_times
|
48
|
+
logger.intermediate_times.clear()
|
49
|
+
|
50
|
+
logger.info(message, extra={SHOW_WHEN_ATTR: False, SHOW_WHERE_ATTR: False})
|
23
51
|
|
24
52
|
|
25
53
|
"""
|
@@ -24,7 +24,11 @@ def TimeStamp(*, precision: str = "microseconds") -> str:
|
|
24
24
|
|
25
25
|
|
26
26
|
def FormattedElapsedTime(
|
27
|
-
now: date_time_t,
|
27
|
+
now: date_time_t,
|
28
|
+
/,
|
29
|
+
*,
|
30
|
+
reference: date_time_t = START_DATE_TIME,
|
31
|
+
with_separator: bool = True,
|
28
32
|
) -> str:
|
29
33
|
""""""
|
30
34
|
output = str(now - reference)
|
@@ -36,7 +40,8 @@ def FormattedElapsedTime(
|
|
36
40
|
if output[0] == "0":
|
37
41
|
output = output[1:]
|
38
42
|
|
39
|
-
|
43
|
+
if with_separator:
|
44
|
+
output = ELAPSED_TIME_SEPARATOR + output
|
40
45
|
|
41
46
|
if output.__len__() > TIME_LENGTH:
|
42
47
|
return output[:TIME_LENGTH]
|
@@ -92,6 +92,9 @@ class logger_t(base_t):
|
|
92
92
|
|
93
93
|
history: dict[date_time_t, str] = d.field(init=False, default_factory=dict)
|
94
94
|
n_events: dict[int, int] = d.field(init=False, default_factory=dict)
|
95
|
+
intermediate_times: list[tuple[str, date_time_t]] = d.field(
|
96
|
+
init=False, default_factory=list
|
97
|
+
)
|
95
98
|
|
96
99
|
last_message_now: date_time_t = d.field(init=False, default=DATE_TIME_ORIGIN)
|
97
100
|
last_message_date: date_t = d.field(init=False, default=DATE_ORIGIN)
|
@@ -109,6 +112,7 @@ class logger_t(base_t):
|
|
109
112
|
# Used only until the first handler is added (see AddHandler).
|
110
113
|
_should_activate_log_interceptions: bool = d.field(init=False, default=False)
|
111
114
|
|
115
|
+
server_handlers: tuple[l.Handler,...]|None = d.field(init=False, default=None)
|
112
116
|
log_server: log_server_t | None = d.field(init=False, default=None)
|
113
117
|
|
114
118
|
name_: d.InitVar[str | None] = None
|
@@ -429,9 +433,12 @@ class logger_t(base_t):
|
|
429
433
|
handler). If handlers are added passed this call, execution might freeze or
|
430
434
|
crash.
|
431
435
|
"""
|
432
|
-
assert
|
436
|
+
assert prll.current_process().name == MAIN_PROCESS_NAME
|
433
437
|
assert self.hasHandlers()
|
434
438
|
|
439
|
+
if self.log_server is not None:
|
440
|
+
return
|
441
|
+
|
435
442
|
handlers = tuple(self.handlers) # Making a copy is necessary.
|
436
443
|
for handler in handlers:
|
437
444
|
self.removeHandler(handler)
|
@@ -440,9 +447,31 @@ class logger_t(base_t):
|
|
440
447
|
|
441
448
|
self.addHandler(queue_handler_t(queue))
|
442
449
|
|
443
|
-
self.
|
450
|
+
self.server_handlers = handlers
|
451
|
+
self.log_server = log_server_t(queue, *handlers, respect_handler_level=True)
|
444
452
|
self.log_server.start()
|
445
453
|
|
454
|
+
def RemoveMultiSafety(self) -> None:
|
455
|
+
"""
|
456
|
+
Calling this method automatically as an atexit-registered function does not
|
457
|
+
flush the enqueued log records. It is probably too late then for this. Hence, if
|
458
|
+
MakeMultiSafe has been called, this method should also be called before the
|
459
|
+
execution ends.
|
460
|
+
"""
|
461
|
+
assert prll.current_process().name == MAIN_PROCESS_NAME
|
462
|
+
|
463
|
+
if self.log_server is None:
|
464
|
+
return
|
465
|
+
|
466
|
+
self.log_server.stop()
|
467
|
+
|
468
|
+
for handler in self.handlers: # There is only the QueueHandler, actually.
|
469
|
+
self.removeHandler(handler)
|
470
|
+
for handler in self.server_handlers:
|
471
|
+
self.addHandler(handler)
|
472
|
+
|
473
|
+
self.server_handlers = self.log_server = None
|
474
|
+
|
446
475
|
def __call__(self, *args, **kwargs) -> None:
|
447
476
|
"""
|
448
477
|
For a print-like calling for print-based debugging.
|
@@ -510,7 +539,7 @@ class logger_t(base_t):
|
|
510
539
|
message = "\n".join(lines[:1] + lines[2:])
|
511
540
|
else:
|
512
541
|
# TODO: Explain:
|
513
|
-
# - Why it
|
542
|
+
# - Why is it not: "\n".join(lines)?
|
514
543
|
# - Why adding exception name here and not when removing caller?
|
515
544
|
formatted = "".join(lines)
|
516
545
|
message = f"Exception of type {type(exception).__name__}\n----\n{formatted}"
|
@@ -541,11 +570,6 @@ class logger_t(base_t):
|
|
541
570
|
}
|
542
571
|
)
|
543
572
|
base_t.handle(self, record)
|
544
|
-
# emit_rule_name = handler_extension_t.EmitRule.__name__
|
545
|
-
# for handler in self.handlers:
|
546
|
-
# EmitRule = getattr(handler, emit_rule_name, None)
|
547
|
-
# if EmitRule is not None:
|
548
|
-
# EmitRule(text=message, color=color)
|
549
573
|
|
550
574
|
def AddContextLevel(self, new_level: str, /) -> None:
|
551
575
|
""""""
|
@@ -670,9 +694,13 @@ class logger_t(base_t):
|
|
670
694
|
del extra[HAS_ACTUAL_EXPECTED_ATTR]
|
671
695
|
self.staged_issues.clear()
|
672
696
|
|
697
|
+
def SetInstantName(self, name: str, /) -> None:
|
698
|
+
""""""
|
699
|
+
self.intermediate_times.append((name, date_time_t.now()))
|
700
|
+
|
673
701
|
def StoragePath(self, suffix: str, /) -> path_t:
|
674
702
|
"""
|
675
|
-
Use as staticmethod if needed.
|
703
|
+
Use as staticmethod if needed, passing a logger as self.
|
676
704
|
"""
|
677
705
|
for handler in self.handlers:
|
678
706
|
if (path := getattr(handler, "baseFilename", None)) is not None:
|
@@ -699,15 +727,6 @@ class logger_t(base_t):
|
|
699
727
|
_ = self.context_levels.pop()
|
700
728
|
return False
|
701
729
|
|
702
|
-
def __del__(self) -> None:
|
703
|
-
""""""
|
704
|
-
if (
|
705
|
-
(prll.current_process is not None)
|
706
|
-
and (prll.current_process().name == MAIN_PROCESS_NAME)
|
707
|
-
and (self.log_server is not None)
|
708
|
-
):
|
709
|
-
self.log_server.stop()
|
710
|
-
|
711
730
|
|
712
731
|
def _HandleForWarnings(interceptor: base_t, /) -> logger_handle_h:
|
713
732
|
""""""
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|