logger-36 2024.1__py3-none-any.whl → 2025.3__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- logger_36/__init__.py +64 -42
- logger_36/api/logger.py +53 -0
- logger_36/api/storage.py +53 -0
- logger_36/catalog/config/console_rich.py +76 -0
- logger_36/catalog/handler/console.py +117 -0
- logger_36/catalog/handler/console_rich.py +235 -0
- logger_36/catalog/handler/file.py +128 -0
- logger_36/catalog/handler/generic.py +228 -0
- logger_36/catalog/logger/chronos.py +61 -0
- logger_36/catalog/logger/gpu.py +90 -0
- logger_36/catalog/logger/memory.py +129 -0
- logger_36/catalog/logger/system.py +84 -0
- logger_36/config/issue.py +56 -0
- logger_36/config/logger.py +103 -0
- logger_36/config/memory.py +54 -0
- logger_36/config/message.py +66 -0
- logger_36/config/system.py +70 -0
- logger_36/constant/error.py +70 -0
- logger_36/constant/generic.py +58 -0
- logger_36/constant/handler.py +58 -0
- logger_36/constant/issue.py +58 -0
- logger_36/constant/logger.py +67 -0
- logger_36/constant/memory.py +58 -0
- logger_36/constant/message.py +72 -0
- logger_36/constant/record.py +55 -0
- logger_36/constant/system.py +60 -0
- logger_36/content.py +55 -0
- logger_36/exception.py +105 -0
- logger_36/gpu.py +53 -0
- logger_36/handler.py +209 -0
- logger_36/instance/logger.py +55 -0
- logger_36/instance/loggers.py +56 -0
- logger_36/memory.py +60 -0
- logger_36/storage.py +53 -0
- logger_36/system.py +53 -0
- logger_36/task/format/memory.py +132 -0
- logger_36/task/format/message.py +111 -0
- logger_36/task/format/rule.py +74 -0
- logger_36/task/inspection.py +70 -48
- logger_36/task/measure/chronos.py +84 -0
- logger_36/task/measure/memory.py +72 -0
- logger_36/task/storage.py +127 -46
- logger_36/time.py +54 -0
- logger_36/type/handler.py +184 -0
- logger_36/type/issue.py +91 -0
- logger_36/type/logger.py +542 -0
- logger_36/type/loggers.py +78 -0
- logger_36/version.py +53 -32
- logger_36-2025.3.dist-info/METADATA +154 -0
- logger_36-2025.3.dist-info/RECORD +52 -0
- {logger_36-2024.1.dist-info → logger_36-2025.3.dist-info}/WHEEL +1 -1
- logger_36/catalog/gpu.py +0 -56
- logger_36/catalog/memory.py +0 -109
- logger_36/catalog/system.py +0 -84
- logger_36/config.py +0 -48
- logger_36/constant.py +0 -52
- logger_36/instance.py +0 -34
- logger_36/main.py +0 -96
- logger_36/measure/chronos.py +0 -55
- logger_36/measure/memory.py +0 -50
- logger_36/type/console.py +0 -122
- logger_36/type/extension.py +0 -122
- logger_36/type/file.py +0 -52
- logger_36/type/generic.py +0 -115
- logger_36-2024.1.dist-info/METADATA +0 -106
- logger_36-2024.1.dist-info/RECORD +0 -21
- {logger_36-2024.1.dist-info → logger_36-2025.3.dist-info}/top_level.txt +0 -0
logger_36/instance.py
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
# eric.debreuve@cnrs.fr
|
2
|
-
#
|
3
|
-
# This software is governed by the CeCILL license under French law and
|
4
|
-
# abiding by the rules of distribution of free software. You can use,
|
5
|
-
# modify and/ or redistribute the software under the terms of the CeCILL
|
6
|
-
# license as circulated by CEA, CNRS and INRIA at the following URL
|
7
|
-
# "http://www.cecill.info".
|
8
|
-
#
|
9
|
-
# As a counterpart to the access to the source code and rights to copy,
|
10
|
-
# modify and redistribute granted by the license, users are provided only
|
11
|
-
# with a limited warranty and the software's author, the holder of the
|
12
|
-
# economic rights, and the successive licensors have only limited
|
13
|
-
# liability.
|
14
|
-
#
|
15
|
-
# In this respect, the user's attention is drawn to the risks associated
|
16
|
-
# with loading, using, modifying and/or developing or reproducing the
|
17
|
-
# software by the user in light of its specific status of free software,
|
18
|
-
# that may mean that it is complicated to manipulate, and that also
|
19
|
-
# therefore means that it is reserved for developers and experienced
|
20
|
-
# professionals having in-depth computer knowledge. Users are therefore
|
21
|
-
# encouraged to load and test the software's suitability as regards their
|
22
|
-
# requirements in conditions enabling the security of their systems and/or
|
23
|
-
# data to be ensured and, more generally, to use and operate it in the
|
24
|
-
# same conditions as regards security.
|
25
|
-
#
|
26
|
-
# The fact that you are presently reading this means that you have had
|
27
|
-
# knowledge of the CeCILL license and that you accept its terms.
|
28
|
-
|
29
|
-
import logging as lggg
|
30
|
-
|
31
|
-
from logger_36.config import LOGGER_NAME
|
32
|
-
|
33
|
-
LOGGER = lggg.getLogger(name=LOGGER_NAME)
|
34
|
-
LOGGER.setLevel(lggg.DEBUG)
|
logger_36/main.py
DELETED
@@ -1,96 +0,0 @@
|
|
1
|
-
# Copyright CNRS/Inria/UCA
|
2
|
-
# Contributor(s): Eric Debreuve (since 2023)
|
3
|
-
#
|
4
|
-
# eric.debreuve@cnrs.fr
|
5
|
-
#
|
6
|
-
# This software is governed by the CeCILL license under French law and
|
7
|
-
# abiding by the rules of distribution of free software. You can use,
|
8
|
-
# modify and/ or redistribute the software under the terms of the CeCILL
|
9
|
-
# license as circulated by CEA, CNRS and INRIA at the following URL
|
10
|
-
# "http://www.cecill.info".
|
11
|
-
#
|
12
|
-
# As a counterpart to the access to the source code and rights to copy,
|
13
|
-
# modify and redistribute granted by the license, users are provided only
|
14
|
-
# with a limited warranty and the software's author, the holder of the
|
15
|
-
# economic rights, and the successive licensors have only limited
|
16
|
-
# liability.
|
17
|
-
#
|
18
|
-
# In this respect, the user's attention is drawn to the risks associated
|
19
|
-
# with loading, using, modifying and/or developing or reproducing the
|
20
|
-
# software by the user in light of its specific status of free software,
|
21
|
-
# that may mean that it is complicated to manipulate, and that also
|
22
|
-
# therefore means that it is reserved for developers and experienced
|
23
|
-
# professionals having in-depth computer knowledge. Users are therefore
|
24
|
-
# encouraged to load and test the software's suitability as regards their
|
25
|
-
# requirements in conditions enabling the security of their systems and/or
|
26
|
-
# data to be ensured and, more generally, to use and operate it in the
|
27
|
-
# same conditions as regards security.
|
28
|
-
#
|
29
|
-
# The fact that you are presently reading this means that you have had
|
30
|
-
# knowledge of the CeCILL license and that you accept its terms.
|
31
|
-
|
32
|
-
"""
|
33
|
-
Alternative implementations: using logging.Filter or logging.LoggerAdapter.
|
34
|
-
"""
|
35
|
-
import logging as lggg
|
36
|
-
from pathlib import Path as path_t
|
37
|
-
from typing import Callable, Literal
|
38
|
-
|
39
|
-
from logger_36.instance import LOGGER
|
40
|
-
from logger_36.type.console import console_handler_t
|
41
|
-
from logger_36.type.file import file_handler_t
|
42
|
-
from logger_36.type.generic import can_show_message_p, generic_handler_t
|
43
|
-
|
44
|
-
|
45
|
-
def AddGenericHandler(
|
46
|
-
interface: can_show_message_p | Callable[[str], None],
|
47
|
-
/,
|
48
|
-
*args,
|
49
|
-
level: int = lggg.INFO,
|
50
|
-
supports_html: bool = False,
|
51
|
-
**kwargs,
|
52
|
-
) -> None:
|
53
|
-
""""""
|
54
|
-
handler = generic_handler_t(interface, *args, supports_html=supports_html, **kwargs)
|
55
|
-
handler.setLevel(level)
|
56
|
-
LOGGER.addHandler(handler)
|
57
|
-
|
58
|
-
|
59
|
-
def AddFileHandler(
|
60
|
-
path: str | path_t, /, *args, level: int = lggg.INFO, **kwargs
|
61
|
-
) -> None:
|
62
|
-
""""""
|
63
|
-
if isinstance(path, str):
|
64
|
-
path = path_t(path)
|
65
|
-
if path.exists():
|
66
|
-
raise ValueError(f"{path}: File already exists")
|
67
|
-
|
68
|
-
handler = file_handler_t(path, *args, **kwargs)
|
69
|
-
handler.setLevel(level)
|
70
|
-
LOGGER.addHandler(handler)
|
71
|
-
|
72
|
-
|
73
|
-
def SetLOGLevel(level: int, /, *, which: Literal["c", "f", "a"] = "a") -> None:
|
74
|
-
"""
|
75
|
-
which: c=console, f=file, a=all
|
76
|
-
"""
|
77
|
-
if which not in "cfa":
|
78
|
-
raise ValueError(
|
79
|
-
f"{which}: Invalid handler specifier. "
|
80
|
-
f'Expected="c" for console, "f" for file, or "a" for all'
|
81
|
-
)
|
82
|
-
|
83
|
-
for handler in LOGGER.handlers:
|
84
|
-
if (
|
85
|
-
(which == "a")
|
86
|
-
or ((which == "c") and isinstance(handler, console_handler_t))
|
87
|
-
or ((which == "f") and isinstance(handler, file_handler_t))
|
88
|
-
):
|
89
|
-
handler.setLevel(level)
|
90
|
-
|
91
|
-
|
92
|
-
def SetExitOnError(exit_on_error: bool, /) -> None:
|
93
|
-
""""""
|
94
|
-
for handler in LOGGER.handlers:
|
95
|
-
if hasattr(handler, "exit_on_error"):
|
96
|
-
handler.exit_on_error = exit_on_error
|
logger_36/measure/chronos.py
DELETED
@@ -1,55 +0,0 @@
|
|
1
|
-
# Copyright CNRS/Inria/UCA
|
2
|
-
# Contributor(s): Eric Debreuve (since 2023)
|
3
|
-
#
|
4
|
-
# eric.debreuve@cnrs.fr
|
5
|
-
#
|
6
|
-
# This software is governed by the CeCILL license under French law and
|
7
|
-
# abiding by the rules of distribution of free software. You can use,
|
8
|
-
# modify and/ or redistribute the software under the terms of the CeCILL
|
9
|
-
# license as circulated by CEA, CNRS and INRIA at the following URL
|
10
|
-
# "http://www.cecill.info".
|
11
|
-
#
|
12
|
-
# As a counterpart to the access to the source code and rights to copy,
|
13
|
-
# modify and redistribute granted by the license, users are provided only
|
14
|
-
# with a limited warranty and the software's author, the holder of the
|
15
|
-
# economic rights, and the successive licensors have only limited
|
16
|
-
# liability.
|
17
|
-
#
|
18
|
-
# In this respect, the user's attention is drawn to the risks associated
|
19
|
-
# with loading, using, modifying and/or developing or reproducing the
|
20
|
-
# software by the user in light of its specific status of free software,
|
21
|
-
# that may mean that it is complicated to manipulate, and that also
|
22
|
-
# therefore means that it is reserved for developers and experienced
|
23
|
-
# professionals having in-depth computer knowledge. Users are therefore
|
24
|
-
# encouraged to load and test the software's suitability as regards their
|
25
|
-
# requirements in conditions enabling the security of their systems and/or
|
26
|
-
# data to be ensured and, more generally, to use and operate it in the
|
27
|
-
# same conditions as regards security.
|
28
|
-
#
|
29
|
-
# The fact that you are presently reading this means that you have had
|
30
|
-
# knowledge of the CeCILL license and that you accept its terms.
|
31
|
-
|
32
|
-
import time
|
33
|
-
from datetime import datetime as dttm
|
34
|
-
|
35
|
-
from logger_36.constant import START_TIME
|
36
|
-
|
37
|
-
|
38
|
-
def TimeStamp() -> str:
|
39
|
-
""""""
|
40
|
-
return (
|
41
|
-
dttm.now()
|
42
|
-
.isoformat(timespec="milliseconds")
|
43
|
-
.replace(".", "-")
|
44
|
-
.replace(":", "-")
|
45
|
-
)
|
46
|
-
|
47
|
-
|
48
|
-
def ElapsedTime() -> str:
|
49
|
-
""""""
|
50
|
-
elapsed_seconds = (dttm.now() - START_TIME).total_seconds()
|
51
|
-
output = time.strftime("%Hh %Mm %Ss", time.gmtime(elapsed_seconds))
|
52
|
-
while output.startswith("00") and (" " in output):
|
53
|
-
output = output.split(maxsplit=1)[-1]
|
54
|
-
|
55
|
-
return output
|
logger_36/measure/memory.py
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
# Copyright CNRS/Inria/UCA
|
2
|
-
# Contributor(s): Eric Debreuve (since 2023)
|
3
|
-
#
|
4
|
-
# eric.debreuve@cnrs.fr
|
5
|
-
#
|
6
|
-
# This software is governed by the CeCILL license under French law and
|
7
|
-
# abiding by the rules of distribution of free software. You can use,
|
8
|
-
# modify and/ or redistribute the software under the terms of the CeCILL
|
9
|
-
# license as circulated by CEA, CNRS and INRIA at the following URL
|
10
|
-
# "http://www.cecill.info".
|
11
|
-
#
|
12
|
-
# As a counterpart to the access to the source code and rights to copy,
|
13
|
-
# modify and redistribute granted by the license, users are provided only
|
14
|
-
# with a limited warranty and the software's author, the holder of the
|
15
|
-
# economic rights, and the successive licensors have only limited
|
16
|
-
# liability.
|
17
|
-
#
|
18
|
-
# In this respect, the user's attention is drawn to the risks associated
|
19
|
-
# with loading, using, modifying and/or developing or reproducing the
|
20
|
-
# software by the user in light of its specific status of free software,
|
21
|
-
# that may mean that it is complicated to manipulate, and that also
|
22
|
-
# therefore means that it is reserved for developers and experienced
|
23
|
-
# professionals having in-depth computer knowledge. Users are therefore
|
24
|
-
# encouraged to load and test the software's suitability as regards their
|
25
|
-
# requirements in conditions enabling the security of their systems and/or
|
26
|
-
# data to be ensured and, more generally, to use and operate it in the
|
27
|
-
# same conditions as regards security.
|
28
|
-
#
|
29
|
-
# The fact that you are presently reading this means that you have had
|
30
|
-
# knowledge of the CeCILL license and that you accept its terms.
|
31
|
-
|
32
|
-
try:
|
33
|
-
from psutil import Process as process_t
|
34
|
-
|
35
|
-
_PROCESS = process_t()
|
36
|
-
except ModuleNotFoundError:
|
37
|
-
_PROCESS = None
|
38
|
-
|
39
|
-
|
40
|
-
def CanCheckMemory() -> bool:
|
41
|
-
""""""
|
42
|
-
return _PROCESS is not None
|
43
|
-
|
44
|
-
|
45
|
-
def CurrentUsage() -> int:
|
46
|
-
""""""
|
47
|
-
if _PROCESS is None:
|
48
|
-
return -1
|
49
|
-
|
50
|
-
return _PROCESS.memory_info().rss
|
logger_36/type/console.py
DELETED
@@ -1,122 +0,0 @@
|
|
1
|
-
# Copyright CNRS/Inria/UCA
|
2
|
-
# Contributor(s): Eric Debreuve (since 2023)
|
3
|
-
#
|
4
|
-
# eric.debreuve@cnrs.fr
|
5
|
-
#
|
6
|
-
# This software is governed by the CeCILL license under French law and
|
7
|
-
# abiding by the rules of distribution of free software. You can use,
|
8
|
-
# modify and/ or redistribute the software under the terms of the CeCILL
|
9
|
-
# license as circulated by CEA, CNRS and INRIA at the following URL
|
10
|
-
# "http://www.cecill.info".
|
11
|
-
#
|
12
|
-
# As a counterpart to the access to the source code and rights to copy,
|
13
|
-
# modify and redistribute granted by the license, users are provided only
|
14
|
-
# with a limited warranty and the software's author, the holder of the
|
15
|
-
# economic rights, and the successive licensors have only limited
|
16
|
-
# liability.
|
17
|
-
#
|
18
|
-
# In this respect, the user's attention is drawn to the risks associated
|
19
|
-
# with loading, using, modifying and/or developing or reproducing the
|
20
|
-
# software by the user in light of its specific status of free software,
|
21
|
-
# that may mean that it is complicated to manipulate, and that also
|
22
|
-
# therefore means that it is reserved for developers and experienced
|
23
|
-
# professionals having in-depth computer knowledge. Users are therefore
|
24
|
-
# encouraged to load and test the software's suitability as regards their
|
25
|
-
# requirements in conditions enabling the security of their systems and/or
|
26
|
-
# data to be ensured and, more generally, to use and operate it in the
|
27
|
-
# same conditions as regards security.
|
28
|
-
#
|
29
|
-
# The fact that you are presently reading this means that you have had
|
30
|
-
# knowledge of the CeCILL license and that you accept its terms.
|
31
|
-
|
32
|
-
import logging as lggg
|
33
|
-
from typing import ClassVar
|
34
|
-
|
35
|
-
from rich.color import Color as color_t
|
36
|
-
from rich.console import Console as console_t
|
37
|
-
from rich.markup import escape as PreProcessedForRich
|
38
|
-
from rich.style import Style as style_t
|
39
|
-
from rich.text import Text as text_t
|
40
|
-
|
41
|
-
from logger_36.config import ELAPSED_TIME_SEPARATOR, LEVEL_CLOSING, WHERE_SEPARATOR
|
42
|
-
from logger_36.constant import DATE_TIME_LENGTH
|
43
|
-
from logger_36.type.extension import handler_extension_t
|
44
|
-
|
45
|
-
|
46
|
-
class console_handler_t(lggg.Handler, handler_extension_t):
|
47
|
-
TAB_SIZE: ClassVar[int] = 5 # => CONTEXT_SEPARATOR aligned for all log levels.
|
48
|
-
DATE_TIME_COLOR: ClassVar[str] = "dodger_blue2"
|
49
|
-
LEVEL_COLOR: ClassVar[dict[int, str | style_t]] = {
|
50
|
-
lggg.DEBUG: "orchid",
|
51
|
-
lggg.INFO: "white",
|
52
|
-
lggg.WARNING: "yellow",
|
53
|
-
lggg.ERROR: "orange1",
|
54
|
-
lggg.CRITICAL: "red",
|
55
|
-
}
|
56
|
-
ELAPSED_TIME_COLOR: ClassVar[str] = "green"
|
57
|
-
ACTUAL_COLOR: ClassVar[str] = "red"
|
58
|
-
EXPECTED_COLOR: ClassVar[str] = "green"
|
59
|
-
GRAY_STYLE: ClassVar[style_t] = style_t(color=color_t.from_rgb(150, 150, 150))
|
60
|
-
ACTUAL_PATTERNS: ClassVar[tuple[str]] = (r" Actual=[^.]+;",)
|
61
|
-
EXPECTED_PATTERNS: ClassVar[tuple[str]] = (r" Expected([!<>]=|: )[^.]+\.",)
|
62
|
-
|
63
|
-
console: console_t
|
64
|
-
|
65
|
-
def __init__(self, /, *, level: int = lggg.NOTSET) -> None:
|
66
|
-
""""""
|
67
|
-
lggg.Handler.__init__(self, level=level)
|
68
|
-
handler_extension_t.__init__(self)
|
69
|
-
|
70
|
-
self.setFormatter(self.formatter)
|
71
|
-
self.console = console_t(
|
72
|
-
tab_size=self.__class__.TAB_SIZE,
|
73
|
-
highlight=False,
|
74
|
-
force_terminal=True,
|
75
|
-
record=True,
|
76
|
-
)
|
77
|
-
|
78
|
-
def emit(self, record: lggg.LogRecord, /) -> None:
|
79
|
-
""""""
|
80
|
-
first_line, next_lines = self.MessageLines(
|
81
|
-
record, PreProcessed=PreProcessedForRich
|
82
|
-
)
|
83
|
-
highlighted = self.__class__.HighlightedVersion(
|
84
|
-
first_line, next_lines, record.levelno
|
85
|
-
)
|
86
|
-
self.console.print(highlighted, crop=False, overflow="ignore")
|
87
|
-
|
88
|
-
self.ExitOrNotIfError(record)
|
89
|
-
|
90
|
-
@classmethod
|
91
|
-
def HighlightedVersion(
|
92
|
-
cls, first_line: str, next_lines: str | None, log_level: int, /
|
93
|
-
) -> text_t:
|
94
|
-
""""""
|
95
|
-
output = text_t(first_line)
|
96
|
-
|
97
|
-
# Used instead of _CONTEXT_LENGTH which might include \t, thus creating a
|
98
|
-
# mismatch between character length and length when displayed in console.
|
99
|
-
context_end = first_line.find(LEVEL_CLOSING)
|
100
|
-
elapsed_time_separator = first_line.rfind(ELAPSED_TIME_SEPARATOR)
|
101
|
-
where_separator = first_line.rfind(
|
102
|
-
WHERE_SEPARATOR, context_end, elapsed_time_separator
|
103
|
-
)
|
104
|
-
|
105
|
-
output.stylize(cls.DATE_TIME_COLOR, end=DATE_TIME_LENGTH)
|
106
|
-
output.stylize(
|
107
|
-
cls.LEVEL_COLOR[log_level],
|
108
|
-
start=DATE_TIME_LENGTH,
|
109
|
-
end=context_end + 1,
|
110
|
-
)
|
111
|
-
output.stylize(
|
112
|
-
cls.GRAY_STYLE, start=where_separator, end=elapsed_time_separator
|
113
|
-
)
|
114
|
-
output.stylize(cls.ELAPSED_TIME_COLOR, start=elapsed_time_separator)
|
115
|
-
|
116
|
-
if next_lines is not None:
|
117
|
-
output.append(next_lines)
|
118
|
-
|
119
|
-
output.highlight_words(cls.ACTUAL_PATTERNS, style=cls.ACTUAL_COLOR)
|
120
|
-
output.highlight_words(cls.EXPECTED_PATTERNS, style=cls.EXPECTED_COLOR)
|
121
|
-
|
122
|
-
return output
|
logger_36/type/extension.py
DELETED
@@ -1,122 +0,0 @@
|
|
1
|
-
# Copyright CNRS/Inria/UCA
|
2
|
-
# Contributor(s): Eric Debreuve (since 2023)
|
3
|
-
#
|
4
|
-
# eric.debreuve@cnrs.fr
|
5
|
-
#
|
6
|
-
# This software is governed by the CeCILL license under French law and
|
7
|
-
# abiding by the rules of distribution of free software. You can use,
|
8
|
-
# modify and/ or redistribute the software under the terms of the CeCILL
|
9
|
-
# license as circulated by CEA, CNRS and INRIA at the following URL
|
10
|
-
# "http://www.cecill.info".
|
11
|
-
#
|
12
|
-
# As a counterpart to the access to the source code and rights to copy,
|
13
|
-
# modify and redistribute granted by the license, users are provided only
|
14
|
-
# with a limited warranty and the software's author, the holder of the
|
15
|
-
# economic rights, and the successive licensors have only limited
|
16
|
-
# liability.
|
17
|
-
#
|
18
|
-
# In this respect, the user's attention is drawn to the risks associated
|
19
|
-
# with loading, using, modifying and/or developing or reproducing the
|
20
|
-
# software by the user in light of its specific status of free software,
|
21
|
-
# that may mean that it is complicated to manipulate, and that also
|
22
|
-
# therefore means that it is reserved for developers and experienced
|
23
|
-
# professionals having in-depth computer knowledge. Users are therefore
|
24
|
-
# encouraged to load and test the software's suitability as regards their
|
25
|
-
# requirements in conditions enabling the security of their systems and/or
|
26
|
-
# data to be ensured and, more generally, to use and operate it in the
|
27
|
-
# same conditions as regards security.
|
28
|
-
#
|
29
|
-
# The fact that you are presently reading this means that you have had
|
30
|
-
# knowledge of the CeCILL license and that you accept its terms.
|
31
|
-
|
32
|
-
import logging as lggg
|
33
|
-
import sys as sstm
|
34
|
-
from typing import Callable
|
35
|
-
|
36
|
-
from logger_36.catalog.memory import WithAutoUnit as MemoryWithAutoUnit
|
37
|
-
from logger_36.config import DATE_TIME_FORMAT, MESSAGE_FORMAT
|
38
|
-
from logger_36.constant import LOG_LEVEL_LENGTH, NEXT_LINE_PROLOGUE
|
39
|
-
from logger_36.measure.chronos import ElapsedTime
|
40
|
-
from logger_36.measure.memory import CurrentUsage as CurrentMemoryUsage
|
41
|
-
|
42
|
-
|
43
|
-
class handler_extension_t:
|
44
|
-
__slots__ = ("formatter", "show_memory_usage", "max_memory_usage", "exit_on_error")
|
45
|
-
formatter: lggg.Formatter
|
46
|
-
show_memory_usage: bool
|
47
|
-
max_memory_usage: int
|
48
|
-
exit_on_error: bool
|
49
|
-
|
50
|
-
def __init__(self) -> None:
|
51
|
-
""""""
|
52
|
-
self.formatter = lggg.Formatter(fmt=MESSAGE_FORMAT, datefmt=DATE_TIME_FORMAT)
|
53
|
-
self.show_memory_usage = False
|
54
|
-
self.max_memory_usage = -1
|
55
|
-
self.exit_on_error = False
|
56
|
-
|
57
|
-
def MessageLines(
|
58
|
-
self,
|
59
|
-
record: lggg.LogRecord,
|
60
|
-
/,
|
61
|
-
*,
|
62
|
-
PreProcessed: Callable[[str], str] | None = None,
|
63
|
-
should_fully_format: bool = False,
|
64
|
-
) -> tuple[str, str | None]:
|
65
|
-
"""
|
66
|
-
Note: "message" is not yet an attribute of record (it will be set by format());
|
67
|
-
Use "msg" instead.
|
68
|
-
"""
|
69
|
-
if not isinstance(record.msg, str):
|
70
|
-
record.msg = str(record.msg)
|
71
|
-
if PreProcessed is not None:
|
72
|
-
record.msg = PreProcessed(record.msg)
|
73
|
-
if "\n" in record.msg:
|
74
|
-
original_message = record.msg
|
75
|
-
lines = original_message.splitlines()
|
76
|
-
record.msg = lines[0]
|
77
|
-
next_lines = NEXT_LINE_PROLOGUE.join(lines[1:])
|
78
|
-
next_lines = f"{NEXT_LINE_PROLOGUE}{next_lines}"
|
79
|
-
else:
|
80
|
-
original_message = next_lines = None
|
81
|
-
|
82
|
-
# The record is shared between handlers, so do not re-assign if already there.
|
83
|
-
if not hasattr(record, "elapsed_time"):
|
84
|
-
record.elapsed_time = ElapsedTime()
|
85
|
-
# Re-assign for each handler in case they have different show properties.
|
86
|
-
if self.show_memory_usage:
|
87
|
-
record.memory_usage = self.FormattedMemoryUsage()
|
88
|
-
else:
|
89
|
-
record.memory_usage = ""
|
90
|
-
|
91
|
-
padding = (LOG_LEVEL_LENGTH - record.levelname.__len__() - 1) * " "
|
92
|
-
first_line = self.formatter.format(record).replace("\t", padding)
|
93
|
-
|
94
|
-
# Revert the record message to its original value for subsequent handlers.
|
95
|
-
if original_message is not None:
|
96
|
-
record.msg = original_message
|
97
|
-
|
98
|
-
if should_fully_format:
|
99
|
-
if next_lines is None:
|
100
|
-
return first_line, None
|
101
|
-
else:
|
102
|
-
return f"{first_line}{next_lines}", None
|
103
|
-
else:
|
104
|
-
return first_line, next_lines
|
105
|
-
|
106
|
-
def FormattedMemoryUsage(self) -> str:
|
107
|
-
""""""
|
108
|
-
if self.show_memory_usage:
|
109
|
-
usage = CurrentMemoryUsage()
|
110
|
-
if usage > self.max_memory_usage:
|
111
|
-
self.max_memory_usage = usage
|
112
|
-
|
113
|
-
usage, unit = MemoryWithAutoUnit(usage, 1)
|
114
|
-
|
115
|
-
return f" :{usage}{unit}"
|
116
|
-
else:
|
117
|
-
return ""
|
118
|
-
|
119
|
-
def ExitOrNotIfError(self, record: lggg.LogRecord, /) -> None:
|
120
|
-
""""""
|
121
|
-
if self.exit_on_error and (record.levelno in (lggg.ERROR, lggg.CRITICAL)):
|
122
|
-
sstm.exit(1)
|
logger_36/type/file.py
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
# Copyright CNRS/Inria/UCA
|
2
|
-
# Contributor(s): Eric Debreuve (since 2023)
|
3
|
-
#
|
4
|
-
# eric.debreuve@cnrs.fr
|
5
|
-
#
|
6
|
-
# This software is governed by the CeCILL license under French law and
|
7
|
-
# abiding by the rules of distribution of free software. You can use,
|
8
|
-
# modify and/ or redistribute the software under the terms of the CeCILL
|
9
|
-
# license as circulated by CEA, CNRS and INRIA at the following URL
|
10
|
-
# "http://www.cecill.info".
|
11
|
-
#
|
12
|
-
# As a counterpart to the access to the source code and rights to copy,
|
13
|
-
# modify and redistribute granted by the license, users are provided only
|
14
|
-
# with a limited warranty and the software's author, the holder of the
|
15
|
-
# economic rights, and the successive licensors have only limited
|
16
|
-
# liability.
|
17
|
-
#
|
18
|
-
# In this respect, the user's attention is drawn to the risks associated
|
19
|
-
# with loading, using, modifying and/or developing or reproducing the
|
20
|
-
# software by the user in light of its specific status of free software,
|
21
|
-
# that may mean that it is complicated to manipulate, and that also
|
22
|
-
# therefore means that it is reserved for developers and experienced
|
23
|
-
# professionals having in-depth computer knowledge. Users are therefore
|
24
|
-
# encouraged to load and test the software's suitability as regards their
|
25
|
-
# requirements in conditions enabling the security of their systems and/or
|
26
|
-
# data to be ensured and, more generally, to use and operate it in the
|
27
|
-
# same conditions as regards security.
|
28
|
-
#
|
29
|
-
# The fact that you are presently reading this means that you have had
|
30
|
-
# knowledge of the CeCILL license and that you accept its terms.
|
31
|
-
|
32
|
-
import logging as lggg
|
33
|
-
from pathlib import Path as path_t
|
34
|
-
|
35
|
-
from logger_36.type.extension import handler_extension_t
|
36
|
-
|
37
|
-
|
38
|
-
class file_handler_t(lggg.FileHandler, handler_extension_t):
|
39
|
-
def __init__(self, path: str | path_t, /, *args, **kwargs) -> None:
|
40
|
-
""""""
|
41
|
-
lggg.FileHandler.__init__(self, str(path), *args, **kwargs)
|
42
|
-
handler_extension_t.__init__(self)
|
43
|
-
|
44
|
-
self.setFormatter(self.formatter)
|
45
|
-
|
46
|
-
def emit(self, record: lggg.LogRecord, /) -> None:
|
47
|
-
""""""
|
48
|
-
message, _ = self.MessageLines(record, should_fully_format=True)
|
49
|
-
print(message, file=self.stream)
|
50
|
-
self.stream.flush()
|
51
|
-
|
52
|
-
self.ExitOrNotIfError(record)
|
logger_36/type/generic.py
DELETED
@@ -1,115 +0,0 @@
|
|
1
|
-
# Copyright CNRS/Inria/UCA
|
2
|
-
# Contributor(s): Eric Debreuve (since 2023)
|
3
|
-
#
|
4
|
-
# eric.debreuve@cnrs.fr
|
5
|
-
#
|
6
|
-
# This software is governed by the CeCILL license under French law and
|
7
|
-
# abiding by the rules of distribution of free software. You can use,
|
8
|
-
# modify and/ or redistribute the software under the terms of the CeCILL
|
9
|
-
# license as circulated by CEA, CNRS and INRIA at the following URL
|
10
|
-
# "http://www.cecill.info".
|
11
|
-
#
|
12
|
-
# As a counterpart to the access to the source code and rights to copy,
|
13
|
-
# modify and redistribute granted by the license, users are provided only
|
14
|
-
# with a limited warranty and the software's author, the holder of the
|
15
|
-
# economic rights, and the successive licensors have only limited
|
16
|
-
# liability.
|
17
|
-
#
|
18
|
-
# In this respect, the user's attention is drawn to the risks associated
|
19
|
-
# with loading, using, modifying and/or developing or reproducing the
|
20
|
-
# software by the user in light of its specific status of free software,
|
21
|
-
# that may mean that it is complicated to manipulate, and that also
|
22
|
-
# therefore means that it is reserved for developers and experienced
|
23
|
-
# professionals having in-depth computer knowledge. Users are therefore
|
24
|
-
# encouraged to load and test the software's suitability as regards their
|
25
|
-
# requirements in conditions enabling the security of their systems and/or
|
26
|
-
# data to be ensured and, more generally, to use and operate it in the
|
27
|
-
# same conditions as regards security.
|
28
|
-
#
|
29
|
-
# The fact that you are presently reading this means that you have had
|
30
|
-
# knowledge of the CeCILL license and that you accept its terms.
|
31
|
-
|
32
|
-
import logging as lggg
|
33
|
-
from typing import Callable, Protocol
|
34
|
-
|
35
|
-
from rich.console import Console as console_t
|
36
|
-
from rich.markup import escape as PreProcessedForRich
|
37
|
-
from rich.terminal_theme import DEFAULT_TERMINAL_THEME
|
38
|
-
|
39
|
-
from logger_36.type.console import console_handler_t
|
40
|
-
from logger_36.type.extension import handler_extension_t
|
41
|
-
|
42
|
-
|
43
|
-
class can_show_message_p(Protocol):
|
44
|
-
def Show(self, message: str, /) -> None: ...
|
45
|
-
|
46
|
-
|
47
|
-
class generic_handler_t(lggg.Handler, handler_extension_t):
|
48
|
-
__slots__ = ("console", "Show")
|
49
|
-
console: console_t | None
|
50
|
-
Show: Callable[[str], None]
|
51
|
-
|
52
|
-
def __init__(
|
53
|
-
self,
|
54
|
-
interface: can_show_message_p | Callable[[str], None],
|
55
|
-
/,
|
56
|
-
*args,
|
57
|
-
supports_html: bool = False,
|
58
|
-
**kwargs,
|
59
|
-
) -> None:
|
60
|
-
""""""
|
61
|
-
lggg.Handler.__init__(self, *args, **kwargs)
|
62
|
-
handler_extension_t.__init__(self)
|
63
|
-
|
64
|
-
if supports_html:
|
65
|
-
self.console = console_t(
|
66
|
-
tab_size=console_handler_t.TAB_SIZE,
|
67
|
-
highlight=False,
|
68
|
-
force_terminal=True,
|
69
|
-
)
|
70
|
-
else:
|
71
|
-
self.console = None
|
72
|
-
if hasattr(interface, "Show"):
|
73
|
-
self.Show = interface.Show
|
74
|
-
else:
|
75
|
-
self.Show = interface
|
76
|
-
self.setFormatter(self.formatter)
|
77
|
-
|
78
|
-
def emit(self, record: lggg.LogRecord, /) -> None:
|
79
|
-
""""""
|
80
|
-
if self.console is None:
|
81
|
-
message, _ = self.MessageLines(record, should_fully_format=True)
|
82
|
-
else:
|
83
|
-
first_line, next_lines = self.MessageLines(
|
84
|
-
record, PreProcessed=PreProcessedForRich
|
85
|
-
)
|
86
|
-
highlighted = console_handler_t.HighlightedVersion(
|
87
|
-
first_line, next_lines, record.levelno
|
88
|
-
)
|
89
|
-
segments = self.console.render(highlighted)
|
90
|
-
|
91
|
-
# Inspired from the code of: rich.console.export_html.
|
92
|
-
html_segments = []
|
93
|
-
for text, style, _ in segments:
|
94
|
-
if text == "\n":
|
95
|
-
html_segments.append("\n")
|
96
|
-
else:
|
97
|
-
if style is not None:
|
98
|
-
style = style.get_html_style(DEFAULT_TERMINAL_THEME)
|
99
|
-
if (style is not None) and (style.__len__() > 0):
|
100
|
-
text = f'<span style="{style}">{text}</span>'
|
101
|
-
html_segments.append(text)
|
102
|
-
if html_segments[-1] == "\n":
|
103
|
-
html_segments = html_segments[:-1]
|
104
|
-
|
105
|
-
# /!\ For some reason, the widget splits the message into lines, place each line
|
106
|
-
# inside a pre tag, and set margin-bottom of the first and list lines to 12px.
|
107
|
-
# This can be seen by printing self.contents.toHtml(). To avoid the unwanted
|
108
|
-
# extra margins, margin-bottom is set to 0 below.
|
109
|
-
message = (
|
110
|
-
"<pre style='margin-bottom:0px'>" + "".join(html_segments) + "</pre>"
|
111
|
-
)
|
112
|
-
|
113
|
-
self.Show(message)
|
114
|
-
|
115
|
-
self.ExitOrNotIfError(record)
|