logger-36 2025.21__py3-none-any.whl → 2025.22__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/catalog/config/optional.py +10 -1
- logger_36/catalog/handler/console.py +1 -1
- logger_36/catalog/handler/console_rich.py +2 -2
- logger_36/catalog/handler/file.py +1 -1
- logger_36/catalog/handler/generic.py +7 -7
- logger_36/constant/record.py +4 -1
- logger_36/type/handler.py +7 -7
- logger_36/type/logger.py +144 -79
- logger_36/version.py +1 -1
- {logger_36-2025.21.dist-info → logger_36-2025.22.dist-info}/METADATA +1 -1
- {logger_36-2025.21.dist-info → logger_36-2025.22.dist-info}/RECORD +13 -13
- {logger_36-2025.21.dist-info → logger_36-2025.22.dist-info}/WHEEL +0 -0
- {logger_36-2025.21.dist-info → logger_36-2025.22.dist-info}/top_level.txt +0 -0
@@ -8,11 +8,20 @@ try:
|
|
8
8
|
import rich # noqa
|
9
9
|
except ModuleNotFoundError:
|
10
10
|
RICH_IS_AVAILABLE = False
|
11
|
-
from logger_36.constant.error import MISSING_RICH_MESSAGE
|
11
|
+
from logger_36.constant.error import MISSING_RICH_MESSAGE # noqa
|
12
12
|
else:
|
13
13
|
RICH_IS_AVAILABLE = True
|
14
14
|
MISSING_RICH_MESSAGE = None
|
15
15
|
|
16
|
+
from logger_36.task.measure.memory import CanCheckUsage as CanCheckMemoryUsage
|
17
|
+
|
18
|
+
if CanCheckMemoryUsage():
|
19
|
+
MEMORY_MEASURE_IS_AVAILABLE = True
|
20
|
+
MEMORY_MEASURE_ERROR = None
|
21
|
+
else:
|
22
|
+
MEMORY_MEASURE_IS_AVAILABLE = False
|
23
|
+
from logger_36.constant.error import MEMORY_MEASURE_ERROR # noqa
|
24
|
+
|
16
25
|
"""
|
17
26
|
COPYRIGHT NOTICE
|
18
27
|
|
@@ -96,7 +96,7 @@ class console_rich_handler_t(base_t):
|
|
96
96
|
""""""
|
97
97
|
return cls(name, message_width, level, kwargs)
|
98
98
|
|
99
|
-
def Rule(self, text: str | None
|
99
|
+
def Rule(self, /, *, text: str | None = None, color: str = "black") -> str | rule_t:
|
100
100
|
""""""
|
101
101
|
if text is None:
|
102
102
|
return rule_t(style=color)
|
@@ -116,7 +116,7 @@ class console_rich_handler_t(base_t):
|
|
116
116
|
self.console.print(message, crop=False, overflow="ignore")
|
117
117
|
self._log_parity = not self._log_parity
|
118
118
|
|
119
|
-
def
|
119
|
+
def EmitMessage(self, message: str | renderable_t, /) -> None:
|
120
120
|
""""""
|
121
121
|
self.console.print(message, crop=False, overflow="ignore")
|
122
122
|
|
@@ -32,7 +32,7 @@ class file_handler_t(base_t):
|
|
32
32
|
self.stream.write(output[0] + "\n")
|
33
33
|
self.stream.flush()
|
34
34
|
|
35
|
-
def
|
35
|
+
def EmitMessage(self, message: str, /) -> None:
|
36
36
|
""""""
|
37
37
|
self.stream.write(message + "\n")
|
38
38
|
self.stream.flush()
|
@@ -38,10 +38,10 @@ class generic_handler_t(base_t):
|
|
38
38
|
self, name: str | None, message_width: int, level: int, kwargs
|
39
39
|
) -> None:
|
40
40
|
"""
|
41
|
-
|
41
|
+
EmitMessage: By definition, the generic handler does not know how to output
|
42
42
|
messages. If not passed, it defaults to output-ing messages in the console.
|
43
43
|
"""
|
44
|
-
|
44
|
+
EmitMessage = kwargs.pop(base_t.EmitMessage.__name__, None)
|
45
45
|
alternating_logs = kwargs.pop("alternating_logs", 0)
|
46
46
|
supports_html = kwargs.pop("supports_html", False)
|
47
47
|
|
@@ -49,8 +49,8 @@ class generic_handler_t(base_t):
|
|
49
49
|
|
50
50
|
base_t.__init__(self, name, message_width, None, level, kwargs)
|
51
51
|
|
52
|
-
if
|
53
|
-
self.
|
52
|
+
if EmitMessage is not None:
|
53
|
+
self.EmitMessage = EmitMessage
|
54
54
|
self.is_rich = False
|
55
55
|
self.console = None # console_t | None.
|
56
56
|
self.console_options = None # rich.console.ConsoleOptions | None.
|
@@ -82,14 +82,14 @@ class generic_handler_t(base_t):
|
|
82
82
|
""""""
|
83
83
|
return cls(name, message_width, level, kwargs)
|
84
84
|
|
85
|
-
def Rule(self, text: str | None
|
85
|
+
def Rule(self, /, *, text: str | None = None, color: str = "black") -> str | rule_t:
|
86
86
|
""""""
|
87
87
|
if self.is_rich:
|
88
88
|
if text is None:
|
89
89
|
return rule_t(style=color)
|
90
90
|
return rule_t(title=text_t(text, style=f"bold {color}"), style=color)
|
91
91
|
|
92
|
-
return base_t.Rule(self, text, color=color)
|
92
|
+
return base_t.Rule(self, text=text, color=color)
|
93
93
|
|
94
94
|
def emit(self, record: l.LogRecord, /) -> None:
|
95
95
|
""""""
|
@@ -131,7 +131,7 @@ class generic_handler_t(base_t):
|
|
131
131
|
else:
|
132
132
|
message = self.MessageFromRecord(record)[0]
|
133
133
|
|
134
|
-
self.
|
134
|
+
self.EmitMessage(message)
|
135
135
|
self._log_parity = not self._log_parity
|
136
136
|
|
137
137
|
|
logger_36/constant/record.py
CHANGED
@@ -4,8 +4,11 @@ Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2023
|
|
4
4
|
SEE COPYRIGHT NOTICE BELOW
|
5
5
|
"""
|
6
6
|
|
7
|
-
|
7
|
+
INTERNAL_INFO_ATTR = "internal_info"
|
8
8
|
SHOW_WHERE_ATTR = "should_show_where"
|
9
|
+
SHOW_W_RULE_ATTR = "should_show_w_rule"
|
10
|
+
WHEN_OR_ELAPSED_ATTR = "when_or_elapsed"
|
11
|
+
WHERE_ATTR = "where"
|
9
12
|
|
10
13
|
"""
|
11
14
|
COPYRIGHT NOTICE
|
logger_36/type/handler.py
CHANGED
@@ -16,7 +16,7 @@ from logger_36.config.message import (
|
|
16
16
|
WHERE_SEPARATOR,
|
17
17
|
)
|
18
18
|
from logger_36.constant.message import NEXT_LINE_PROLOGUE
|
19
|
-
from logger_36.constant.record import SHOW_W_RULE_ATTR
|
19
|
+
from logger_36.constant.record import SHOW_W_RULE_ATTR, WHEN_OR_ELAPSED_ATTR, WHERE_ATTR
|
20
20
|
from logger_36.constant.rule import (
|
21
21
|
DEFAULT_RULE,
|
22
22
|
DEFAULT_RULE_LENGTH,
|
@@ -66,7 +66,7 @@ class extension_t:
|
|
66
66
|
message = self.PreProcessedMessage(message)
|
67
67
|
|
68
68
|
if hasattr(record, SHOW_W_RULE_ATTR):
|
69
|
-
return self.Rule(message, color=rule_color), False
|
69
|
+
return self.Rule(text=message, color=rule_color), False
|
70
70
|
|
71
71
|
if (self.message_width <= 0) or (message.__len__() <= self.message_width):
|
72
72
|
if "\n" in message:
|
@@ -78,11 +78,11 @@ class extension_t:
|
|
78
78
|
lines = WrappedLines([message], self.message_width)
|
79
79
|
message = NEXT_LINE_PROLOGUE.join(lines)
|
80
80
|
|
81
|
-
when_or_elapsed = getattr(record,
|
81
|
+
when_or_elapsed = getattr(record, WHEN_OR_ELAPSED_ATTR, None)
|
82
82
|
if when_or_elapsed is None:
|
83
83
|
return message, True
|
84
84
|
|
85
|
-
if (where := getattr(record,
|
85
|
+
if (where := getattr(record, WHERE_ATTR, None)) is None:
|
86
86
|
where = ""
|
87
87
|
else:
|
88
88
|
where = f"{NEXT_LINE_PROLOGUE}{WHERE_SEPARATOR} {where}"
|
@@ -93,7 +93,7 @@ class extension_t:
|
|
93
93
|
f"{MESSAGE_MARKER} {message}{where}"
|
94
94
|
), True
|
95
95
|
|
96
|
-
def Rule(self, text: str | None
|
96
|
+
def Rule(self, /, *, text: str | None = None, color: str = "black") -> str | h.Any:
|
97
97
|
"""
|
98
98
|
Return type hint h.Any: For Rich, for example.
|
99
99
|
"""
|
@@ -113,13 +113,13 @@ class extension_t:
|
|
113
113
|
|
114
114
|
return f"{half_rule} {text} {half_rule}"
|
115
115
|
|
116
|
-
def
|
116
|
+
def EmitMessage(self, message: str, /) -> None:
|
117
117
|
""""""
|
118
118
|
raise NotImplementedError
|
119
119
|
|
120
120
|
def EmitRule(self, /, *, text: str | None = None, color: str = "black") -> None:
|
121
121
|
""""""
|
122
|
-
self.
|
122
|
+
self.EmitMessage(self.Rule(text=text, color=color))
|
123
123
|
|
124
124
|
|
125
125
|
class handler_t(l.Handler, extension_t):
|
logger_36/type/logger.py
CHANGED
@@ -19,7 +19,12 @@ from os import sep as FOLDER_SEPARATOR
|
|
19
19
|
from pathlib import Path as path_t
|
20
20
|
from traceback import TracebackException as traceback_t
|
21
21
|
|
22
|
-
from logger_36.catalog.config.optional import
|
22
|
+
from logger_36.catalog.config.optional import (
|
23
|
+
MEMORY_MEASURE_ERROR,
|
24
|
+
MEMORY_MEASURE_IS_AVAILABLE,
|
25
|
+
MISSING_RICH_MESSAGE,
|
26
|
+
RICH_IS_AVAILABLE,
|
27
|
+
)
|
23
28
|
from logger_36.catalog.handler.console import console_handler_t
|
24
29
|
from logger_36.catalog.handler.file import file_handler_t
|
25
30
|
from logger_36.config.issue import ISSUE_CONTEXT_END, ISSUE_CONTEXT_SEPARATOR
|
@@ -30,17 +35,19 @@ from logger_36.config.message import (
|
|
30
35
|
TIME_FORMAT,
|
31
36
|
WHERE_SEPARATOR,
|
32
37
|
)
|
33
|
-
from logger_36.constant.error import MEMORY_MEASURE_ERROR
|
34
38
|
from logger_36.constant.generic import NOT_PASSED
|
35
39
|
from logger_36.constant.issue import ISSUE_LEVEL_SEPARATOR, ORDER, order_h
|
36
40
|
from logger_36.constant.logger import WARNING_LOGGER_NAME, WARNING_TYPE_COMPILED_PATTERN
|
37
41
|
from logger_36.constant.memory import UNKNOWN_MEMORY_USAGE
|
38
42
|
from logger_36.constant.message import LINE_INDENT, TIME_LENGTH_m_1, expected_op_h
|
39
43
|
from logger_36.constant.path import PROJECT_FILE_RELATIVE, USER_FOLDER
|
40
|
-
from logger_36.constant.record import
|
44
|
+
from logger_36.constant.record import (
|
45
|
+
INTERNAL_INFO_ATTR,
|
46
|
+
SHOW_W_RULE_ATTR,
|
47
|
+
SHOW_WHERE_ATTR,
|
48
|
+
)
|
41
49
|
from logger_36.task.format.message import MessageWithActualExpected
|
42
50
|
from logger_36.task.measure.chronos import ElapsedTime
|
43
|
-
from logger_36.task.measure.memory import CanCheckUsage as CanCheckMemoryUsage
|
44
51
|
from logger_36.task.measure.memory import CurrentUsage as CurrentMemoryUsage
|
45
52
|
from logger_36.type.handler import any_handler_t as base_handler_t
|
46
53
|
from logger_36.type.handler import extension_t as handler_extension_t
|
@@ -61,7 +68,6 @@ logger_handle_h = logger_handle_raw_h | logger_handle_with_self_h
|
|
61
68
|
|
62
69
|
_DATE_TIME_ORIGIN = date_time_t.fromtimestamp(1970, None)
|
63
70
|
_DATE_ORIGIN = _DATE_TIME_ORIGIN.date()
|
64
|
-
_MEMORY_MEASURE_ERROR = MEMORY_MEASURE_ERROR
|
65
71
|
|
66
72
|
|
67
73
|
@d.dataclass(slots=True, repr=False, eq=False)
|
@@ -74,16 +80,17 @@ class logger_t(base_t):
|
|
74
80
|
will be missed by an early call of ToggleLogInterceptions. Therefore, passing True
|
75
81
|
for activate_log_interceptions only sets _should_activate_log_interceptions to True,
|
76
82
|
which is later checked in AddHandler to effectively call ToggleLogInterceptions if
|
77
|
-
|
83
|
+
_warming_up is False (which normally indicates that the handler about to
|
78
84
|
be added is the last one).
|
79
85
|
|
80
|
-
|
86
|
+
_warming_up: Must not be False until at least one handler has been added.
|
81
87
|
"""
|
82
88
|
|
83
89
|
should_record_messages: bool = False
|
84
|
-
|
90
|
+
should_monitor_memory_usage: bool = False
|
85
91
|
exit_on_error: bool = False # Implies exit_on_critical.
|
86
92
|
exit_on_critical: bool = False
|
93
|
+
verbose: bool = False
|
87
94
|
|
88
95
|
events: dict[int, int] = d.field(init=False, default_factory=dict)
|
89
96
|
recorded: list[tuple[int, str]] = d.field(init=False, default_factory=list)
|
@@ -98,11 +105,13 @@ class logger_t(base_t):
|
|
98
105
|
init=False, default_factory=dict
|
99
106
|
)
|
100
107
|
intercepts_exceptions: bool = d.field(init=False, default=False)
|
101
|
-
_should_hold_messages: bool = d.field(init=False, default=True)
|
102
|
-
_should_activate_log_interceptions: bool = d.field(init=False, default=False)
|
103
|
-
_on_hold: list[l.LogRecord] = d.field(init=False, default_factory=list)
|
104
108
|
_recording_handler: handler_extension_t | None = d.field(init=False, default=None)
|
105
109
|
|
110
|
+
# Used only until the last handler is added (see AddHandler).
|
111
|
+
_should_activate_log_interceptions: bool = d.field(init=False, default=False)
|
112
|
+
_warming_up: bool = d.field(init=False, default=True)
|
113
|
+
_on_hold: list[l.LogRecord] | None = d.field(init=False, default_factory=list)
|
114
|
+
|
106
115
|
name_: d.InitVar[str | None] = None
|
107
116
|
level_: d.InitVar[int] = l.NOTSET
|
108
117
|
activate_wrn_interceptions: d.InitVar[bool] = True
|
@@ -156,11 +165,10 @@ class logger_t(base_t):
|
|
156
165
|
activate_exc_interceptions: bool,
|
157
166
|
) -> None:
|
158
167
|
""""""
|
159
|
-
global _MEMORY_MEASURE_ERROR
|
160
|
-
|
161
168
|
if name_ is None:
|
162
169
|
name_ = f"{type(self).__name__}:{hex(id(self))[2:]}"
|
163
170
|
|
171
|
+
self.handle = self._HandleWarmUp
|
164
172
|
base_t.__init__(self, name_)
|
165
173
|
self.setLevel(level_)
|
166
174
|
self.propagate = False # Part of base_t.
|
@@ -174,7 +182,10 @@ class logger_t(base_t):
|
|
174
182
|
if self.should_record_messages:
|
175
183
|
self.ActivateMessageRecording()
|
176
184
|
|
177
|
-
self.info(
|
185
|
+
self.info(
|
186
|
+
f'New logger "{self.name}" for "{PROJECT_FILE_RELATIVE}"',
|
187
|
+
extra={INTERNAL_INFO_ATTR: True},
|
188
|
+
)
|
178
189
|
|
179
190
|
if activate_wrn_interceptions:
|
180
191
|
self.ToggleWarningInterceptions(True)
|
@@ -183,14 +194,32 @@ class logger_t(base_t):
|
|
183
194
|
if activate_exc_interceptions:
|
184
195
|
self.ToggleExceptionInterceptions(True)
|
185
196
|
|
186
|
-
if self.
|
187
|
-
self.
|
188
|
-
if _MEMORY_MEASURE_ERROR is not None:
|
189
|
-
s.__stderr__.write(_MEMORY_MEASURE_ERROR + "\n")
|
190
|
-
_MEMORY_MEASURE_ERROR = None
|
197
|
+
if self.should_monitor_memory_usage:
|
198
|
+
self.ActivateMemoryUsageMonitoring()
|
191
199
|
|
192
|
-
def
|
200
|
+
def _HandleWarmUp(self, record: l.LogRecord, /) -> None:
|
193
201
|
""""""
|
202
|
+
now = ElapsedTime(should_return_now=True)[1]
|
203
|
+
if (date := now.date()) != self.last_message_date:
|
204
|
+
self._AcknowledgeDateChange(date)
|
205
|
+
|
206
|
+
# When.
|
207
|
+
record.when_or_elapsed = (TIME_LENGTH_m_1 + 1) * "."
|
208
|
+
# Where.
|
209
|
+
if record.levelno != l.INFO:
|
210
|
+
_ = _RecordLocation(record, True)
|
211
|
+
# What.
|
212
|
+
if not isinstance(record.msg, str):
|
213
|
+
record.msg = str(record.msg)
|
214
|
+
|
215
|
+
self._on_hold.append(record)
|
216
|
+
|
217
|
+
def _HandleRoutine(self, record: l.LogRecord, /) -> None:
|
218
|
+
""""""
|
219
|
+
is_internal_info = getattr(record, INTERNAL_INFO_ATTR, False)
|
220
|
+
if is_internal_info and not self.verbose:
|
221
|
+
return
|
222
|
+
|
194
223
|
elapsed_time, now = ElapsedTime(should_return_now=True)
|
195
224
|
|
196
225
|
if (date := now.date()) != self.last_message_date:
|
@@ -206,19 +235,8 @@ class logger_t(base_t):
|
|
206
235
|
|
207
236
|
# Where.
|
208
237
|
should_show_where = getattr(record, SHOW_WHERE_ATTR, record.levelno != l.INFO)
|
209
|
-
if should_show_where or self.
|
210
|
-
|
211
|
-
for path in s.path:
|
212
|
-
if module.is_relative_to(path):
|
213
|
-
module = module.relative_to(path).with_suffix("")
|
214
|
-
module = str(module).replace(FOLDER_SEPARATOR, ".")
|
215
|
-
break
|
216
|
-
else:
|
217
|
-
if module.is_relative_to(USER_FOLDER):
|
218
|
-
module = module.relative_to(USER_FOLDER)
|
219
|
-
where = f"{module}:{record.funcName}:{record.lineno}"
|
220
|
-
if should_show_where:
|
221
|
-
record.where = where
|
238
|
+
if should_show_where or self.should_monitor_memory_usage:
|
239
|
+
where = _RecordLocation(record, should_show_where)
|
222
240
|
else:
|
223
241
|
where = None
|
224
242
|
|
@@ -226,13 +244,9 @@ class logger_t(base_t):
|
|
226
244
|
if not isinstance(record.msg, str):
|
227
245
|
record.msg = str(record.msg)
|
228
246
|
|
229
|
-
|
230
|
-
self._on_hold.append(record)
|
231
|
-
else:
|
232
|
-
self._HandleRecord(record)
|
233
|
-
self.events[record.levelno] += 1
|
247
|
+
self._HandleRaw(record)
|
234
248
|
|
235
|
-
if self.
|
249
|
+
if self.should_monitor_memory_usage:
|
236
250
|
self.memory_usages.append((where, CurrentMemoryUsage()))
|
237
251
|
|
238
252
|
if (self.exit_on_critical and (record.levelno is l.CRITICAL)) or (
|
@@ -242,12 +256,28 @@ class logger_t(base_t):
|
|
242
256
|
# __post_init__ set self.exit_on_critical if self.exit_on_error.
|
243
257
|
s.exit(1)
|
244
258
|
|
245
|
-
def
|
259
|
+
def _HandleRaw(self, record: l.LogRecord, /) -> None:
|
246
260
|
""""""
|
261
|
+
if self.should_record_messages:
|
262
|
+
message = self._recording_handler.MessageFromRecord(record)[0]
|
263
|
+
self.recorded.append((record.levelno, message))
|
264
|
+
|
265
|
+
base_t.handle(self, record)
|
266
|
+
self.events[record.levelno] += 1
|
267
|
+
|
268
|
+
def _FlushRecordsOnHold(self) -> None:
|
269
|
+
"""
|
270
|
+
should_record_messages and verbose must have been set by now.
|
271
|
+
"""
|
247
272
|
for held in self._on_hold:
|
248
|
-
self.
|
273
|
+
if self.verbose or not getattr(held, INTERNAL_INFO_ATTR, False):
|
274
|
+
self._HandleRaw(held)
|
249
275
|
|
250
276
|
self._on_hold.clear()
|
277
|
+
self._on_hold = None
|
278
|
+
self._warming_up = False
|
279
|
+
|
280
|
+
self.handle = self._HandleRoutine
|
251
281
|
|
252
282
|
def _AcknowledgeDateChange(self, date: date_t, /) -> None:
|
253
283
|
""""""
|
@@ -262,24 +292,32 @@ class logger_t(base_t):
|
|
262
292
|
}
|
263
293
|
)
|
264
294
|
|
265
|
-
if self.
|
295
|
+
if self._warming_up:
|
266
296
|
self._on_hold.append(record)
|
267
297
|
else:
|
268
|
-
self.
|
269
|
-
|
270
|
-
def _HandleRecord(self, record: l.LogRecord, /) -> None:
|
271
|
-
""""""
|
272
|
-
if self.should_record_messages:
|
273
|
-
message = self._recording_handler.MessageFromRecord(record)[0]
|
274
|
-
self.recorded.append((record.levelno, message))
|
275
|
-
|
276
|
-
base_t.handle(self, record)
|
298
|
+
self._HandleRaw(record)
|
277
299
|
|
278
300
|
def ActivateMessageRecording(self) -> None:
|
279
301
|
""""""
|
280
302
|
self._recording_handler = handler_extension_t("recording_handler", 0, None)
|
281
303
|
self.should_record_messages = True # Useless if called from __post_init__.
|
282
|
-
self.info(
|
304
|
+
self.info(
|
305
|
+
f'Message recording activated for logger "{self.name}"',
|
306
|
+
extra={INTERNAL_INFO_ATTR: True},
|
307
|
+
)
|
308
|
+
|
309
|
+
def ActivateMemoryUsageMonitoring(self) -> None:
|
310
|
+
""""""
|
311
|
+
if MEMORY_MEASURE_IS_AVAILABLE:
|
312
|
+
# Useless if called from __post_init__.
|
313
|
+
self.should_monitor_memory_usage = True
|
314
|
+
self.info(
|
315
|
+
f'Memory usage monitoring activated for logger "{self.name}"',
|
316
|
+
extra={INTERNAL_INFO_ATTR: True},
|
317
|
+
)
|
318
|
+
else:
|
319
|
+
self.should_monitor_memory_usage = False
|
320
|
+
self.error(MEMORY_MEASURE_ERROR)
|
283
321
|
|
284
322
|
def ResetEventCounts(self) -> None:
|
285
323
|
""""""
|
@@ -297,7 +335,7 @@ class logger_t(base_t):
|
|
297
335
|
logger.handle = t.MethodType(_HandleForWarnings(self), logger)
|
298
336
|
|
299
337
|
l.captureWarnings(True)
|
300
|
-
self.info("Warning Interception: ON")
|
338
|
+
self.info("Warning Interception: ON", extra={INTERNAL_INFO_ATTR: True})
|
301
339
|
else:
|
302
340
|
if not self.intercepts_warnings:
|
303
341
|
return
|
@@ -307,7 +345,7 @@ class logger_t(base_t):
|
|
307
345
|
self.intercepted_wrn_handle = None
|
308
346
|
|
309
347
|
l.captureWarnings(False)
|
310
|
-
self.info("Warning Interception: OFF")
|
348
|
+
self.info("Warning Interception: OFF", extra={INTERNAL_INFO_ATTR: True})
|
311
349
|
|
312
350
|
def ToggleLogInterceptions(self, state: bool, /) -> None:
|
313
351
|
""""""
|
@@ -331,7 +369,10 @@ class logger_t(base_t):
|
|
331
369
|
intercepted = sorted(self.intercepted_log_handles.keys())
|
332
370
|
if intercepted.__len__() > 0:
|
333
371
|
as_str = ", ".join(intercepted)
|
334
|
-
self.info(
|
372
|
+
self.info(
|
373
|
+
f"Now Intercepting LOGs from: {as_str}",
|
374
|
+
extra={INTERNAL_INFO_ATTR: True},
|
375
|
+
)
|
335
376
|
else:
|
336
377
|
if not self.intercepts_logs:
|
337
378
|
return
|
@@ -340,7 +381,7 @@ class logger_t(base_t):
|
|
340
381
|
logger = l.getLogger(name)
|
341
382
|
logger.handle = handle
|
342
383
|
self.intercepted_log_handles.clear()
|
343
|
-
self.info("Log Interception: OFF")
|
384
|
+
self.info("Log Interception: OFF", extra={INTERNAL_INFO_ATTR: True})
|
344
385
|
|
345
386
|
def ToggleExceptionInterceptions(self, state: bool, /) -> None:
|
346
387
|
""""""
|
@@ -351,7 +392,7 @@ class logger_t(base_t):
|
|
351
392
|
s.excepthook = self.DealWithException
|
352
393
|
thrd.excepthook = self.DealWithExceptionInThread
|
353
394
|
self.intercepts_exceptions = True
|
354
|
-
self.info("Exception Interception: ON")
|
395
|
+
self.info("Exception Interception: ON", extra={INTERNAL_INFO_ATTR: True})
|
355
396
|
else:
|
356
397
|
if not self.intercepts_exceptions:
|
357
398
|
return
|
@@ -359,7 +400,7 @@ class logger_t(base_t):
|
|
359
400
|
s.excepthook = s.__excepthook__
|
360
401
|
thrd.excepthook = thrd.__excepthook__
|
361
402
|
self.intercepts_exceptions = False
|
362
|
-
self.info("Exception Interception: OFF")
|
403
|
+
self.info("Exception Interception: OFF", extra={INTERNAL_INFO_ATTR: True})
|
363
404
|
|
364
405
|
def AddHandler(
|
365
406
|
self,
|
@@ -372,7 +413,7 @@ class logger_t(base_t):
|
|
372
413
|
name: str | None = None,
|
373
414
|
level: int = l.INFO,
|
374
415
|
message_width: int = -1,
|
375
|
-
|
416
|
+
this_is_last_handler: bool = True,
|
376
417
|
**kwargs,
|
377
418
|
) -> None:
|
378
419
|
"""
|
@@ -380,12 +421,11 @@ class logger_t(base_t):
|
|
380
421
|
"""
|
381
422
|
should_flush_on_hold = False
|
382
423
|
new_handler_warning = ""
|
383
|
-
if self.
|
424
|
+
if self._warming_up and this_is_last_handler:
|
384
425
|
if self._should_activate_log_interceptions:
|
385
426
|
self.ToggleLogInterceptions(True)
|
386
427
|
self._should_activate_log_interceptions = False
|
387
428
|
|
388
|
-
self._should_hold_messages = False
|
389
429
|
should_flush_on_hold = True
|
390
430
|
new_handler_warning = "\n(Handlers added from now on will miss above logs.)"
|
391
431
|
|
@@ -397,32 +437,33 @@ class logger_t(base_t):
|
|
397
437
|
handler = handler_t_or_handler
|
398
438
|
base_t.addHandler(self, handler)
|
399
439
|
|
440
|
+
if self.verbose:
|
441
|
+
path = getattr(handler, "baseFilename", "")
|
442
|
+
if isinstance(path, path_t) or (path.__len__() > 0):
|
443
|
+
path = f"\nPath: {path}"
|
444
|
+
self.info(
|
445
|
+
f'New handler "{handler.name}" of type "{type(handler).__name__}" and '
|
446
|
+
f"level {handler.level}={l.getLevelName(handler.level)}{path}"
|
447
|
+
f"{new_handler_warning}",
|
448
|
+
extra={INTERNAL_INFO_ATTR: True},
|
449
|
+
)
|
450
|
+
|
400
451
|
# Wait until after the handler has been added to flush messages on hold.
|
401
452
|
if should_flush_on_hold:
|
402
453
|
self._FlushRecordsOnHold()
|
403
454
|
|
404
|
-
path = getattr(handler, "baseFilename", "")
|
405
|
-
if isinstance(path, path_t) or (path.__len__() > 0):
|
406
|
-
path = f"\nPath: {path}"
|
407
|
-
self.info(
|
408
|
-
f'New handler "{handler.name}" of type "{type(handler).__name__}" and '
|
409
|
-
f"level {handler.level}={l.getLevelName(handler.level)}{path}"
|
410
|
-
f"{new_handler_warning}"
|
411
|
-
)
|
412
|
-
|
413
455
|
def MakeMonochrome(self) -> None:
|
414
456
|
""""""
|
415
457
|
self.AddHandler(console_handler_t)
|
416
458
|
|
417
459
|
def MakeRich(self, *, alternating_logs: int = 0) -> None:
|
418
460
|
""""""
|
419
|
-
if
|
420
|
-
s.__stderr__.write(MISSING_RICH_MESSAGE + "\n")
|
421
|
-
|
422
|
-
if console_rich_handler_t is console_handler_t:
|
423
|
-
handler_kwargs = {}
|
424
|
-
else:
|
461
|
+
if RICH_IS_AVAILABLE:
|
425
462
|
handler_kwargs = {"alternating_logs": alternating_logs}
|
463
|
+
else:
|
464
|
+
handler_kwargs = {}
|
465
|
+
self.error(MISSING_RICH_MESSAGE)
|
466
|
+
|
426
467
|
self.AddHandler(console_rich_handler_t, **handler_kwargs)
|
427
468
|
|
428
469
|
def MakePermanent(self, path: str | path_t, /) -> None:
|
@@ -509,8 +550,11 @@ class logger_t(base_t):
|
|
509
550
|
message = text.indent(message, LINE_INDENT)
|
510
551
|
|
511
552
|
for handler in self.handlers:
|
512
|
-
|
513
|
-
|
553
|
+
EmitMessage = getattr(
|
554
|
+
handler, handler_extension_t.EmitMessage.__name__, None
|
555
|
+
)
|
556
|
+
if EmitMessage is not None:
|
557
|
+
EmitMessage(message)
|
514
558
|
|
515
559
|
info_raw = LogAsIs # To follow the convention of the logging methods info, error...
|
516
560
|
|
@@ -519,7 +563,8 @@ class logger_t(base_t):
|
|
519
563
|
) -> None:
|
520
564
|
""""""
|
521
565
|
for handler in self.handlers:
|
522
|
-
|
566
|
+
EmitRule = getattr(handler, handler_extension_t.EmitRule.__name__, None)
|
567
|
+
if EmitRule is not None:
|
523
568
|
EmitRule(text=message, color=color)
|
524
569
|
|
525
570
|
def AddContextLevel(self, new_level: str, /) -> None:
|
@@ -647,6 +692,26 @@ class logger_t(base_t):
|
|
647
692
|
return False
|
648
693
|
|
649
694
|
|
695
|
+
def _RecordLocation(record: l.LogRecord, should_also_store: bool, /) -> str:
|
696
|
+
""""""
|
697
|
+
module = path_t(record.pathname)
|
698
|
+
for path in s.path:
|
699
|
+
if module.is_relative_to(path):
|
700
|
+
module = module.relative_to(path).with_suffix("")
|
701
|
+
module = str(module).replace(FOLDER_SEPARATOR, ".")
|
702
|
+
break
|
703
|
+
else:
|
704
|
+
if module.is_relative_to(USER_FOLDER):
|
705
|
+
module = module.relative_to(USER_FOLDER)
|
706
|
+
|
707
|
+
output = f"{module}:{record.funcName}:{record.lineno}"
|
708
|
+
|
709
|
+
if should_also_store:
|
710
|
+
record.where = output
|
711
|
+
|
712
|
+
return output
|
713
|
+
|
714
|
+
|
650
715
|
def _HandleForWarnings(interceptor: base_t, /) -> logger_handle_h:
|
651
716
|
""""""
|
652
717
|
|
logger_36/version.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
logger_36/__init__.py,sha256=mK6AD0eWI2Sk42oxleTvsxzYJ28FbHK5WNkpLgAhnNE,2129
|
2
|
-
logger_36/version.py,sha256=
|
2
|
+
logger_36/version.py,sha256=WM8W-3pzA_JWd1DQWpdL-uJTAxV5u8_nbyWIlGaizjg,1680
|
3
3
|
logger_36/api/content.py,sha256=DuT4UX4r_1DTXzuuRD-tvsTZk5X-Nj11loBKhuWOMw0,1791
|
4
4
|
logger_36/api/gpu.py,sha256=NNs1IvQ7bh8Dppm8O8K2YLWbm4rogc3Ie_-D6xzkX3g,1726
|
5
5
|
logger_36/api/memory.py,sha256=vOY4cTTrC3u7L0OrKXdPNlsCahYjCrY4h7iqpGZv9kU,2217
|
@@ -8,11 +8,11 @@ logger_36/api/system.py,sha256=h-3GfhZPwawv0UKBWKkT1LzxSCZwpA2VIsy03lLYi6w,1725
|
|
8
8
|
logger_36/api/time.py,sha256=JG0vgzPSRZ7UWQyoihnVu4sjPC-okFIKA3ZyNh2GaZo,1798
|
9
9
|
logger_36/api/type.py,sha256=eLZ2yuH-sYeh4Z2KnAwTRJEbmkmgzBPMncdqXfFUTG8,1760
|
10
10
|
logger_36/catalog/config/console_rich.py,sha256=t9p9-AkSgPiLAsm1evAdbz77g7JcVLePhUJ1FzNi3cY,2330
|
11
|
-
logger_36/catalog/config/optional.py,sha256=
|
12
|
-
logger_36/catalog/handler/console.py,sha256=
|
13
|
-
logger_36/catalog/handler/console_rich.py,sha256=
|
14
|
-
logger_36/catalog/handler/file.py,sha256=
|
15
|
-
logger_36/catalog/handler/generic.py,sha256=
|
11
|
+
logger_36/catalog/config/optional.py,sha256=8d8HdpE07gHfsdoL8mVAlRlh9AgLcb4z7I7h6ob7CfU,2174
|
12
|
+
logger_36/catalog/handler/console.py,sha256=YEQN8fw7ra9w-5sJACNC4pktv9einm5ASP9TncU8TQo,2311
|
13
|
+
logger_36/catalog/handler/console_rich.py,sha256=gPpq8ij1ZFTXaLgISaCTXDDwv7uWPivLeq2ttpiuKlk,6190
|
14
|
+
logger_36/catalog/handler/file.py,sha256=yg8GnsV6AmDsx1R5iZlsK-5idqD733gc09Syl02TG7Y,2458
|
15
|
+
logger_36/catalog/handler/generic.py,sha256=L8mLc-iQlBWKBqEN3-wIKy2yk_TVgqIWYn_P1hXDsQA,6361
|
16
16
|
logger_36/catalog/logger/chronos.py,sha256=S4m9TMPQy_Ju500mpE1jNzu2gZG-QKdVuvX9RVRKHR8,1911
|
17
17
|
logger_36/catalog/logger/gpu.py,sha256=Py5YY0nD_pqJzJsEKQYoOGHcPqyNVJ3J2noOS3hDL6g,2890
|
18
18
|
logger_36/catalog/logger/memory.py,sha256=J0ZGKO7j1FZA_aDGxpABtvzDy1RjCDiDmWYh4U98fEI,4253
|
@@ -29,7 +29,7 @@ logger_36/constant/logger.py,sha256=ZQYX9JiPsoivwRgYNtdEqRKCagSKD88lRqvxP8MX1ZE,
|
|
29
29
|
logger_36/constant/memory.py,sha256=Q_E5tTWa-cGaNwrE_xmKa3BxQG6oJO6DHczrxc_M4sE,1817
|
30
30
|
logger_36/constant/message.py,sha256=YJOEzdI0ZjUOdHo3CsiS56FVPhrfNoQYvXuUkprH61g,2312
|
31
31
|
logger_36/constant/path.py,sha256=OfLh70Jyc8po9Ls34nQh_bRr3PXyQ3kF9ciR9QPhiqI,2213
|
32
|
-
logger_36/constant/record.py,sha256=
|
32
|
+
logger_36/constant/record.py,sha256=IGWnKA4TGv1oU6ezzNrGocZlB7Ie7nTr4l3IOtwdWOg,1833
|
33
33
|
logger_36/constant/rule.py,sha256=tBKQgPTt6G_p5eInDdWoEEAvQFz4WMSt5THsS5jvk14,1779
|
34
34
|
logger_36/constant/system.py,sha256=pLlLXG5sepQlSUOo3TphaGrHg8xzJBp-GxpL2NPP47k,1904
|
35
35
|
logger_36/extension/html_.py,sha256=W9SyiYsaaYHUrHLGAAN2wiJGXUlwOBJ5gzdjmEcnF18,3342
|
@@ -42,11 +42,11 @@ logger_36/task/format/memory.py,sha256=J1Oy3jw8wjSp2kuiRUm_VFpzXOHX2FOc7nuRrCyrs
|
|
42
42
|
logger_36/task/format/message.py,sha256=Rm6zymVEEGcgKfmxMPXP7q3PtwZJKlXGhqZ5tnvlwxA,3502
|
43
43
|
logger_36/task/measure/chronos.py,sha256=7ijMZgP4EP18HbLV2yCxpNpRS9724Wyk523f-nkbhUM,2529
|
44
44
|
logger_36/task/measure/memory.py,sha256=kkPHEIUTUhkCOLrAt01eLJLnsnkl0nFPNhFZdIB_JAw,1991
|
45
|
-
logger_36/type/handler.py,sha256=
|
45
|
+
logger_36/type/handler.py,sha256=4LCFZzI4OEH6lVBrBQ09ZIvF0nq-_j7OOVnujBDyDWA,6665
|
46
46
|
logger_36/type/issue.py,sha256=QHAYf7QgrjJUtF2D46z6X630qTgeP_0FE5hIwf54RsE,2688
|
47
|
-
logger_36/type/logger.py,sha256
|
47
|
+
logger_36/type/logger.py,sha256=b2F21M5z1hwPdDsyHgBIlC06X9-_7zsjqyGEsVaIJgM,27536
|
48
48
|
logger_36/type/loggers.py,sha256=7EX7Sg_RlduBjdfFlNZmUfNeDloH1xU30Rdkg_-rXh8,3172
|
49
|
-
logger_36-2025.
|
50
|
-
logger_36-2025.
|
51
|
-
logger_36-2025.
|
52
|
-
logger_36-2025.
|
49
|
+
logger_36-2025.22.dist-info/METADATA,sha256=xcPkxJFWNYEIXgspK2VCcU4LbsME8hlmFQjASmR-3KM,6529
|
50
|
+
logger_36-2025.22.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
51
|
+
logger_36-2025.22.dist-info/top_level.txt,sha256=sM95BTMWmslEEgR_1pzwZsOeSp8C_QBiu8ImbFr0XLc,10
|
52
|
+
logger_36-2025.22.dist-info/RECORD,,
|
File without changes
|
File without changes
|