logger-36 2025.13__py3-none-any.whl → 2025.14__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/handler/console.py +8 -13
- logger_36/catalog/handler/console_rich.py +53 -35
- logger_36/catalog/handler/file.py +8 -13
- logger_36/catalog/handler/generic.py +61 -41
- logger_36/config/message.py +1 -0
- logger_36/constant/html.py +70 -0
- logger_36/task/format/message.py +60 -1
- logger_36/task/format/rule.py +3 -2
- logger_36/task/storage.py +29 -8
- logger_36/type/handler.py +24 -9
- logger_36/type/logger.py +44 -30
- logger_36/type/message.py +20 -51
- logger_36/version.py +1 -1
- {logger_36-2025.13.dist-info → logger_36-2025.14.dist-info}/METADATA +1 -1
- {logger_36-2025.13.dist-info → logger_36-2025.14.dist-info}/RECORD +17 -16
- {logger_36-2025.13.dist-info → logger_36-2025.14.dist-info}/WHEEL +0 -0
- {logger_36-2025.13.dist-info → logger_36-2025.14.dist-info}/top_level.txt +0 -0
@@ -8,7 +8,6 @@ import logging as l
|
|
8
8
|
import sys as s
|
9
9
|
import typing as h
|
10
10
|
|
11
|
-
from logger_36.constant.record import SHOW_W_RULE_ATTR
|
12
11
|
from logger_36.task.format.rule import RuleAsText
|
13
12
|
from logger_36.type.handler import handler_t as base_t
|
14
13
|
|
@@ -26,29 +25,25 @@ class console_handler_t(base_t):
|
|
26
25
|
message_width: int = -1,
|
27
26
|
level: int = l.NOTSET,
|
28
27
|
formatter: l.Formatter | None = None,
|
29
|
-
**
|
28
|
+
**_,
|
30
29
|
) -> h.Self:
|
31
30
|
""""""
|
32
31
|
return cls(name, should_store_memory_usage, message_width, level, formatter)
|
33
32
|
|
34
33
|
def emit(self, record: l.LogRecord, /) -> None:
|
35
34
|
""""""
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
s.__stdout__.write(message + "\n")
|
35
|
+
message = self.MessageFromRecord(
|
36
|
+
record, RuleAsText, line_width=self.message_width
|
37
|
+
)
|
38
|
+
s.__stdout__.write(message[0] + "\n")
|
41
39
|
|
42
40
|
def LogAsIs(self, message: str, /) -> None:
|
43
|
-
"""
|
44
|
-
See documentation of
|
45
|
-
logger_36.catalog.handler.generic.generic_handler_t.LogAsIs.
|
46
|
-
"""
|
41
|
+
""""""
|
47
42
|
s.__stdout__.write(message + "\n")
|
48
43
|
|
49
|
-
def DisplayRule(self, /, *, text: str | None = None, color: str = "
|
44
|
+
def DisplayRule(self, /, *, text: str | None = None, color: str = "black") -> None:
|
50
45
|
""""""
|
51
|
-
self.LogAsIs(RuleAsText(text))
|
46
|
+
self.LogAsIs(RuleAsText(text, None))
|
52
47
|
|
53
48
|
|
54
49
|
"""
|
@@ -25,7 +25,6 @@ from logger_36.catalog.config.console_rich import (
|
|
25
25
|
)
|
26
26
|
from logger_36.config.message import ACTUAL_PATTERNS, EXPECTED_PATTERNS, WHERE_SEPARATOR
|
27
27
|
from logger_36.constant.message import CONTEXT_LENGTH
|
28
|
-
from logger_36.constant.record import SHOW_W_RULE_ATTR
|
29
28
|
from logger_36.task.format.rule import Rule
|
30
29
|
from logger_36.type.handler import handler_t as base_t
|
31
30
|
|
@@ -53,33 +52,36 @@ class console_rich_handler_t(base_t):
|
|
53
52
|
|
54
53
|
kind: h.ClassVar[str] = "c"
|
55
54
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
formatter: l.Formatter | None = None,
|
66
|
-
**kwargs,
|
67
|
-
) -> h.Self:
|
55
|
+
def __init__(
|
56
|
+
self,
|
57
|
+
name: str | None,
|
58
|
+
should_store_memory_usage: bool,
|
59
|
+
message_width: int,
|
60
|
+
level: int,
|
61
|
+
formatter: l.Formatter | None,
|
62
|
+
kwargs,
|
63
|
+
) -> None:
|
68
64
|
""""""
|
69
65
|
alternating_logs = kwargs.pop("alternating_logs", 0)
|
70
66
|
should_install_traceback = kwargs.pop("should_install_traceback", False)
|
71
67
|
|
72
68
|
assert alternating_logs in (0, 1, 2)
|
73
69
|
|
74
|
-
|
70
|
+
base_t.__init__(
|
71
|
+
self,
|
72
|
+
name,
|
73
|
+
should_store_memory_usage,
|
74
|
+
message_width,
|
75
|
+
level,
|
76
|
+
formatter,
|
77
|
+
kwargs,
|
78
|
+
)
|
75
79
|
|
76
|
-
|
77
|
-
|
78
|
-
|
80
|
+
self.console = None # console_t | None.
|
81
|
+
self.alternating_logs = alternating_logs
|
82
|
+
self._log_parity = False
|
79
83
|
|
80
|
-
|
81
|
-
|
82
|
-
return output
|
84
|
+
self.__post_init_local__(should_install_traceback, **kwargs)
|
83
85
|
|
84
86
|
def __post_init_local__(self, should_install_traceback: bool, **kwargs) -> None:
|
85
87
|
""""""
|
@@ -97,32 +99,48 @@ class console_rich_handler_t(base_t):
|
|
97
99
|
traceback_kwargs["console"] = self.console
|
98
100
|
InstallTracebackHandler(**traceback_kwargs)
|
99
101
|
|
102
|
+
@classmethod
|
103
|
+
def New(
|
104
|
+
cls,
|
105
|
+
/,
|
106
|
+
*,
|
107
|
+
name: str | None = None,
|
108
|
+
should_store_memory_usage: bool = False,
|
109
|
+
message_width: int = -1,
|
110
|
+
level: int = l.NOTSET,
|
111
|
+
formatter: l.Formatter | None = None,
|
112
|
+
**kwargs,
|
113
|
+
) -> h.Self:
|
114
|
+
""""""
|
115
|
+
return cls(
|
116
|
+
name, should_store_memory_usage, message_width, level, formatter, kwargs
|
117
|
+
)
|
118
|
+
|
100
119
|
def emit(self, record: l.LogRecord, /) -> None:
|
101
120
|
""""""
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
121
|
+
message, is_not_a_rule = self.MessageFromRecord(
|
122
|
+
record,
|
123
|
+
Rule,
|
124
|
+
line_width=self.message_width,
|
125
|
+
color=DATE_TIME_COLOR,
|
126
|
+
PreProcessed=EscapedVersion,
|
127
|
+
)
|
128
|
+
if is_not_a_rule:
|
129
|
+
message = HighlightedVersion(
|
109
130
|
self.console,
|
110
131
|
message,
|
111
132
|
record.levelno,
|
112
133
|
self.alternating_logs,
|
113
|
-
self.
|
134
|
+
self._log_parity,
|
114
135
|
)
|
115
|
-
self.console.print(
|
116
|
-
self.
|
136
|
+
self.console.print(message, crop=False, overflow="ignore")
|
137
|
+
self._log_parity = not self._log_parity
|
117
138
|
|
118
139
|
def LogAsIs(self, message: str | renderable_t, /) -> None:
|
119
|
-
"""
|
120
|
-
See documentation of
|
121
|
-
logger_36.catalog.handler.generic.generic_handler_t.LogAsIs.
|
122
|
-
"""
|
140
|
+
""""""
|
123
141
|
self.console.print(message, crop=False, overflow="ignore")
|
124
142
|
|
125
|
-
def DisplayRule(self, /, *, text: str | None = None, color: str = "
|
143
|
+
def DisplayRule(self, /, *, text: str | None = None, color: str = "black") -> None:
|
126
144
|
""""""
|
127
145
|
self.LogAsIs(Rule(text, color))
|
128
146
|
|
@@ -8,7 +8,6 @@ import logging as l
|
|
8
8
|
import typing as h
|
9
9
|
from pathlib import Path as path_t
|
10
10
|
|
11
|
-
from logger_36.constant.record import SHOW_W_RULE_ATTR
|
12
11
|
from logger_36.task.format.rule import RuleAsText
|
13
12
|
from logger_36.type.handler import file_handler_t as base_t
|
14
13
|
|
@@ -27,7 +26,7 @@ class file_handler_t(base_t):
|
|
27
26
|
level: int = l.NOTSET,
|
28
27
|
formatter: l.Formatter | None = None,
|
29
28
|
path: str | path_t | None = None,
|
30
|
-
**
|
29
|
+
**_,
|
31
30
|
) -> h.Self:
|
32
31
|
""""""
|
33
32
|
return cls(
|
@@ -36,24 +35,20 @@ class file_handler_t(base_t):
|
|
36
35
|
|
37
36
|
def emit(self, record: l.LogRecord, /) -> None:
|
38
37
|
""""""
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
self.stream.write(message + "\n")
|
38
|
+
message = self.MessageFromRecord(
|
39
|
+
record, RuleAsText, line_width=self.message_width
|
40
|
+
)
|
41
|
+
self.stream.write(message[0] + "\n")
|
44
42
|
self.stream.flush()
|
45
43
|
|
46
44
|
def LogAsIs(self, message: str, /) -> None:
|
47
|
-
"""
|
48
|
-
See documentation of
|
49
|
-
logger_36.catalog.handler.generic.generic_handler_t.LogAsIs.
|
50
|
-
"""
|
45
|
+
""""""
|
51
46
|
self.stream.write(message + "\n")
|
52
47
|
self.stream.flush()
|
53
48
|
|
54
|
-
def DisplayRule(self, /, *, text: str | None = None, color: str = "
|
49
|
+
def DisplayRule(self, /, *, text: str | None = None, color: str = "black") -> None:
|
55
50
|
""""""
|
56
|
-
self.LogAsIs(RuleAsText(text))
|
51
|
+
self.LogAsIs(RuleAsText(text, None))
|
57
52
|
|
58
53
|
|
59
54
|
"""
|
@@ -22,8 +22,7 @@ else:
|
|
22
22
|
EscapedForRich
|
23
23
|
) = DEFAULT_TERMINAL_THEME = None
|
24
24
|
|
25
|
-
from logger_36.
|
26
|
-
from logger_36.task.format.rule import Rule, RuleAsText
|
25
|
+
from logger_36.task.format.rule import Rule, RuleAsText, rule_t
|
27
26
|
from logger_36.type.handler import handler_t as base_t
|
28
27
|
|
29
28
|
LogAsIs_h = h.Callable[[str | h.Any], None]
|
@@ -54,18 +53,15 @@ class generic_handler_t(base_t):
|
|
54
53
|
|
55
54
|
kind: h.ClassVar[str] = "g"
|
56
55
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
formatter: l.Formatter | None = None,
|
67
|
-
**kwargs,
|
68
|
-
) -> h.Self:
|
56
|
+
def __init__(
|
57
|
+
self,
|
58
|
+
name: str | None,
|
59
|
+
should_store_memory_usage: bool,
|
60
|
+
message_width: int,
|
61
|
+
level: int,
|
62
|
+
formatter: l.Formatter | None,
|
63
|
+
kwargs,
|
64
|
+
) -> None:
|
69
65
|
""""""
|
70
66
|
alternating_logs = kwargs.pop("alternating_logs", 0)
|
71
67
|
LogAsIs = kwargs.pop("LogAsIs", lambda _, indented=False: print(_))
|
@@ -73,18 +69,24 @@ class generic_handler_t(base_t):
|
|
73
69
|
|
74
70
|
assert alternating_logs in (0, 1, 2)
|
75
71
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
72
|
+
base_t.__init__(
|
73
|
+
self,
|
74
|
+
name,
|
75
|
+
should_store_memory_usage,
|
76
|
+
message_width,
|
77
|
+
level,
|
78
|
+
formatter,
|
79
|
+
kwargs,
|
80
|
+
)
|
81
|
+
|
82
|
+
self.LogAsIs = LogAsIs
|
83
|
+
self.DisplayRule = None # DisplayRule_p | None.
|
84
|
+
self.console = None # console_t | None.
|
85
|
+
self.console_options = None # console_options_t | None.
|
86
|
+
self.alternating_logs = alternating_logs
|
87
|
+
self._log_parity = False
|
88
|
+
|
89
|
+
self.__post_init_local__(supports_html)
|
88
90
|
|
89
91
|
def __post_init_local__(self, supports_html: bool) -> None:
|
90
92
|
""""""
|
@@ -97,28 +99,46 @@ class generic_handler_t(base_t):
|
|
97
99
|
else:
|
98
100
|
self.DisplayRule = self._DisplayRuleAsText
|
99
101
|
|
102
|
+
@classmethod
|
103
|
+
def New(
|
104
|
+
cls,
|
105
|
+
/,
|
106
|
+
*,
|
107
|
+
name: str | None = None,
|
108
|
+
should_store_memory_usage: bool = False,
|
109
|
+
message_width: int = -1,
|
110
|
+
level: int = l.NOTSET,
|
111
|
+
formatter: l.Formatter | None = None,
|
112
|
+
**kwargs,
|
113
|
+
) -> h.Self:
|
114
|
+
""""""
|
115
|
+
return cls(
|
116
|
+
name, should_store_memory_usage, message_width, level, formatter, kwargs
|
117
|
+
)
|
118
|
+
|
100
119
|
def emit(self, record: l.LogRecord, /) -> None:
|
101
120
|
""""""
|
102
121
|
if self.console is None:
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
message = self.MessageFromRecord(record, line_width=self.message_width)
|
122
|
+
message = self.MessageFromRecord(
|
123
|
+
record, RuleAsText, line_width=self.message_width
|
124
|
+
)[0]
|
107
125
|
else:
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
126
|
+
message, is_not_a_rule = self.MessageFromRecord(
|
127
|
+
record,
|
128
|
+
Rule,
|
129
|
+
line_width=self.message_width,
|
130
|
+
color=DATE_TIME_COLOR,
|
131
|
+
PreProcessed=EscapedForRich,
|
132
|
+
)
|
133
|
+
if is_not_a_rule:
|
134
|
+
message = HighlightedVersion(
|
115
135
|
self.console,
|
116
136
|
message,
|
117
137
|
record.levelno,
|
118
138
|
self.alternating_logs,
|
119
|
-
self.
|
139
|
+
self._log_parity,
|
120
140
|
)
|
121
|
-
segments = self.console.render(
|
141
|
+
segments = self.console.render(message, options=self.console_options)
|
122
142
|
|
123
143
|
# Inspired from the code of: rich.console.export_html.
|
124
144
|
html_segments = []
|
@@ -143,13 +163,13 @@ class generic_handler_t(base_t):
|
|
143
163
|
)
|
144
164
|
|
145
165
|
self.LogAsIs(message)
|
146
|
-
self.
|
166
|
+
self._log_parity = not self._log_parity
|
147
167
|
|
148
168
|
def _DisplayRuleAsText(
|
149
169
|
self, /, *, text: str | None = None, color: str = "white"
|
150
170
|
) -> None:
|
151
171
|
""""""
|
152
|
-
self.LogAsIs(RuleAsText(text))
|
172
|
+
self.LogAsIs(RuleAsText(text, None))
|
153
173
|
|
154
174
|
def _DisplayRule(self, /, *, text: str | None = None, color: str = "white") -> None:
|
155
175
|
""""""
|
logger_36/config/message.py
CHANGED
@@ -0,0 +1,70 @@
|
|
1
|
+
"""
|
2
|
+
Copyright CNRS/Inria/UniCA
|
3
|
+
Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2023
|
4
|
+
SEE COPYRIGHT NOTICE BELOW
|
5
|
+
"""
|
6
|
+
|
7
|
+
TITLE_PLACEHOLDER = "TITLE"
|
8
|
+
BODY_PLACEHOLDER = "BODY"
|
9
|
+
|
10
|
+
MINIMAL_HTML = f"""
|
11
|
+
<!DOCTYPE html>
|
12
|
+
<html lang="en">
|
13
|
+
<head>
|
14
|
+
<meta charset="utf-8">
|
15
|
+
<title>{TITLE_PLACEHOLDER}</title>
|
16
|
+
</head>
|
17
|
+
<body>
|
18
|
+
<pre>
|
19
|
+
{BODY_PLACEHOLDER}
|
20
|
+
</pre>
|
21
|
+
</body>
|
22
|
+
</html>
|
23
|
+
"""
|
24
|
+
|
25
|
+
|
26
|
+
"""
|
27
|
+
COPYRIGHT NOTICE
|
28
|
+
|
29
|
+
This software is governed by the CeCILL license under French law and
|
30
|
+
abiding by the rules of distribution of free software. You can use,
|
31
|
+
modify and/ or redistribute the software under the terms of the CeCILL
|
32
|
+
license as circulated by CEA, CNRS and INRIA at the following URL
|
33
|
+
"http://www.cecill.info".
|
34
|
+
|
35
|
+
As a counterpart to the access to the source code and rights to copy,
|
36
|
+
modify and redistribute granted by the license, users are provided only
|
37
|
+
with a limited warranty and the software's author, the holder of the
|
38
|
+
economic rights, and the successive licensors have only limited
|
39
|
+
liability.
|
40
|
+
|
41
|
+
In this respect, the user's attention is drawn to the risks associated
|
42
|
+
with loading, using, modifying and/or developing or reproducing the
|
43
|
+
software by the user in light of its specific status of free software,
|
44
|
+
that may mean that it is complicated to manipulate, and that also
|
45
|
+
therefore means that it is reserved for developers and experienced
|
46
|
+
professionals having in-depth computer knowledge. Users are therefore
|
47
|
+
encouraged to load and test the software's suitability as regards their
|
48
|
+
requirements in conditions enabling the security of their systems and/or
|
49
|
+
data to be ensured and, more generally, to use and operate it in the
|
50
|
+
same conditions as regards security.
|
51
|
+
|
52
|
+
The fact that you are presently reading this means that you have had
|
53
|
+
knowledge of the CeCILL license and that you accept its terms.
|
54
|
+
|
55
|
+
SEE LICENCE NOTICE: file README-LICENCE-utf8.txt at project source root.
|
56
|
+
|
57
|
+
This software is being developed by Eric Debreuve, a CNRS employee and
|
58
|
+
member of team Morpheme.
|
59
|
+
Team Morpheme is a joint team between Inria, CNRS, and UniCA.
|
60
|
+
It is hosted by the Centre Inria d'Université Côte d'Azur, Laboratory
|
61
|
+
I3S, and Laboratory iBV.
|
62
|
+
|
63
|
+
CNRS: https://www.cnrs.fr/index.php/en
|
64
|
+
Inria: https://www.inria.fr/en/
|
65
|
+
UniCA: https://univ-cotedazur.eu/
|
66
|
+
Centre Inria d'Université Côte d'Azur: https://www.inria.fr/en/centre/sophia/
|
67
|
+
I3S: https://www.i3s.unice.fr/en/
|
68
|
+
iBV: http://ibv.unice.fr/
|
69
|
+
Team Morpheme: https://team.inria.fr/morpheme/
|
70
|
+
"""
|
logger_36/task/format/message.py
CHANGED
@@ -5,10 +5,69 @@ SEE COPYRIGHT NOTICE BELOW
|
|
5
5
|
"""
|
6
6
|
|
7
7
|
import difflib as diff
|
8
|
+
import logging as l
|
8
9
|
import typing as h
|
9
10
|
|
11
|
+
from logger_36.config.message import (
|
12
|
+
LEVEL_CLOSING,
|
13
|
+
LEVEL_OPENING,
|
14
|
+
MESSAGE_MARKER,
|
15
|
+
WHERE_SEPARATOR,
|
16
|
+
)
|
10
17
|
from logger_36.constant.generic import NOT_PASSED
|
11
|
-
from logger_36.constant.message import expected_op_h
|
18
|
+
from logger_36.constant.message import NEXT_LINE_PROLOGUE, expected_op_h
|
19
|
+
from logger_36.constant.record import SHOW_W_RULE_ATTR
|
20
|
+
from logger_36.extension.line import WrappedLines
|
21
|
+
from logger_36.type.message import RuleWithText_h
|
22
|
+
|
23
|
+
|
24
|
+
def MessageFromRecord(
|
25
|
+
record: l.LogRecord,
|
26
|
+
RuleWithText: RuleWithText_h,
|
27
|
+
/,
|
28
|
+
*,
|
29
|
+
line_width: int = 0,
|
30
|
+
color: str | None = None,
|
31
|
+
PreProcessed: h.Callable[[str], str] | None = None,
|
32
|
+
) -> tuple[str, bool]:
|
33
|
+
"""
|
34
|
+
See logger_36.catalog.handler.README.txt.
|
35
|
+
|
36
|
+
The second returned value is is_not_a_rule.
|
37
|
+
"""
|
38
|
+
message = record.msg
|
39
|
+
|
40
|
+
if hasattr(record, SHOW_W_RULE_ATTR):
|
41
|
+
return RuleWithText(message, color), False
|
42
|
+
|
43
|
+
if PreProcessed is not None:
|
44
|
+
message = PreProcessed(message)
|
45
|
+
if (line_width <= 0) or (message.__len__() <= line_width):
|
46
|
+
if "\n" in message:
|
47
|
+
message = NEXT_LINE_PROLOGUE.join(message.splitlines())
|
48
|
+
else:
|
49
|
+
if "\n" in message:
|
50
|
+
lines = WrappedLines(message.splitlines(), line_width)
|
51
|
+
else:
|
52
|
+
lines = WrappedLines([message], line_width)
|
53
|
+
message = NEXT_LINE_PROLOGUE.join(lines)
|
54
|
+
|
55
|
+
when_or_elapsed = getattr(record, "when_or_elapsed", None)
|
56
|
+
if when_or_elapsed is None:
|
57
|
+
return message, True
|
58
|
+
|
59
|
+
level_first_letter = getattr(record, "level_first_letter", "")
|
60
|
+
|
61
|
+
if (where := getattr(record, "where", None)) is None:
|
62
|
+
where = ""
|
63
|
+
else:
|
64
|
+
where = f"{NEXT_LINE_PROLOGUE}{WHERE_SEPARATOR} {where}"
|
65
|
+
|
66
|
+
return (
|
67
|
+
f"{when_or_elapsed}"
|
68
|
+
f"{LEVEL_OPENING}{level_first_letter}{LEVEL_CLOSING} "
|
69
|
+
f"{MESSAGE_MARKER} {message}{where}"
|
70
|
+
), True
|
12
71
|
|
13
72
|
|
14
73
|
def MessageWithActualExpected(
|
logger_36/task/format/rule.py
CHANGED
@@ -7,7 +7,7 @@ SEE COPYRIGHT NOTICE BELOW
|
|
7
7
|
from logger_36.catalog.config.optional import RICH_IS_AVAILABLE
|
8
8
|
|
9
9
|
|
10
|
-
def RuleAsText(text: str | None, /) -> str:
|
10
|
+
def RuleAsText(text: str | None, _: None, /) -> str:
|
11
11
|
""""""
|
12
12
|
if text is None:
|
13
13
|
return "---- ---- ---- ---- ---- ---- ---- ---- ----"
|
@@ -27,7 +27,8 @@ if RICH_IS_AVAILABLE:
|
|
27
27
|
return rule_t(title=text_t(text, style=f"bold {color}"), style=color)
|
28
28
|
|
29
29
|
else:
|
30
|
-
|
30
|
+
rule_t = text_t = None
|
31
|
+
Rule = lambda _, __: RuleAsText(_, None)
|
31
32
|
|
32
33
|
"""
|
33
34
|
COPYRIGHT NOTICE
|
logger_36/task/storage.py
CHANGED
@@ -8,6 +8,7 @@ import logging as l
|
|
8
8
|
from io import IOBase as io_base_t
|
9
9
|
from pathlib import Path as path_t
|
10
10
|
|
11
|
+
from logger_36.constant.html import BODY_PLACEHOLDER, MINIMAL_HTML, TITLE_PLACEHOLDER
|
11
12
|
from logger_36.instance.logger import L
|
12
13
|
|
13
14
|
|
@@ -35,19 +36,39 @@ def SaveLOGasHTML(path: str | path_t | io_base_t | None = None) -> None:
|
|
35
36
|
path = path_t(path)
|
36
37
|
|
37
38
|
actual_file = isinstance(path, path_t)
|
39
|
+
|
38
40
|
if actual_file and path.exists():
|
39
41
|
L.warning(f'{cannot_save}: File "{path}" already exists.')
|
40
42
|
return
|
41
43
|
|
42
|
-
|
43
|
-
|
44
|
-
|
44
|
+
body = "\n".join(map(_HighlightedEvent, L.recorded))
|
45
|
+
html = MINIMAL_HTML.replace(TITLE_PLACEHOLDER, L.name).replace(
|
46
|
+
BODY_PLACEHOLDER, body
|
47
|
+
)
|
48
|
+
if actual_file:
|
49
|
+
with open(path, "w") as accessor:
|
50
|
+
accessor.write(html)
|
45
51
|
else:
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
52
|
+
path.write(html)
|
53
|
+
|
54
|
+
|
55
|
+
def _HighlightedEvent(event: tuple[int, str], /) -> str:
|
56
|
+
""""""
|
57
|
+
level, message = event
|
58
|
+
if level == l.DEBUG:
|
59
|
+
color = "BlueViolet"
|
60
|
+
elif level == l.INFO:
|
61
|
+
color = "black"
|
62
|
+
elif level == l.WARNING:
|
63
|
+
color = "gold"
|
64
|
+
elif level == l.ERROR:
|
65
|
+
color = "orange"
|
66
|
+
elif level == l.CRITICAL:
|
67
|
+
color = "red"
|
68
|
+
else:
|
69
|
+
color = "black"
|
70
|
+
|
71
|
+
return f'<span style="color:{color}">{message}</span>'
|
51
72
|
|
52
73
|
|
53
74
|
"""
|
logger_36/type/handler.py
CHANGED
@@ -9,12 +9,13 @@ import sys as s
|
|
9
9
|
import typing as h
|
10
10
|
from pathlib import Path as path_t
|
11
11
|
|
12
|
+
from logger_36.config.message import FALLBACK_MESSAGE_WIDTH
|
12
13
|
from logger_36.constant.error import MEMORY_MEASURE_ERROR
|
13
14
|
from logger_36.constant.handler import HANDLER_KINDS
|
14
|
-
from logger_36.task.format.message import MessageWithActualExpected
|
15
|
+
from logger_36.task.format.message import MessageFromRecord, MessageWithActualExpected
|
15
16
|
from logger_36.task.measure.chronos import TimeStamp
|
16
17
|
from logger_36.task.measure.memory import CanCheckUsage as CanCheckMemoryUsage
|
17
|
-
from logger_36.type.message import
|
18
|
+
from logger_36.type.message import MessageFromRecord_h, RuleWithText_h
|
18
19
|
|
19
20
|
_MEMORY_MEASURE_ERROR = MEMORY_MEASURE_ERROR
|
20
21
|
|
@@ -56,8 +57,8 @@ class _base_t:
|
|
56
57
|
s.__stderr__.write(_MEMORY_MEASURE_ERROR + "\n")
|
57
58
|
_MEMORY_MEASURE_ERROR = None
|
58
59
|
|
59
|
-
if 0 < self.message_width <
|
60
|
-
self.message_width =
|
60
|
+
if 0 < self.message_width < FALLBACK_MESSAGE_WIDTH:
|
61
|
+
self.message_width = FALLBACK_MESSAGE_WIDTH
|
61
62
|
|
62
63
|
@classmethod
|
63
64
|
def New(cls, **kwargs) -> h.Self:
|
@@ -66,6 +67,17 @@ class _base_t:
|
|
66
67
|
"""
|
67
68
|
raise NotImplementedError
|
68
69
|
|
70
|
+
def LogAsIs(self, message: str, /) -> None:
|
71
|
+
"""
|
72
|
+
See documentation of
|
73
|
+
logger_36.catalog.handler.generic.generic_handler_t.LogAsIs.
|
74
|
+
"""
|
75
|
+
raise NotImplementedError
|
76
|
+
|
77
|
+
def DisplayRule(self, /, *, text: str | None = None, color: str = "black") -> None:
|
78
|
+
""""""
|
79
|
+
raise NotImplementedError
|
80
|
+
|
69
81
|
|
70
82
|
class handler_t(l.Handler, _base_t):
|
71
83
|
def __init__(
|
@@ -75,11 +87,12 @@ class handler_t(l.Handler, _base_t):
|
|
75
87
|
message_width: int,
|
76
88
|
level: int,
|
77
89
|
formatter: l.Formatter | None,
|
90
|
+
*_,
|
78
91
|
) -> None:
|
79
92
|
""""""
|
80
93
|
l.Handler.__init__(self)
|
81
94
|
_base_t.__init__(self, name, should_store_memory_usage, message_width)
|
82
|
-
|
95
|
+
__post_init__(self, level, formatter)
|
83
96
|
|
84
97
|
|
85
98
|
class file_handler_t(l.FileHandler, _base_t):
|
@@ -91,6 +104,7 @@ class file_handler_t(l.FileHandler, _base_t):
|
|
91
104
|
level: int,
|
92
105
|
formatter: l.Formatter | None,
|
93
106
|
path: str | path_t | None,
|
107
|
+
*_,
|
94
108
|
) -> None:
|
95
109
|
""""""
|
96
110
|
if path is None:
|
@@ -102,13 +116,13 @@ class file_handler_t(l.FileHandler, _base_t):
|
|
102
116
|
|
103
117
|
l.FileHandler.__init__(self, path)
|
104
118
|
_base_t.__init__(self, name, should_store_memory_usage, message_width)
|
105
|
-
|
119
|
+
__post_init__(self, level, formatter)
|
106
120
|
|
107
121
|
|
108
122
|
any_handler_t = handler_t | file_handler_t
|
109
123
|
|
110
124
|
|
111
|
-
def
|
125
|
+
def __post_init__(
|
112
126
|
handler: any_handler_t, level: int, formatter: l.Formatter | None
|
113
127
|
) -> None:
|
114
128
|
""""""
|
@@ -122,13 +136,14 @@ def _HandlerPostInit(
|
|
122
136
|
|
123
137
|
def _MessageFromRecord(
|
124
138
|
record: l.LogRecord,
|
139
|
+
_: RuleWithText_h,
|
125
140
|
/,
|
126
141
|
*,
|
127
142
|
line_width: int = 0,
|
128
143
|
PreProcessed: h.Callable[[str], str] | None = None,
|
129
|
-
) -> str:
|
144
|
+
) -> tuple[str, bool]:
|
130
145
|
#
|
131
|
-
return _MessageFromRecordRaw(record)
|
146
|
+
return _MessageFromRecordRaw(record), False
|
132
147
|
|
133
148
|
handler.MessageFromRecord = _MessageFromRecord
|
134
149
|
|
logger_36/type/logger.py
CHANGED
@@ -44,13 +44,12 @@ from logger_36.constant.record import (
|
|
44
44
|
STORE_MEMORY_ATTR,
|
45
45
|
)
|
46
46
|
from logger_36.extension.exception import OverrideExceptionFormat
|
47
|
-
from logger_36.task.format.message import MessageWithActualExpected
|
47
|
+
from logger_36.task.format.message import MessageFromRecord, MessageWithActualExpected
|
48
48
|
from logger_36.task.format.rule import RuleAsText
|
49
49
|
from logger_36.task.measure.chronos import ElapsedTime
|
50
50
|
from logger_36.task.measure.memory import CurrentUsage as CurrentMemoryUsage
|
51
51
|
from logger_36.type.handler import any_handler_t as base_handler_t
|
52
52
|
from logger_36.type.issue import NewIssue, issue_t
|
53
|
-
from logger_36.type.message import MessageFromRecord
|
54
53
|
|
55
54
|
if RICH_IS_AVAILABLE:
|
56
55
|
from logger_36.catalog.handler.console_rich import console_rich_handler_t
|
@@ -75,23 +74,23 @@ class logger_t(base_t):
|
|
75
74
|
intercepted_wrn_handle: When warning interception is on, this stores the original
|
76
75
|
"handle" method of the Python warning logger.
|
77
76
|
|
78
|
-
|
77
|
+
_should_activate_log_interceptions: Loggers instantiated after a logger_t logger will
|
79
78
|
be missed by an early call of ToggleLogInterceptions. Therefore, passing True for
|
80
|
-
activate_log_interceptions only sets
|
79
|
+
activate_log_interceptions only sets _should_activate_log_interceptions to True,
|
81
80
|
which is later checked in AddHandler to effectively call ToggleLogInterceptions if
|
82
|
-
|
81
|
+
_should_hold_messages is False (which normally indicates that the handler about to be
|
83
82
|
added is the last one).
|
83
|
+
|
84
|
+
_should_hold_messages: Must not be False until at least one handler has been added.
|
84
85
|
"""
|
85
86
|
|
86
|
-
# Must not be False until at least one handler has been added.
|
87
|
-
should_hold_messages: bool = True
|
88
87
|
should_record_messages: bool = False
|
89
88
|
exit_on_error: bool = False # Implies exit_on_critical.
|
90
89
|
exit_on_critical: bool = False
|
91
90
|
|
92
|
-
on_hold: list[l.LogRecord] = d.field(init=False, default_factory=list)
|
93
|
-
recorded: list[str] = d.field(init=False, default_factory=list)
|
94
91
|
events: dict[int, int] = d.field(init=False, default_factory=dict)
|
92
|
+
recorded: list[tuple[int, str]] = d.field(init=False, default_factory=list)
|
93
|
+
|
95
94
|
last_message_now: date_time_t = d.field(init=False, default=_DATE_TIME_ORIGIN)
|
96
95
|
last_message_date: date_t = d.field(init=False, default=_DATE_ORIGIN)
|
97
96
|
any_handler_stores_memory: bool = d.field(init=False, default=False)
|
@@ -102,7 +101,9 @@ class logger_t(base_t):
|
|
102
101
|
intercepted_log_handles: dict[str, logger_handle_h] = d.field(
|
103
102
|
init=False, default_factory=dict
|
104
103
|
)
|
105
|
-
|
104
|
+
_on_hold: list[l.LogRecord] = d.field(init=False, default_factory=list)
|
105
|
+
_should_hold_messages: bool = d.field(init=False, default=True)
|
106
|
+
_should_activate_log_interceptions: bool = d.field(init=False, default=False)
|
106
107
|
|
107
108
|
name_: d.InitVar[str] = LOGGER_NAME
|
108
109
|
level_: d.InitVar[int] = l.NOTSET
|
@@ -167,7 +168,7 @@ class logger_t(base_t):
|
|
167
168
|
if activate_wrn_interceptions:
|
168
169
|
self.ToggleWarningInterceptions(True)
|
169
170
|
if activate_log_interceptions:
|
170
|
-
self.
|
171
|
+
self._should_activate_log_interceptions = True
|
171
172
|
|
172
173
|
if self.exit_on_error:
|
173
174
|
self.exit_on_critical = True
|
@@ -176,12 +177,14 @@ class logger_t(base_t):
|
|
176
177
|
""""""
|
177
178
|
elapsed_time, now = ElapsedTime(should_return_now=True)
|
178
179
|
|
179
|
-
if (self.
|
180
|
-
for held in self.
|
180
|
+
if (self._on_hold.__len__() > 0) and not self._should_hold_messages:
|
181
|
+
for held in self._on_hold:
|
181
182
|
if self.should_record_messages:
|
182
|
-
self.recorded.append(
|
183
|
+
self.recorded.append(
|
184
|
+
(held.levelno, MessageFromRecord(held, RuleAsText)[0])
|
185
|
+
)
|
183
186
|
base_t.handle(self, held)
|
184
|
-
self.
|
187
|
+
self._on_hold.clear()
|
185
188
|
|
186
189
|
if (date := now.date()) != self.last_message_date:
|
187
190
|
self.last_message_date = date
|
@@ -194,11 +197,16 @@ class logger_t(base_t):
|
|
194
197
|
SHOW_W_RULE_ATTR: True,
|
195
198
|
}
|
196
199
|
)
|
197
|
-
if self.
|
198
|
-
self.
|
200
|
+
if self._should_hold_messages:
|
201
|
+
self._on_hold.append(date_record)
|
199
202
|
else:
|
200
203
|
if self.should_record_messages:
|
201
|
-
self.recorded.append(
|
204
|
+
self.recorded.append(
|
205
|
+
(
|
206
|
+
date_record.levelno,
|
207
|
+
MessageFromRecord(date_record, RuleAsText)[0],
|
208
|
+
)
|
209
|
+
)
|
202
210
|
base_t.handle(self, date_record)
|
203
211
|
|
204
212
|
# When.
|
@@ -238,11 +246,13 @@ class logger_t(base_t):
|
|
238
246
|
if not isinstance(record.msg, str):
|
239
247
|
record.msg = str(record.msg)
|
240
248
|
|
241
|
-
if self.
|
242
|
-
self.
|
249
|
+
if self._should_hold_messages:
|
250
|
+
self._on_hold.append(record)
|
243
251
|
else:
|
244
252
|
if self.should_record_messages:
|
245
|
-
self.recorded.append(
|
253
|
+
self.recorded.append(
|
254
|
+
(record.levelno, MessageFromRecord(record, RuleAsText)[0])
|
255
|
+
)
|
246
256
|
base_t.handle(self, record)
|
247
257
|
|
248
258
|
if (self.exit_on_critical and (record.levelno is l.CRITICAL)) or (
|
@@ -381,11 +391,11 @@ class logger_t(base_t):
|
|
381
391
|
**kwargs,
|
382
392
|
) -> None:
|
383
393
|
""""""
|
384
|
-
if (not should_still_hold_messages) and self.
|
394
|
+
if (not should_still_hold_messages) and self._should_activate_log_interceptions:
|
385
395
|
self.ToggleLogInterceptions(True)
|
386
|
-
self.
|
396
|
+
self._should_activate_log_interceptions = False
|
387
397
|
|
388
|
-
self.
|
398
|
+
self._should_hold_messages = should_still_hold_messages
|
389
399
|
handler = handler_t.New(
|
390
400
|
name=name,
|
391
401
|
should_store_memory_usage=should_store_memory_usage,
|
@@ -415,6 +425,13 @@ class logger_t(base_t):
|
|
415
425
|
f"level {handler.level}={l.getLevelName(handler.level)}{path}"
|
416
426
|
)
|
417
427
|
|
428
|
+
def __call__(self, *args, **kwargs) -> None:
|
429
|
+
"""
|
430
|
+
For a print-like calling.
|
431
|
+
"""
|
432
|
+
separator = kwargs.get("separator", " ")
|
433
|
+
self.info(separator.join(map(str, args)))
|
434
|
+
|
418
435
|
def Log(
|
419
436
|
self,
|
420
437
|
message: str,
|
@@ -463,10 +480,7 @@ class logger_t(base_t):
|
|
463
480
|
self.log(level, message)
|
464
481
|
|
465
482
|
def LogAsIs(self, message: str, /, *, indented: bool = False) -> None:
|
466
|
-
"""
|
467
|
-
See documentation of
|
468
|
-
logger_36.catalog.handler.generic.generic_handler_t.LogAsIs.
|
469
|
-
"""
|
483
|
+
""""""
|
470
484
|
if indented:
|
471
485
|
message = text.indent(message, LINE_INDENT)
|
472
486
|
|
@@ -476,7 +490,7 @@ class logger_t(base_t):
|
|
476
490
|
else:
|
477
491
|
LogAsIs(message)
|
478
492
|
|
479
|
-
|
493
|
+
info_raw = LogAsIs # To follow the convention of the logging methods info, error...
|
480
494
|
|
481
495
|
def DisplayRule(
|
482
496
|
self, /, *, message: str | None = None, color: str = "white"
|
@@ -484,7 +498,7 @@ class logger_t(base_t):
|
|
484
498
|
""""""
|
485
499
|
for handler in self.handlers:
|
486
500
|
if (DisplayRule := getattr(handler, "DisplayRule", None)) is None:
|
487
|
-
self.info(RuleAsText(message))
|
501
|
+
self.info(RuleAsText(message, None))
|
488
502
|
else:
|
489
503
|
DisplayRule(text=message, color=color)
|
490
504
|
|
logger_36/type/message.py
CHANGED
@@ -7,14 +7,24 @@ SEE COPYRIGHT NOTICE BELOW
|
|
7
7
|
import logging as l
|
8
8
|
import typing as h
|
9
9
|
|
10
|
-
from logger_36.config.
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
)
|
16
|
-
|
17
|
-
|
10
|
+
from logger_36.catalog.config.optional import RICH_IS_AVAILABLE
|
11
|
+
|
12
|
+
|
13
|
+
@h.runtime_checkable
|
14
|
+
class _RuleAsText_p(h.Protocol):
|
15
|
+
def __call__(self, text: str | None, color: None, /) -> str: ...
|
16
|
+
|
17
|
+
|
18
|
+
if RICH_IS_AVAILABLE:
|
19
|
+
from rich.rule import Rule as rule_t # noqa
|
20
|
+
|
21
|
+
@h.runtime_checkable
|
22
|
+
class _Rule_p(h.Protocol):
|
23
|
+
def __call__(self, text: str | None, color: str, /) -> rule_t | str: ...
|
24
|
+
else:
|
25
|
+
_Rule_p = None
|
26
|
+
|
27
|
+
RuleWithText_h = _RuleAsText_p | _Rule_p
|
18
28
|
|
19
29
|
|
20
30
|
@h.runtime_checkable
|
@@ -22,58 +32,17 @@ class _MessageFromRecordPreprocessed_p(h.Protocol):
|
|
22
32
|
def __call__(
|
23
33
|
self,
|
24
34
|
record: l.LogRecord,
|
35
|
+
RuleWithText: RuleWithText_h,
|
25
36
|
/,
|
26
37
|
*,
|
27
38
|
line_width: int = 0,
|
28
39
|
PreProcessed: h.Callable[[str], str] | None = None,
|
29
|
-
) -> str: ...
|
40
|
+
) -> tuple[str, bool]: ...
|
30
41
|
|
31
42
|
|
32
43
|
MessageFromRecord_h = _MessageFromRecordPreprocessed_p
|
33
44
|
|
34
45
|
|
35
|
-
def MessageFromRecord(
|
36
|
-
record: l.LogRecord,
|
37
|
-
/,
|
38
|
-
*,
|
39
|
-
line_width: int = 0,
|
40
|
-
PreProcessed: h.Callable[[str], str] | None = None,
|
41
|
-
) -> str:
|
42
|
-
"""
|
43
|
-
See logger_36.catalog.handler.README.txt.
|
44
|
-
"""
|
45
|
-
message = record.msg
|
46
|
-
|
47
|
-
if PreProcessed is not None:
|
48
|
-
message = PreProcessed(message)
|
49
|
-
if (line_width <= 0) or (message.__len__() <= line_width):
|
50
|
-
if "\n" in message:
|
51
|
-
message = NEXT_LINE_PROLOGUE.join(message.splitlines())
|
52
|
-
else:
|
53
|
-
if "\n" in message:
|
54
|
-
lines = WrappedLines(message.splitlines(), line_width)
|
55
|
-
else:
|
56
|
-
lines = WrappedLines([message], line_width)
|
57
|
-
message = NEXT_LINE_PROLOGUE.join(lines)
|
58
|
-
|
59
|
-
when_or_elapsed = getattr(record, "when_or_elapsed", None)
|
60
|
-
if when_or_elapsed is None:
|
61
|
-
return message
|
62
|
-
|
63
|
-
level_first_letter = getattr(record, "level_first_letter", "")
|
64
|
-
|
65
|
-
if (where := getattr(record, "where", None)) is None:
|
66
|
-
where = ""
|
67
|
-
else:
|
68
|
-
where = f"{NEXT_LINE_PROLOGUE}{WHERE_SEPARATOR} {where}"
|
69
|
-
|
70
|
-
return (
|
71
|
-
f"{when_or_elapsed}"
|
72
|
-
f"{LEVEL_OPENING}{level_first_letter}{LEVEL_CLOSING} "
|
73
|
-
f"{MESSAGE_MARKER} {message}{where}"
|
74
|
-
)
|
75
|
-
|
76
|
-
|
77
46
|
"""
|
78
47
|
COPYRIGHT NOTICE
|
79
48
|
|
logger_36/version.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
logger_36/__init__.py,sha256=UhKxuQLS1Pfgt5H0K_7BaDAPejOUR8byD5BYRCnHQMQ,2655
|
2
|
-
logger_36/version.py,sha256=
|
2
|
+
logger_36/version.py,sha256=puslblEld2sLwTmqWreV3vMyhNnL0uc4l3B-pcUa2hg,2206
|
3
3
|
logger_36/api/content.py,sha256=clHYYUKa8n4qef6PVlUV4mFHRRf6fnm9wEd2fu9oagA,2381
|
4
4
|
logger_36/api/exception.py,sha256=QKIkNJA0N6FvVHLTApiH3ymhVQoSYU08t2RkyufQPIw,2291
|
5
5
|
logger_36/api/gpu.py,sha256=BOumedCAPWvCo7J-KJ3XE-jr5S0KSmgcFv_S4QKRPO8,2252
|
@@ -10,21 +10,22 @@ logger_36/api/time.py,sha256=Uw1jQtY1njsRuIPRAXX44v4nPOo84MSBu_WK_YCRzQs,2324
|
|
10
10
|
logger_36/api/type.py,sha256=4m5fZGI6LOQvFakEStFv6HTP4FY9nyFpNNlK34rCfQw,2286
|
11
11
|
logger_36/catalog/config/console_rich.py,sha256=lAa5Ev5BhXvmQzfIt1FNihMNUQJFlXaIzNanAMdgtd0,2861
|
12
12
|
logger_36/catalog/config/optional.py,sha256=HaN6mbx7gHBBppNvUw1ckhYTOrlYqb-b_r0mzPcHPjM,2398
|
13
|
-
logger_36/catalog/handler/console.py,sha256=
|
14
|
-
logger_36/catalog/handler/console_rich.py,sha256=
|
15
|
-
logger_36/catalog/handler/file.py,sha256=
|
16
|
-
logger_36/catalog/handler/generic.py,sha256=
|
13
|
+
logger_36/catalog/handler/console.py,sha256=5F_JFsGm5ERFh0_1rh8Jae51VwAJMg7d7bRLZkOK4DY,3283
|
14
|
+
logger_36/catalog/handler/console_rich.py,sha256=U4hD8qF88dpDALKkeOvwnrJpUbUpG5egq1JfImU4pFg,7168
|
15
|
+
logger_36/catalog/handler/file.py,sha256=4Du9f-UNJsZrcNV9jCVLLCklA0T4HYX_jKjxSie-deM,3428
|
16
|
+
logger_36/catalog/handler/generic.py,sha256=8xQA0ETIMmdhmip0wcaD21h4ZGz-52gk0hgoUJYxbn8,8258
|
17
17
|
logger_36/catalog/logger/chronos.py,sha256=ocY13f98EfknU7wZCv0FS9Xb7pTNaWCPSusXFIEvEd4,2437
|
18
18
|
logger_36/catalog/logger/gpu.py,sha256=ybn7Q8exiqoigvNpzEhg0Zp027WogypuNJwfsQ1pRY4,3416
|
19
19
|
logger_36/catalog/logger/memory.py,sha256=CWhr2J4BqArJxzH6tS-ZThr-rYPAQGtuLn0pP7Iryfg,4685
|
20
20
|
logger_36/catalog/logger/system.py,sha256=3VWbceSAknZwmRhEfd8pkuLwU2B8zPhCGNGQE0h5KLo,3065
|
21
21
|
logger_36/config/issue.py,sha256=G-i5p6lhZCLAOa-VTMyL9ZonvGCvhdoQ5KZdSWgP-FU,2267
|
22
22
|
logger_36/config/memory.py,sha256=yCX5phsB_KJMr5xHpVUeOHFhAA7p_8yahP3X28VndOY,2217
|
23
|
-
logger_36/config/message.py,sha256=
|
23
|
+
logger_36/config/message.py,sha256=mgPcMS7qWBuqP2w5NoHw1df32kcVToVhisozb32_EII,2554
|
24
24
|
logger_36/config/system.py,sha256=HD8ZuwsXhEAExeZrww8YoDkQGMs4T5RDqQMb1W4qVgc,2477
|
25
25
|
logger_36/constant/error.py,sha256=LzsS_P1IoH3ct_ifNWi9LzJ-X_Y5DN1naTLwwIFzDQA,2827
|
26
26
|
logger_36/constant/generic.py,sha256=t6aRb66_NHwMhR1p7BZ4QXTU2jpLz-H5YAL4PuMtKx8,2244
|
27
27
|
logger_36/constant/handler.py,sha256=PQUehMK9Yg0_rBDcMc8xpUbAsCauCLy_eS_ntiWew1Y,2378
|
28
|
+
logger_36/constant/html.py,sha256=-m1CDyDN0kkurloEtJeqBsyxy9nXCImIMGLwEIF33M0,2515
|
28
29
|
logger_36/constant/issue.py,sha256=01l8itRPWGS5F6gXtsXUJgGR-4lS1Eu3_YeKC-khKLw,2315
|
29
30
|
logger_36/constant/logger.py,sha256=2qRkteblpbHrq9x0aiw9MPquyXrSRd6_yMQnPEhFp2U,2468
|
30
31
|
logger_36/constant/memory.py,sha256=ZL1MwbdtNsrCrOwzEyfTsfOoOsRBTJtbbf3otHGnxXo,2343
|
@@ -38,18 +39,18 @@ logger_36/extension/line.py,sha256=3MJ3B5PXJn18RHxBUcWnNBLEYzb7VTcEAufn7ULdYfY,3
|
|
38
39
|
logger_36/instance/logger.py,sha256=oTw5svRzKRJKvGrrZUtutJIOjp5UISft3fl0Ze7DOBE,2241
|
39
40
|
logger_36/instance/loggers.py,sha256=RCWpC1NPAf6vXnFc9NqsSALv-x-FEzcH6k_OlxTxeQk,2251
|
40
41
|
logger_36/task/inspection.py,sha256=VR9ESSa2iAAiQggwzHzV2A3-rRr6VgMqR1HvclhK2Xc,5010
|
41
|
-
logger_36/task/storage.py,sha256=
|
42
|
+
logger_36/task/storage.py,sha256=Y88934cVcen1i8qruskmCMQYA5-dl1wI8EaJFCv49Q0,4042
|
42
43
|
logger_36/task/format/memory.py,sha256=ZipL1f-Bqv4ugFvXZfNrj49rdIMXjEKcVz1OvgMaZXI,4249
|
43
|
-
logger_36/task/format/message.py,sha256=
|
44
|
-
logger_36/task/format/rule.py,sha256=
|
44
|
+
logger_36/task/format/message.py,sha256=5mR9CZaARy9q-JtIX68IyY-DKTepkxyRV7juByqBH7c,5771
|
45
|
+
logger_36/task/format/rule.py,sha256=CtR7d2X-pZFKdqG6Y2_3b5AMKg_J274Jq69kht0N6xs,2910
|
45
46
|
logger_36/task/measure/chronos.py,sha256=1kVhu6jZlNAtNWQQh8ZVuRwZIAC9gGz3_ul1tn0t4Yw,3055
|
46
47
|
logger_36/task/measure/memory.py,sha256=OjU5EYFH8SnzlCQKAoiXvauUlwQYOrH34jFXTVYF0jE,2517
|
47
|
-
logger_36/type/handler.py,sha256=
|
48
|
+
logger_36/type/handler.py,sha256=6oxW-Y_kuAEfoXsMr-KXspv0czYiwe8rDzMAMrshFmw,6567
|
48
49
|
logger_36/type/issue.py,sha256=2rGsFqaQJCbeml9xN08mN_nK79L8qscaS_0ws36Y0bI,3214
|
49
|
-
logger_36/type/logger.py,sha256=
|
50
|
+
logger_36/type/logger.py,sha256=ISMUQBZ-KhLBi_tZjCAYtss5pAwFW3psTQu5k9_ZbEw,25287
|
50
51
|
logger_36/type/loggers.py,sha256=znqxWBnfQxvkg3VUfbTUvt3S6Kq0DAzWWepxQDt9suI,2871
|
51
|
-
logger_36/type/message.py,sha256=
|
52
|
-
logger_36-2025.
|
53
|
-
logger_36-2025.
|
54
|
-
logger_36-2025.
|
55
|
-
logger_36-2025.
|
52
|
+
logger_36/type/message.py,sha256=zKME5p87ynsXte_b5usXV3VHaj34Uezs9Gg_WVWfaeY,3063
|
53
|
+
logger_36-2025.14.dist-info/METADATA,sha256=GkEE-L8P0ShhL0XxKOu-A5p3yZD0mJzAcGax90FiUw8,6506
|
54
|
+
logger_36-2025.14.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
55
|
+
logger_36-2025.14.dist-info/top_level.txt,sha256=sM95BTMWmslEEgR_1pzwZsOeSp8C_QBiu8ImbFr0XLc,10
|
56
|
+
logger_36-2025.14.dist-info/RECORD,,
|
File without changes
|
File without changes
|