omlish 0.0.0.dev7__py3-none-any.whl → 0.0.0.dev8__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.
- omlish/__about__.py +2 -2
- omlish/lite/logs.py +73 -4
- omlish/lite/marshal.py +3 -1
- omlish/logs/__init__.py +13 -9
- omlish/logs/configs.py +12 -30
- omlish/logs/formatters.py +3 -53
- {omlish-0.0.0.dev7.dist-info → omlish-0.0.0.dev8.dist-info}/METADATA +1 -1
- {omlish-0.0.0.dev7.dist-info → omlish-0.0.0.dev8.dist-info}/RECORD +11 -12
- omlish/logs/filters.py +0 -11
- {omlish-0.0.0.dev7.dist-info → omlish-0.0.0.dev8.dist-info}/LICENSE +0 -0
- {omlish-0.0.0.dev7.dist-info → omlish-0.0.0.dev8.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev7.dist-info → omlish-0.0.0.dev8.dist-info}/top_level.txt +0 -0
omlish/__about__.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
__version__ = '0.0.0.
|
|
1
|
+
__version__ = '0.0.0.dev8'
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
#
|
|
@@ -105,6 +105,6 @@ class SetuptoolsBase:
|
|
|
105
105
|
|
|
106
106
|
class Setuptools(SetuptoolsBase):
|
|
107
107
|
find_packages = {
|
|
108
|
-
'include': [
|
|
108
|
+
'include': [Project.name, f'{Project.name}.*'],
|
|
109
109
|
'exclude': [*SetuptoolsBase.find_packages['exclude']],
|
|
110
110
|
}
|
omlish/lite/logs.py
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
"""
|
|
2
2
|
TODO:
|
|
3
|
+
- translate json keys
|
|
3
4
|
- debug
|
|
4
5
|
"""
|
|
5
|
-
# ruff: noqa: UP007
|
|
6
|
+
# ruff: noqa: UP006 UP007 N802
|
|
7
|
+
import datetime
|
|
6
8
|
import logging
|
|
9
|
+
import threading
|
|
7
10
|
import typing as ta
|
|
8
11
|
|
|
9
12
|
from .json import json_dumps_compact
|
|
@@ -12,6 +15,19 @@ from .json import json_dumps_compact
|
|
|
12
15
|
log = logging.getLogger(__name__)
|
|
13
16
|
|
|
14
17
|
|
|
18
|
+
##
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class TidLogFilter(logging.Filter):
|
|
22
|
+
|
|
23
|
+
def filter(self, record):
|
|
24
|
+
record.tid = threading.get_native_id()
|
|
25
|
+
return True
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
##
|
|
29
|
+
|
|
30
|
+
|
|
15
31
|
class JsonLogFormatter(logging.Formatter):
|
|
16
32
|
|
|
17
33
|
KEYS: ta.Mapping[str, bool] = {
|
|
@@ -47,6 +63,59 @@ class JsonLogFormatter(logging.Formatter):
|
|
|
47
63
|
return json_dumps_compact(dct)
|
|
48
64
|
|
|
49
65
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
66
|
+
##
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
STANDARD_LOG_FORMAT_PARTS = [
|
|
70
|
+
('asctime', '%(asctime)-15s'),
|
|
71
|
+
('process', 'pid=%(process)-6s'),
|
|
72
|
+
('thread', 'tid=%(thread)-16s'),
|
|
73
|
+
('levelname', '%(levelname)-8s'),
|
|
74
|
+
('name', '%(name)s'),
|
|
75
|
+
('separator', '::'),
|
|
76
|
+
('message', '%(message)s'),
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class StandardLogFormatter(logging.Formatter):
|
|
81
|
+
|
|
82
|
+
@staticmethod
|
|
83
|
+
def build_log_format(parts: ta.Iterable[ta.Tuple[str, str]]) -> str:
|
|
84
|
+
return ' '.join(v for k, v in parts)
|
|
85
|
+
|
|
86
|
+
converter = datetime.datetime.fromtimestamp # type: ignore
|
|
87
|
+
|
|
88
|
+
def formatTime(self, record, datefmt=None):
|
|
89
|
+
ct = self.converter(record.created) # type: ignore
|
|
90
|
+
if datefmt:
|
|
91
|
+
return ct.strftime(datefmt) # noqa
|
|
92
|
+
else:
|
|
93
|
+
t = ct.strftime("%Y-%m-%d %H:%M:%S") # noqa
|
|
94
|
+
return '%s.%03d' % (t, record.msecs)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
##
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def configure_standard_logging(
|
|
101
|
+
level: ta.Union[int, str] = logging.INFO,
|
|
102
|
+
*,
|
|
103
|
+
json: bool = False,
|
|
104
|
+
) -> logging.Handler:
|
|
105
|
+
handler = logging.StreamHandler()
|
|
106
|
+
|
|
107
|
+
formatter: logging.Formatter
|
|
108
|
+
if json:
|
|
109
|
+
formatter = JsonLogFormatter()
|
|
110
|
+
else:
|
|
111
|
+
formatter = StandardLogFormatter(StandardLogFormatter.build_log_format(STANDARD_LOG_FORMAT_PARTS))
|
|
112
|
+
handler.setFormatter(formatter)
|
|
113
|
+
|
|
114
|
+
handler.addFilter(TidLogFilter())
|
|
115
|
+
|
|
116
|
+
logging.root.addHandler(handler)
|
|
117
|
+
|
|
118
|
+
if level is not None:
|
|
119
|
+
logging.root.setLevel(level)
|
|
120
|
+
|
|
121
|
+
return handler
|
omlish/lite/marshal.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
TODO:
|
|
3
3
|
- pickle stdlib objs? have to pin to 3.8 pickle protocol, will be cross-version
|
|
4
|
+
- nonstrict toggle
|
|
4
5
|
"""
|
|
5
6
|
# ruff: noqa: UP006 UP007
|
|
6
7
|
import abc
|
|
@@ -143,12 +144,13 @@ class IterableObjMarshaler(ObjMarshaler):
|
|
|
143
144
|
class DataclassObjMarshaler(ObjMarshaler):
|
|
144
145
|
ty: type
|
|
145
146
|
fs: ta.Mapping[str, ObjMarshaler]
|
|
147
|
+
nonstrict: bool = False
|
|
146
148
|
|
|
147
149
|
def marshal(self, o: ta.Any) -> ta.Any:
|
|
148
150
|
return {k: m.marshal(getattr(o, k)) for k, m in self.fs.items()}
|
|
149
151
|
|
|
150
152
|
def unmarshal(self, o: ta.Any) -> ta.Any:
|
|
151
|
-
return self.ty(**{k: self.fs[k].unmarshal(v) for k, v in o.items()})
|
|
153
|
+
return self.ty(**{k: self.fs[k].unmarshal(v) for k, v in o.items() if self.nonstrict or k in self.fs})
|
|
152
154
|
|
|
153
155
|
|
|
154
156
|
@dc.dataclass(frozen=True)
|
omlish/logs/__init__.py
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
from .configs import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
from .
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
from .configs import ( # noqa
|
|
2
|
+
configure_standard_logging,
|
|
3
|
+
)
|
|
4
|
+
|
|
5
|
+
from .formatters import ( # noqa
|
|
6
|
+
ColorLogFormatter,
|
|
7
|
+
JsonLogFormatter,
|
|
8
|
+
StandardLogFormatter,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
from .utils import ( # noqa
|
|
12
|
+
error_logging,
|
|
13
|
+
)
|
omlish/logs/configs.py
CHANGED
|
@@ -2,9 +2,10 @@ import dataclasses as dc
|
|
|
2
2
|
import logging
|
|
3
3
|
import typing as ta
|
|
4
4
|
|
|
5
|
-
from .
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
from ..lite.logs import configure_standard_logging as configure_lite_standard_logging
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
##
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
NOISY_LOGGERS: set[str] = {
|
|
@@ -16,6 +17,9 @@ NOISY_LOGGERS: set[str] = {
|
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
|
|
20
|
+
##
|
|
21
|
+
|
|
22
|
+
|
|
19
23
|
@dc.dataclass()
|
|
20
24
|
class DictConfig:
|
|
21
25
|
version: int = 1
|
|
@@ -33,19 +37,8 @@ FormatterConfig = dict[str, ta.Any]
|
|
|
33
37
|
HandlerConfig = dict[str, ta.Any]
|
|
34
38
|
LoggerConfig = dict[str, ta.Any]
|
|
35
39
|
|
|
36
|
-
STANDARD_LOG_FORMAT_PARTS = [
|
|
37
|
-
('asctime', '%(asctime)-15s'),
|
|
38
|
-
('process', 'pid=%(process)-6s'),
|
|
39
|
-
('thread', 'tid=%(thread)-16s'),
|
|
40
|
-
('levelname', '%(levelname)-8s'),
|
|
41
|
-
('name', '%(name)s'),
|
|
42
|
-
('separator', '::'),
|
|
43
|
-
('message', '%(message)s'),
|
|
44
|
-
]
|
|
45
|
-
|
|
46
40
|
|
|
47
|
-
|
|
48
|
-
return ' '.join(v for k, v in parts)
|
|
41
|
+
##
|
|
49
42
|
|
|
50
43
|
|
|
51
44
|
def configure_standard_logging(
|
|
@@ -53,21 +46,10 @@ def configure_standard_logging(
|
|
|
53
46
|
*,
|
|
54
47
|
json: bool = False,
|
|
55
48
|
) -> logging.Handler:
|
|
56
|
-
handler =
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
formatter = JsonLogFormatter()
|
|
61
|
-
else:
|
|
62
|
-
formatter = StandardLogFormatter(build_log_format(STANDARD_LOG_FORMAT_PARTS))
|
|
63
|
-
handler.setFormatter(formatter)
|
|
64
|
-
|
|
65
|
-
handler.addFilter(TidFilter())
|
|
66
|
-
|
|
67
|
-
logging.root.addHandler(handler)
|
|
68
|
-
|
|
69
|
-
if level is not None:
|
|
70
|
-
logging.root.setLevel(level)
|
|
49
|
+
handler = configure_lite_standard_logging(
|
|
50
|
+
level,
|
|
51
|
+
json=json,
|
|
52
|
+
)
|
|
71
53
|
|
|
72
54
|
for noisy_logger in NOISY_LOGGERS:
|
|
73
55
|
logging.getLogger(noisy_logger).setLevel(logging.WARNING)
|
omlish/logs/formatters.py
CHANGED
|
@@ -1,25 +1,10 @@
|
|
|
1
|
-
# ruff: noqa: ANN201
|
|
2
|
-
# ruff: noqa: N802
|
|
3
|
-
|
|
4
|
-
import datetime
|
|
1
|
+
# ruff: noqa: ANN201 N802
|
|
5
2
|
import logging
|
|
6
3
|
import typing as ta
|
|
7
4
|
|
|
8
5
|
from .. import term
|
|
9
|
-
from ..
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class StandardLogFormatter(logging.Formatter):
|
|
13
|
-
|
|
14
|
-
converter = datetime.datetime.fromtimestamp # type: ignore
|
|
15
|
-
|
|
16
|
-
def formatTime(self, record, datefmt=None):
|
|
17
|
-
ct = self.converter(record.created) # type: ignore
|
|
18
|
-
if datefmt:
|
|
19
|
-
return ct.strftime(datefmt) # noqa
|
|
20
|
-
else:
|
|
21
|
-
t = ct.strftime("%Y-%m-%d %H:%M:%S") # noqa
|
|
22
|
-
return '%s.%03d' % (t, record.msecs)
|
|
6
|
+
from ..lite.logs import JsonLogFormatter # noqa
|
|
7
|
+
from ..lite.logs import StandardLogFormatter
|
|
23
8
|
|
|
24
9
|
|
|
25
10
|
class ColorLogFormatter(StandardLogFormatter):
|
|
@@ -39,38 +24,3 @@ class ColorLogFormatter(StandardLogFormatter):
|
|
|
39
24
|
else:
|
|
40
25
|
buf = term.SGR(c) + buf + term.SGR(term.SGRs.RESET)
|
|
41
26
|
return buf
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
class JsonLogFormatter(logging.Formatter):
|
|
45
|
-
|
|
46
|
-
KEYS: ta.Mapping[str, bool] = {
|
|
47
|
-
'name': False,
|
|
48
|
-
'msg': False,
|
|
49
|
-
'args': False,
|
|
50
|
-
'levelname': False,
|
|
51
|
-
'levelno': False,
|
|
52
|
-
'pathname': False,
|
|
53
|
-
'filename': False,
|
|
54
|
-
'module': False,
|
|
55
|
-
'exc_info': True,
|
|
56
|
-
'exc_text': True,
|
|
57
|
-
'stack_info': True,
|
|
58
|
-
'lineno': False,
|
|
59
|
-
'funcName': False,
|
|
60
|
-
'created': False,
|
|
61
|
-
'msecs': False,
|
|
62
|
-
'relativeCreated': False,
|
|
63
|
-
'thread': False,
|
|
64
|
-
'threadName': False,
|
|
65
|
-
'processName': False,
|
|
66
|
-
'process': False,
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
def format(self, record: logging.LogRecord) -> str:
|
|
70
|
-
dct = {
|
|
71
|
-
k: v
|
|
72
|
-
for k, o in self.KEYS.items()
|
|
73
|
-
for v in [getattr(record, k)]
|
|
74
|
-
if not (o and v is None)
|
|
75
|
-
}
|
|
76
|
-
return json.dumps_compact(dct)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
omlish/__about__.py,sha256=
|
|
1
|
+
omlish/__about__.py,sha256=kOS_wa2wbqZj1jzr4S6oJDbqf_7ODbXbHEEgXAsBXCI,2279
|
|
2
2
|
omlish/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
3
|
omlish/argparse.py,sha256=QRQmX9G0-L_nATkFtGHvpd4qrpYzKATdjuFLbBqzJPM,6224
|
|
4
4
|
omlish/bootstrap.py,sha256=3pGNiHlUcQl81q76_Wesd4pblmy82EOKkcdgectF15Q,18820
|
|
@@ -182,18 +182,17 @@ omlish/lite/cached.py,sha256=dUm647FbIsoxWT23XUFM51F7i-C2Buxr5b5zzgbCtQI,546
|
|
|
182
182
|
omlish/lite/check.py,sha256=DR3Zj-7o4Y7pNheln68nN_BdX9zaotGQ2y8v97GDiWQ,535
|
|
183
183
|
omlish/lite/contextmanagers.py,sha256=HnQJiyrOmSvTL22XRJrFl5CLpCyHD9fsntEUAr9G-60,427
|
|
184
184
|
omlish/lite/json.py,sha256=7-02Ny4fq-6YAu5ynvqoijhuYXWpLmfCI19GUeZnb1c,740
|
|
185
|
-
omlish/lite/logs.py,sha256=
|
|
186
|
-
omlish/lite/marshal.py,sha256=
|
|
185
|
+
omlish/lite/logs.py,sha256=VrZMlHgUK6o1zHaKNgHLecIozv49cZ8vwY43wJ_6-pE,2646
|
|
186
|
+
omlish/lite/marshal.py,sha256=5uwri-KzPiktnbYORkGXcJ4kulZvp_nS4MxPsU1Y-G0,8608
|
|
187
187
|
omlish/lite/reflect.py,sha256=9QYJwdINraq1JNMEgvoqeSlVvRRgOXpxAkpgX8EgRXc,1307
|
|
188
188
|
omlish/lite/runtime.py,sha256=VUhmNQvwf8QzkWSKj4Q0ReieJA_PzHaJNRBivfTseow,452
|
|
189
189
|
omlish/lite/secrets.py,sha256=ToaS10AcH7UOFi7XHKp2mikLErp1Rrne5mtFJ388hF8,462
|
|
190
190
|
omlish/lite/strings.py,sha256=9dO_A6EkhcTZ2xmOUGSOMT-mx9BnoOzYu1-ocSrDJaA,670
|
|
191
191
|
omlish/lite/subprocesses.py,sha256=KuGV3ImehMjCUK0JoV3pUtG_7o5wei1lRDn9HxzByAg,3063
|
|
192
|
-
omlish/logs/__init__.py,sha256=
|
|
192
|
+
omlish/logs/__init__.py,sha256=UPMdG3mbUm4PUJw6muXs4dk-uNE0aMDj_XebKCa-Wpk,224
|
|
193
193
|
omlish/logs/_abc.py,sha256=UgrCUQVUi_PvT3p1CEkb3P74CFrFcZq2AFby3GEUv9M,5974
|
|
194
|
-
omlish/logs/configs.py,sha256=
|
|
195
|
-
omlish/logs/
|
|
196
|
-
omlish/logs/formatters.py,sha256=lI2KB8w_PDVX4YkWkImtki0MRKN2dlT6F2KTNEhYRJA,1970
|
|
194
|
+
omlish/logs/configs.py,sha256=Dnd5nm6OUD_n4YDtP4VuDo8flIofU-xf7xlw-t9FVv8,1285
|
|
195
|
+
omlish/logs/formatters.py,sha256=AFs9C6-qrFkgXZ0nL39wih_LGck1Tc79alvGyibBdQo,720
|
|
197
196
|
omlish/logs/utils.py,sha256=MgGovbP0zUrZ3FGD3qYNQWn-l0jy0Y0bStcQvv5BOmQ,391
|
|
198
197
|
omlish/marshal/__init__.py,sha256=52Jl7SgSA0Ei7TBrNmcbXCcICiU6oBS9NhjGg8zvgKI,1383
|
|
199
198
|
omlish/marshal/any.py,sha256=e82OyYK3Emm1P1ClnsnxP7fIWC2iNVyW0H5nK4mLmWM,779
|
|
@@ -261,8 +260,8 @@ omlish/text/delimit.py,sha256=ubPXcXQmtbOVrUsNh5gH1mDq5H-n1y2R4cPL5_DQf68,4928
|
|
|
261
260
|
omlish/text/glyphsplit.py,sha256=Ug-dPRO7x-OrNNr8g1y6DotSZ2KH0S-VcOmUobwa4B0,3296
|
|
262
261
|
omlish/text/indent.py,sha256=6Jj6TFY9unaPa4xPzrnZemJ-fHsV53IamP93XGjSUHs,1274
|
|
263
262
|
omlish/text/parts.py,sha256=KGgo0wHOIMVMZtDso-rhSWKAcAkYAH2IGpg9tULabu8,6505
|
|
264
|
-
omlish-0.0.0.
|
|
265
|
-
omlish-0.0.0.
|
|
266
|
-
omlish-0.0.0.
|
|
267
|
-
omlish-0.0.0.
|
|
268
|
-
omlish-0.0.0.
|
|
263
|
+
omlish-0.0.0.dev8.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
|
264
|
+
omlish-0.0.0.dev8.dist-info/METADATA,sha256=0U0qkYBESUwpP81Sy37DAXVODIDrZTiEkU97tEQPpxk,2121
|
|
265
|
+
omlish-0.0.0.dev8.dist-info/WHEEL,sha256=Mdi9PDNwEZptOjTlUcAth7XJDFtKrHYaQMPulZeBCiQ,91
|
|
266
|
+
omlish-0.0.0.dev8.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
|
|
267
|
+
omlish-0.0.0.dev8.dist-info/RECORD,,
|
omlish/logs/filters.py
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|