omlish 0.0.0.dev484__py3-none-any.whl → 0.0.0.dev506__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.
Potentially problematic release.
This version of omlish might be problematic. Click here for more details.
- omlish/CODESTYLE.md +345 -0
- omlish/README.md +199 -0
- omlish/__about__.py +12 -5
- omlish/_check.cc +209 -0
- omlish/check.py +11 -0
- omlish/dataclasses/__init__.py +4 -0
- omlish/dataclasses/impl/concerns/frozen.py +4 -1
- omlish/dataclasses/impl/generation/plans.py +2 -17
- omlish/dataclasses/impl/generation/processor.py +2 -2
- omlish/dataclasses/impl/processing/driving.py +13 -1
- omlish/dataclasses/tools/replace.py +27 -0
- omlish/diag/_pycharm/runhack.py +1 -1
- omlish/dispatch/functions.py +1 -1
- omlish/formats/json/stream/lexing.py +13 -5
- omlish/formats/json/stream/parsing.py +1 -1
- omlish/inject/README.md +430 -0
- omlish/inject/__init__.py +20 -11
- omlish/inject/_dataclasses.py +1545 -1383
- omlish/inject/binder.py +7 -4
- omlish/inject/eagers.py +2 -4
- omlish/inject/elements.py +4 -0
- omlish/inject/helpers/late.py +76 -0
- omlish/inject/{managed.py → helpers/managed.py} +37 -34
- omlish/inject/impl/elements.py +7 -4
- omlish/inject/impl/injector.py +14 -26
- omlish/inject/impl/inspect.py +0 -8
- omlish/inject/impl/origins.py +1 -0
- omlish/inject/impl/privates.py +2 -6
- omlish/inject/impl/providers.py +0 -4
- omlish/inject/impl/scopes.py +14 -18
- omlish/inject/inspect.py +10 -1
- omlish/inject/multis.py +0 -3
- omlish/inject/scopes.py +7 -5
- omlish/io/buffers.py +35 -8
- omlish/lang/__init__.py +10 -0
- omlish/lang/classes/simple.py +2 -1
- omlish/lang/iterables.py +6 -0
- omlish/lang/objects.py +13 -0
- omlish/lang/outcomes.py +1 -1
- omlish/lang/recursion.py +1 -1
- omlish/lang/sequences.py +33 -0
- omlish/lifecycles/README.md +30 -0
- omlish/lifecycles/__init__.py +87 -13
- omlish/lifecycles/_dataclasses.py +1388 -0
- omlish/lifecycles/base.py +178 -64
- omlish/lifecycles/contextmanagers.py +113 -4
- omlish/lifecycles/controller.py +150 -87
- omlish/lifecycles/injection.py +143 -0
- omlish/lifecycles/listeners.py +56 -0
- omlish/lifecycles/managed.py +142 -0
- omlish/lifecycles/manager.py +218 -93
- omlish/lifecycles/states.py +2 -0
- omlish/lifecycles/transitions.py +3 -0
- omlish/lifecycles/unwrap.py +57 -0
- omlish/lite/maybes.py +7 -0
- omlish/lite/typing.py +33 -0
- omlish/logs/_amalg.py +1 -1
- omlish/logs/all.py +36 -11
- omlish/logs/asyncs.py +73 -0
- omlish/logs/base.py +101 -12
- omlish/logs/bisync.py +99 -0
- omlish/logs/contexts.py +4 -1
- omlish/logs/lists.py +125 -0
- omlish/logs/modules.py +19 -1
- omlish/logs/std/loggers.py +6 -1
- omlish/logs/std/noisy.py +11 -9
- omlish/logs/{standard.py → std/standard.py} +3 -4
- omlish/logs/utils.py +16 -1
- omlish/marshal/_dataclasses.py +813 -813
- omlish/reflect/__init__.py +43 -26
- omlish/reflect/ops.py +10 -1
- omlish/specs/jmespath/_dataclasses.py +597 -597
- omlish/specs/jsonschema/keywords/_dataclasses.py +244 -244
- omlish/sql/__init__.py +24 -5
- omlish/sql/api/dbapi.py +1 -1
- omlish/sql/dbapi/__init__.py +15 -0
- omlish/sql/{dbapi.py → dbapi/drivers.py} +2 -2
- omlish/sql/queries/__init__.py +3 -0
- omlish/testing/pytest/plugins/asyncs/plugin.py +2 -0
- omlish/text/docwrap/cli.py +5 -0
- omlish/typedvalues/_collection.cc +500 -0
- omlish/typedvalues/collection.py +159 -62
- omlish/typedvalues/generic.py +5 -4
- omlish/typedvalues/values.py +6 -0
- {omlish-0.0.0.dev484.dist-info → omlish-0.0.0.dev506.dist-info}/METADATA +14 -9
- {omlish-0.0.0.dev484.dist-info → omlish-0.0.0.dev506.dist-info}/RECORD +92 -77
- omlish/lifecycles/abstract.py +0 -86
- /omlish/inject/{impl → helpers}/proxy.py +0 -0
- /omlish/sql/{abc.py → dbapi/abc.py} +0 -0
- {omlish-0.0.0.dev484.dist-info → omlish-0.0.0.dev506.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev484.dist-info → omlish-0.0.0.dev506.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev484.dist-info → omlish-0.0.0.dev506.dist-info}/licenses/LICENSE +0 -0
- {omlish-0.0.0.dev484.dist-info → omlish-0.0.0.dev506.dist-info}/top_level.txt +0 -0
omlish/logs/base.py
CHANGED
|
@@ -40,6 +40,11 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
40
40
|
|
|
41
41
|
##
|
|
42
42
|
|
|
43
|
+
# This will be 1 for [Sync]Logger and 0 for AsyncLogger - in sync loggers these methods remain present on the stack,
|
|
44
|
+
# in async loggers they return a coroutine to be awaited and thus aren't actually present when said coroutine is
|
|
45
|
+
# awaited.
|
|
46
|
+
_level_proxy_method_stack_offset: int
|
|
47
|
+
|
|
43
48
|
@ta.overload
|
|
44
49
|
def log(self, level: LogLevel, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T:
|
|
45
50
|
...
|
|
@@ -54,7 +59,14 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
54
59
|
|
|
55
60
|
@ta.final
|
|
56
61
|
def log(self, level: LogLevel, *args, **kwargs):
|
|
57
|
-
return self._log(
|
|
62
|
+
return self._log(
|
|
63
|
+
CaptureLoggingContextImpl(
|
|
64
|
+
level,
|
|
65
|
+
stack_offset=self._level_proxy_method_stack_offset,
|
|
66
|
+
),
|
|
67
|
+
*args,
|
|
68
|
+
**kwargs,
|
|
69
|
+
)
|
|
58
70
|
|
|
59
71
|
#
|
|
60
72
|
|
|
@@ -72,7 +84,14 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
72
84
|
|
|
73
85
|
@ta.final
|
|
74
86
|
def debug(self, *args, **kwargs):
|
|
75
|
-
return self._log(
|
|
87
|
+
return self._log(
|
|
88
|
+
CaptureLoggingContextImpl(
|
|
89
|
+
NamedLogLevel.DEBUG,
|
|
90
|
+
stack_offset=self._level_proxy_method_stack_offset,
|
|
91
|
+
),
|
|
92
|
+
*args,
|
|
93
|
+
**kwargs,
|
|
94
|
+
)
|
|
76
95
|
|
|
77
96
|
#
|
|
78
97
|
|
|
@@ -90,7 +109,14 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
90
109
|
|
|
91
110
|
@ta.final
|
|
92
111
|
def info(self, *args, **kwargs):
|
|
93
|
-
return self._log(
|
|
112
|
+
return self._log(
|
|
113
|
+
CaptureLoggingContextImpl(
|
|
114
|
+
NamedLogLevel.INFO,
|
|
115
|
+
stack_offset=self._level_proxy_method_stack_offset,
|
|
116
|
+
),
|
|
117
|
+
*args,
|
|
118
|
+
**kwargs,
|
|
119
|
+
)
|
|
94
120
|
|
|
95
121
|
#
|
|
96
122
|
|
|
@@ -108,7 +134,14 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
108
134
|
|
|
109
135
|
@ta.final
|
|
110
136
|
def warning(self, *args, **kwargs):
|
|
111
|
-
return self._log(
|
|
137
|
+
return self._log(
|
|
138
|
+
CaptureLoggingContextImpl(
|
|
139
|
+
NamedLogLevel.WARNING,
|
|
140
|
+
stack_offset=self._level_proxy_method_stack_offset,
|
|
141
|
+
),
|
|
142
|
+
*args,
|
|
143
|
+
**kwargs,
|
|
144
|
+
)
|
|
112
145
|
|
|
113
146
|
#
|
|
114
147
|
|
|
@@ -126,7 +159,14 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
126
159
|
|
|
127
160
|
@ta.final
|
|
128
161
|
def error(self, *args, **kwargs):
|
|
129
|
-
return self._log(
|
|
162
|
+
return self._log(
|
|
163
|
+
CaptureLoggingContextImpl(
|
|
164
|
+
NamedLogLevel.ERROR,
|
|
165
|
+
stack_offset=self._level_proxy_method_stack_offset,
|
|
166
|
+
),
|
|
167
|
+
*args,
|
|
168
|
+
**kwargs,
|
|
169
|
+
)
|
|
130
170
|
|
|
131
171
|
#
|
|
132
172
|
|
|
@@ -144,7 +184,15 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
144
184
|
|
|
145
185
|
@ta.final
|
|
146
186
|
def exception(self, *args, exc_info: LoggingExcInfoArg = True, **kwargs):
|
|
147
|
-
return self._log(
|
|
187
|
+
return self._log(
|
|
188
|
+
CaptureLoggingContextImpl(
|
|
189
|
+
NamedLogLevel.ERROR,
|
|
190
|
+
exc_info=exc_info,
|
|
191
|
+
stack_offset=self._level_proxy_method_stack_offset,
|
|
192
|
+
),
|
|
193
|
+
*args,
|
|
194
|
+
**kwargs,
|
|
195
|
+
)
|
|
148
196
|
|
|
149
197
|
#
|
|
150
198
|
|
|
@@ -162,24 +210,53 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
162
210
|
|
|
163
211
|
@ta.final
|
|
164
212
|
def critical(self, *args, **kwargs):
|
|
165
|
-
return self._log(
|
|
213
|
+
return self._log(
|
|
214
|
+
CaptureLoggingContextImpl(
|
|
215
|
+
NamedLogLevel.CRITICAL,
|
|
216
|
+
stack_offset=self._level_proxy_method_stack_offset,
|
|
217
|
+
),
|
|
218
|
+
*args,
|
|
219
|
+
**kwargs,
|
|
220
|
+
)
|
|
166
221
|
|
|
167
222
|
##
|
|
168
223
|
|
|
169
224
|
@abc.abstractmethod
|
|
170
|
-
def _log(
|
|
225
|
+
def _log(
|
|
226
|
+
self,
|
|
227
|
+
ctx: CaptureLoggingContext,
|
|
228
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
229
|
+
*args: ta.Any,
|
|
230
|
+
**kwargs: ta.Any,
|
|
231
|
+
) -> T:
|
|
171
232
|
raise NotImplementedError
|
|
172
233
|
|
|
173
234
|
|
|
174
235
|
class Logger(AnyLogger[None], Abstract):
|
|
236
|
+
_level_proxy_method_stack_offset: int = 1
|
|
237
|
+
|
|
175
238
|
@abc.abstractmethod
|
|
176
|
-
def _log(
|
|
239
|
+
def _log(
|
|
240
|
+
self,
|
|
241
|
+
ctx: CaptureLoggingContext,
|
|
242
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
243
|
+
*args: ta.Any,
|
|
244
|
+
**kwargs: ta.Any,
|
|
245
|
+
) -> None:
|
|
177
246
|
raise NotImplementedError
|
|
178
247
|
|
|
179
248
|
|
|
180
249
|
class AsyncLogger(AnyLogger[ta.Awaitable[None]], Abstract):
|
|
250
|
+
_level_proxy_method_stack_offset: int = 0
|
|
251
|
+
|
|
181
252
|
@abc.abstractmethod
|
|
182
|
-
def _log(
|
|
253
|
+
def _log(
|
|
254
|
+
self,
|
|
255
|
+
ctx: CaptureLoggingContext,
|
|
256
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
257
|
+
*args: ta.Any,
|
|
258
|
+
**kwargs: ta.Any,
|
|
259
|
+
) -> ta.Awaitable[None]:
|
|
183
260
|
raise NotImplementedError
|
|
184
261
|
|
|
185
262
|
|
|
@@ -194,11 +271,23 @@ class AnyNopLogger(AnyLogger[T], Abstract):
|
|
|
194
271
|
|
|
195
272
|
@ta.final
|
|
196
273
|
class NopLogger(AnyNopLogger[None], Logger):
|
|
197
|
-
def _log(
|
|
274
|
+
def _log(
|
|
275
|
+
self,
|
|
276
|
+
ctx: CaptureLoggingContext,
|
|
277
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
278
|
+
*args: ta.Any,
|
|
279
|
+
**kwargs: ta.Any,
|
|
280
|
+
) -> None:
|
|
198
281
|
pass
|
|
199
282
|
|
|
200
283
|
|
|
201
284
|
@ta.final
|
|
202
285
|
class AsyncNopLogger(AnyNopLogger[ta.Awaitable[None]], AsyncLogger):
|
|
203
|
-
async def _log(
|
|
286
|
+
async def _log(
|
|
287
|
+
self,
|
|
288
|
+
ctx: CaptureLoggingContext,
|
|
289
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
290
|
+
*args: ta.Any,
|
|
291
|
+
**kwargs: ta.Any,
|
|
292
|
+
) -> None:
|
|
204
293
|
pass
|
omlish/logs/bisync.py
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
import typing as ta
|
|
3
|
+
|
|
4
|
+
from .. import check
|
|
5
|
+
from .. import lang
|
|
6
|
+
from .base import AsyncLogger
|
|
7
|
+
from .base import Logger
|
|
8
|
+
from .base import LoggingMsgFn
|
|
9
|
+
from .contexts import CaptureLoggingContext
|
|
10
|
+
from .contexts import CaptureLoggingContextImpl
|
|
11
|
+
from .levels import LogLevel
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
##
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class BisyncLogger(Logger, lang.Abstract):
|
|
18
|
+
@property
|
|
19
|
+
@abc.abstractmethod
|
|
20
|
+
def a(self) -> 'BisyncAsyncLogger':
|
|
21
|
+
raise NotImplementedError
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class BisyncAsyncLogger(AsyncLogger, lang.Abstract):
|
|
25
|
+
@property
|
|
26
|
+
@abc.abstractmethod
|
|
27
|
+
def s(self) -> BisyncLogger:
|
|
28
|
+
raise NotImplementedError
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
##
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class _BisyncLoggerImpl(BisyncLogger, lang.Final):
|
|
35
|
+
def __init__(self, u: 'Logger') -> None:
|
|
36
|
+
super().__init__()
|
|
37
|
+
|
|
38
|
+
self._u = u
|
|
39
|
+
|
|
40
|
+
_a: 'BisyncAsyncLogger'
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def a(self) -> BisyncAsyncLogger:
|
|
44
|
+
return self._a
|
|
45
|
+
|
|
46
|
+
def get_effective_level(self) -> LogLevel:
|
|
47
|
+
return self._u.get_effective_level()
|
|
48
|
+
|
|
49
|
+
def _log(
|
|
50
|
+
self,
|
|
51
|
+
ctx: CaptureLoggingContext,
|
|
52
|
+
msg: ta.Union[str, tuple, LoggingMsgFn], # noqa
|
|
53
|
+
*args: ta.Any,
|
|
54
|
+
**kwargs: ta.Any,
|
|
55
|
+
) -> None:
|
|
56
|
+
return self._u._log( # noqa
|
|
57
|
+
check.isinstance(ctx, CaptureLoggingContextImpl).inc_stack_offset(),
|
|
58
|
+
msg,
|
|
59
|
+
*args,
|
|
60
|
+
**kwargs,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class _BisyncAsyncLoggerImpl(BisyncAsyncLogger, lang.Final):
|
|
65
|
+
def __init__(self, u: 'AsyncLogger') -> None:
|
|
66
|
+
super().__init__()
|
|
67
|
+
|
|
68
|
+
self._u = u
|
|
69
|
+
|
|
70
|
+
_s: BisyncLogger
|
|
71
|
+
|
|
72
|
+
@property
|
|
73
|
+
def s(self) -> BisyncLogger:
|
|
74
|
+
return self._s
|
|
75
|
+
|
|
76
|
+
def get_effective_level(self) -> LogLevel:
|
|
77
|
+
return self._u.get_effective_level()
|
|
78
|
+
|
|
79
|
+
async def _log(
|
|
80
|
+
self,
|
|
81
|
+
ctx: CaptureLoggingContext,
|
|
82
|
+
msg: ta.Union[str, tuple, LoggingMsgFn], # noqa
|
|
83
|
+
*args: ta.Any,
|
|
84
|
+
**kwargs: ta.Any,
|
|
85
|
+
) -> None:
|
|
86
|
+
return await self._u._log( # noqa
|
|
87
|
+
check.isinstance(ctx, CaptureLoggingContextImpl).inc_stack_offset(),
|
|
88
|
+
msg,
|
|
89
|
+
*args,
|
|
90
|
+
**kwargs,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def make_bisync_logger(log: Logger, alog: AsyncLogger) -> BisyncLogger:
|
|
95
|
+
s = _BisyncLoggerImpl(log)
|
|
96
|
+
a = _BisyncAsyncLoggerImpl(alog)
|
|
97
|
+
s._a = a # noqa
|
|
98
|
+
a._s = s # noqa
|
|
99
|
+
return s
|
omlish/logs/contexts.py
CHANGED
|
@@ -118,6 +118,9 @@ class CaptureLoggingContextImpl(CaptureLoggingContext):
|
|
|
118
118
|
self._infos[type(info)] = info
|
|
119
119
|
return self
|
|
120
120
|
|
|
121
|
+
def get_infos(self) -> ta.Mapping[ta.Type[LoggingContextInfo], LoggingContextInfo]:
|
|
122
|
+
return self._infos
|
|
123
|
+
|
|
121
124
|
def get_info(self, ty: ta.Type[LoggingContextInfoT]) -> ta.Optional[LoggingContextInfoT]:
|
|
122
125
|
return self._infos.get(ty)
|
|
123
126
|
|
|
@@ -140,7 +143,7 @@ class CaptureLoggingContextImpl(CaptureLoggingContext):
|
|
|
140
143
|
_stack_offset: int
|
|
141
144
|
_stack_info: bool
|
|
142
145
|
|
|
143
|
-
def inc_stack_offset(self, ofs: int = 1) -> '
|
|
146
|
+
def inc_stack_offset(self, ofs: int = 1) -> 'CaptureLoggingContextImpl':
|
|
144
147
|
if hasattr(self, '_stack_offset'):
|
|
145
148
|
self._stack_offset += ofs
|
|
146
149
|
return self
|
omlish/logs/lists.py
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# ruff: noqa: N802 UP006 UP007 UP045
|
|
2
|
+
# @omlish-lite
|
|
3
|
+
import dataclasses as dc
|
|
4
|
+
import typing as ta
|
|
5
|
+
|
|
6
|
+
from ..lite.abstract import Abstract
|
|
7
|
+
from ..lite.check import check
|
|
8
|
+
from .base import AnyLogger
|
|
9
|
+
from .base import AsyncLogger
|
|
10
|
+
from .base import CaptureLoggingContext
|
|
11
|
+
from .base import Logger
|
|
12
|
+
from .base import LoggingMsgFn
|
|
13
|
+
from .contexts import CaptureLoggingContextImpl
|
|
14
|
+
from .infos import LoggingContextInfo
|
|
15
|
+
from .infos import LoggingContextInfos
|
|
16
|
+
from .levels import LogLevel
|
|
17
|
+
from .levels import NamedLogLevel
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
T = ta.TypeVar('T')
|
|
21
|
+
|
|
22
|
+
LoggingContextInfoT = ta.TypeVar('LoggingContextInfoT', bound=LoggingContextInfo)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
##
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dc.dataclass(frozen=True)
|
|
29
|
+
class ListLoggerEntry:
|
|
30
|
+
infos: ta.Mapping[ta.Type[LoggingContextInfo], LoggingContextInfo]
|
|
31
|
+
|
|
32
|
+
def get_info(self, ty: ta.Type[LoggingContextInfoT]) -> ta.Optional[LoggingContextInfoT]:
|
|
33
|
+
return self.infos.get(ty)
|
|
34
|
+
|
|
35
|
+
@ta.final
|
|
36
|
+
def __getitem__(self, ty: ta.Type[LoggingContextInfoT]) -> ta.Optional[LoggingContextInfoT]:
|
|
37
|
+
return self.get_info(ty)
|
|
38
|
+
|
|
39
|
+
def must_get_info(self, ty: ta.Type[LoggingContextInfoT]) -> LoggingContextInfoT:
|
|
40
|
+
return check.not_none(self.get_info(ty))
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class AnyListLogger(AnyLogger[T], Abstract):
|
|
44
|
+
def __init__(
|
|
45
|
+
self,
|
|
46
|
+
*,
|
|
47
|
+
name: ta.Optional[str] = None,
|
|
48
|
+
level: LogLevel = NamedLogLevel.NOTSET,
|
|
49
|
+
) -> None:
|
|
50
|
+
super().__init__()
|
|
51
|
+
|
|
52
|
+
if name is None:
|
|
53
|
+
name = f'{type(self).__name__}@{id(self):x}'
|
|
54
|
+
self._name = name
|
|
55
|
+
self._level = level
|
|
56
|
+
|
|
57
|
+
self._entries: ta.List[ListLoggerEntry] = []
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def name(self) -> str:
|
|
61
|
+
return self._name
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def entries(self) -> ta.List[ListLoggerEntry]:
|
|
65
|
+
"""Intentionally mutable."""
|
|
66
|
+
|
|
67
|
+
return self._entries
|
|
68
|
+
|
|
69
|
+
def set_level(self, level: LogLevel) -> None:
|
|
70
|
+
self._level = level
|
|
71
|
+
|
|
72
|
+
def get_effective_level(self) -> LogLevel:
|
|
73
|
+
return self._level
|
|
74
|
+
|
|
75
|
+
def _add_entry(
|
|
76
|
+
self,
|
|
77
|
+
ctx: CaptureLoggingContextImpl,
|
|
78
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
79
|
+
*args: ta.Any,
|
|
80
|
+
) -> None:
|
|
81
|
+
if not self.is_enabled_for(ctx.must_get_info(LoggingContextInfos.Level).level):
|
|
82
|
+
return
|
|
83
|
+
|
|
84
|
+
ctx.set_basic(
|
|
85
|
+
name=self._name,
|
|
86
|
+
|
|
87
|
+
msg=msg,
|
|
88
|
+
args=args,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
ctx.capture()
|
|
92
|
+
|
|
93
|
+
self._entries.append(ListLoggerEntry(ctx.get_infos()))
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class ListLogger(AnyListLogger[None], Logger):
|
|
97
|
+
def _log(
|
|
98
|
+
self,
|
|
99
|
+
ctx: CaptureLoggingContext,
|
|
100
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
101
|
+
*args: ta.Any,
|
|
102
|
+
**kwargs: ta.Any,
|
|
103
|
+
) -> None:
|
|
104
|
+
self._add_entry(
|
|
105
|
+
check.isinstance(ctx, CaptureLoggingContextImpl).inc_stack_offset(),
|
|
106
|
+
msg,
|
|
107
|
+
*args,
|
|
108
|
+
**kwargs,
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class ListAsyncLogger(AnyListLogger[ta.Awaitable[None]], AsyncLogger):
|
|
113
|
+
async def _log(
|
|
114
|
+
self,
|
|
115
|
+
ctx: CaptureLoggingContext,
|
|
116
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
117
|
+
*args: ta.Any,
|
|
118
|
+
**kwargs: ta.Any,
|
|
119
|
+
) -> None:
|
|
120
|
+
self._add_entry(
|
|
121
|
+
check.isinstance(ctx, CaptureLoggingContextImpl).inc_stack_offset(),
|
|
122
|
+
msg,
|
|
123
|
+
*args,
|
|
124
|
+
**kwargs,
|
|
125
|
+
)
|
omlish/logs/modules.py
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
# ruff: noqa: UP006
|
|
1
2
|
# @omlish-lite
|
|
2
3
|
import logging
|
|
3
4
|
import typing as ta
|
|
4
5
|
|
|
6
|
+
from .asyncs import LoggerToAsyncLogger
|
|
7
|
+
from .base import AsyncLogger
|
|
5
8
|
from .base import Logger
|
|
6
9
|
from .std.loggers import StdLogger
|
|
7
10
|
|
|
@@ -9,5 +12,20 @@ from .std.loggers import StdLogger
|
|
|
9
12
|
##
|
|
10
13
|
|
|
11
14
|
|
|
15
|
+
def _get_module_std_logger(mod_globals: ta.Mapping[str, ta.Any]) -> logging.Logger:
|
|
16
|
+
return logging.getLogger(mod_globals.get('__name__'))
|
|
17
|
+
|
|
18
|
+
|
|
12
19
|
def get_module_logger(mod_globals: ta.Mapping[str, ta.Any]) -> Logger:
|
|
13
|
-
return StdLogger(
|
|
20
|
+
return StdLogger(_get_module_std_logger(mod_globals))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def get_module_async_logger(mod_globals: ta.Mapping[str, ta.Any]) -> AsyncLogger:
|
|
24
|
+
return LoggerToAsyncLogger(get_module_logger(mod_globals))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def get_module_loggers(mod_globals: ta.Mapping[str, ta.Any]) -> ta.Tuple[Logger, AsyncLogger]:
|
|
28
|
+
return (
|
|
29
|
+
log := get_module_logger(mod_globals),
|
|
30
|
+
LoggerToAsyncLogger(log),
|
|
31
|
+
)
|
omlish/logs/std/loggers.py
CHANGED
|
@@ -30,7 +30,12 @@ class StdLogger(Logger):
|
|
|
30
30
|
def get_effective_level(self) -> LogLevel:
|
|
31
31
|
return self._std.getEffectiveLevel()
|
|
32
32
|
|
|
33
|
-
def _log(
|
|
33
|
+
def _log(
|
|
34
|
+
self,
|
|
35
|
+
ctx: CaptureLoggingContext,
|
|
36
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
37
|
+
*args: ta.Any,
|
|
38
|
+
) -> None:
|
|
34
39
|
if not self.is_enabled_for(ctx.must_get_info(LoggingContextInfos.Level).level):
|
|
35
40
|
return
|
|
36
41
|
|
omlish/logs/std/noisy.py
CHANGED
|
@@ -4,16 +4,18 @@ import logging
|
|
|
4
4
|
##
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
'boto3.resources.action',
|
|
9
|
-
'datadog.dogstatsd',
|
|
10
|
-
'elasticsearch',
|
|
11
|
-
'
|
|
12
|
-
'
|
|
13
|
-
'
|
|
7
|
+
NOISY_LOGGER_LEVELS: dict[str, int] = {
|
|
8
|
+
'boto3.resources.action': logging.WARNING,
|
|
9
|
+
'datadog.dogstatsd': logging.WARNING,
|
|
10
|
+
'elasticsearch': logging.WARNING,
|
|
11
|
+
'httpcore': logging.INFO,
|
|
12
|
+
'httpx': logging.WARNING,
|
|
13
|
+
'kazoo.client': logging.WARNING,
|
|
14
|
+
'markdown_it': logging.INFO,
|
|
15
|
+
'requests.packages.urllib3.connectionpool': logging.WARNING,
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
def silence_noisy_loggers() -> None:
|
|
18
|
-
for
|
|
19
|
-
logging.getLogger(
|
|
20
|
+
for name, level in NOISY_LOGGER_LEVELS.items():
|
|
21
|
+
logging.getLogger(name).setLevel(level)
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
# @omlish-lite
|
|
3
3
|
"""
|
|
4
4
|
TODO:
|
|
5
|
-
- !! move to std !!
|
|
6
5
|
- structured
|
|
7
6
|
- prefixed
|
|
8
7
|
- debug
|
|
@@ -13,9 +12,9 @@ import datetime
|
|
|
13
12
|
import logging
|
|
14
13
|
import typing as ta
|
|
15
14
|
|
|
16
|
-
from .
|
|
17
|
-
from .
|
|
18
|
-
from .
|
|
15
|
+
from .filters import TidLoggingFilter
|
|
16
|
+
from .json import JsonLoggingFormatter
|
|
17
|
+
from .proxy import ProxyLoggingHandler
|
|
19
18
|
|
|
20
19
|
|
|
21
20
|
##
|
omlish/logs/utils.py
CHANGED
|
@@ -17,7 +17,7 @@ def exception_logging(log): # noqa
|
|
|
17
17
|
def inner(*args, **kwargs):
|
|
18
18
|
try:
|
|
19
19
|
return fn(*args, **kwargs)
|
|
20
|
-
except Exception:
|
|
20
|
+
except Exception as e: # noqa
|
|
21
21
|
log.exception('Error in %r', fn)
|
|
22
22
|
raise
|
|
23
23
|
|
|
@@ -26,6 +26,21 @@ def exception_logging(log): # noqa
|
|
|
26
26
|
return outer
|
|
27
27
|
|
|
28
28
|
|
|
29
|
+
def async_exception_logging(alog): # noqa
|
|
30
|
+
def outer(fn):
|
|
31
|
+
@functools.wraps(fn)
|
|
32
|
+
async def inner(*args, **kwargs):
|
|
33
|
+
try:
|
|
34
|
+
return await fn(*args, **kwargs)
|
|
35
|
+
except Exception as e: # noqa
|
|
36
|
+
await alog.exception('Error in %r', fn)
|
|
37
|
+
raise
|
|
38
|
+
|
|
39
|
+
return inner
|
|
40
|
+
|
|
41
|
+
return outer
|
|
42
|
+
|
|
43
|
+
|
|
29
44
|
##
|
|
30
45
|
|
|
31
46
|
|