monitaudit 0.1.0__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.
- monitaudit/__init__.py +23 -0
- monitaudit/constants.py +15 -0
- monitaudit/core.py +0 -0
- monitaudit/logger.py +449 -0
- monitaudit/models/__init__.py +23 -0
- monitaudit/models/base.py +32 -0
- monitaudit/models/context.py +24 -0
- monitaudit/models/log.py +35 -0
- monitaudit/models/monitaudit.py +264 -0
- monitaudit/models/sinks.py +195 -0
- monitaudit/sinks/__init__.py +13 -0
- monitaudit/sinks/base.py +10 -0
- monitaudit/sinks/console.py +131 -0
- monitaudit/sinks/delta.py +257 -0
- monitaudit/sinks/file.py +75 -0
- monitaudit/sinks/json.py +20 -0
- monitaudit/sinks/memory.py +38 -0
- monitaudit/utilities/__init__.py +13 -0
- monitaudit/utilities/build_observability.py +94 -0
- monitaudit/utilities/get_environment.py +31 -0
- monitaudit/utilities/get_spark.py +52 -0
- monitaudit/utilities/helpers.py +43 -0
- monitaudit/utilities/json_safe.py +84 -0
- monitaudit/utilities/load_config.py +48 -0
- monitaudit/utilities/parameters.py +93 -0
- monitaudit/utilities/redaction.py +112 -0
- monitaudit-0.1.0.dist-info/METADATA +40 -0
- monitaudit-0.1.0.dist-info/RECORD +31 -0
- monitaudit-0.1.0.dist-info/WHEEL +4 -0
- monitaudit-0.1.0.dist-info/entry_points.txt +2 -0
- monitaudit-0.1.0.dist-info/licenses/LICENSE +674 -0
monitaudit/__init__.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# src/monitaudit/__init__.py
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from .logger import monitauditLogger
|
|
6
|
+
from .models.context import LogContext
|
|
7
|
+
from .models.monitaudit import Observability
|
|
8
|
+
from .sinks import (
|
|
9
|
+
ConsoleSink,
|
|
10
|
+
DeltaSink,
|
|
11
|
+
FileSink,
|
|
12
|
+
JsonSink,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"ConsoleSink",
|
|
17
|
+
"DeltaSink",
|
|
18
|
+
"FileSink",
|
|
19
|
+
"JsonSink",
|
|
20
|
+
"LogContext",
|
|
21
|
+
"Observability",
|
|
22
|
+
"monitauditLogger",
|
|
23
|
+
]
|
monitaudit/constants.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# src/monitaudit/constants.py
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
FUNCTION_START = "function_start"
|
|
7
|
+
FUNCTION_END = "function_end"
|
|
8
|
+
FUNCTION_ERROR = "function_error"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"FUNCTION_START",
|
|
13
|
+
"FUNCTION_END",
|
|
14
|
+
"FUNCTION_ERROR",
|
|
15
|
+
]
|
monitaudit/core.py
ADDED
|
File without changes
|
monitaudit/logger.py
ADDED
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
# src/monitaudit/logger.py
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import inspect
|
|
6
|
+
import sys
|
|
7
|
+
import traceback
|
|
8
|
+
from typing import Any, Literal, cast
|
|
9
|
+
|
|
10
|
+
from monitaudit.models.base import BaseLog
|
|
11
|
+
from monitaudit.models.context import LogContext
|
|
12
|
+
from monitaudit.models.log import (
|
|
13
|
+
CriticalLog,
|
|
14
|
+
DebugLog,
|
|
15
|
+
ErrorLog,
|
|
16
|
+
InfoLog,
|
|
17
|
+
WarningLog,
|
|
18
|
+
)
|
|
19
|
+
from monitaudit.sinks.base import Sink
|
|
20
|
+
from monitaudit.utilities.json_safe import json_safe_dict
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
SinkFailureMode = Literal[
|
|
24
|
+
"continue",
|
|
25
|
+
"raise",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
StandardLog = DebugLog | InfoLog | WarningLog
|
|
29
|
+
StandardLogType = (
|
|
30
|
+
type[DebugLog]
|
|
31
|
+
| type[InfoLog]
|
|
32
|
+
| type[WarningLog]
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
ExceptionLog = ErrorLog | CriticalLog
|
|
36
|
+
ExceptionLogType = (
|
|
37
|
+
type[ErrorLog]
|
|
38
|
+
| type[CriticalLog]
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class monitauditLogger:
|
|
43
|
+
def __init__(
|
|
44
|
+
self,
|
|
45
|
+
context: LogContext,
|
|
46
|
+
*sinks: Sink,
|
|
47
|
+
sink_failure_mode: SinkFailureMode = "continue",
|
|
48
|
+
) -> None:
|
|
49
|
+
self.context: LogContext = context
|
|
50
|
+
self.sinks: tuple[Sink, ...] = sinks
|
|
51
|
+
self.sink_failure_mode: SinkFailureMode = (
|
|
52
|
+
sink_failure_mode
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
def debug(
|
|
56
|
+
self,
|
|
57
|
+
message: str,
|
|
58
|
+
*,
|
|
59
|
+
call_id: str | None = None,
|
|
60
|
+
parent_call_id: str | None = None,
|
|
61
|
+
parameters: dict[str, Any] | None = None,
|
|
62
|
+
duration_ms: float | None = None,
|
|
63
|
+
module: str | None = None,
|
|
64
|
+
function: str | None = None,
|
|
65
|
+
**attributes: Any,
|
|
66
|
+
) -> DebugLog:
|
|
67
|
+
return cast(
|
|
68
|
+
DebugLog,
|
|
69
|
+
self._log(
|
|
70
|
+
DebugLog,
|
|
71
|
+
message,
|
|
72
|
+
call_id=call_id,
|
|
73
|
+
parent_call_id=parent_call_id,
|
|
74
|
+
parameters=parameters,
|
|
75
|
+
duration_ms=duration_ms,
|
|
76
|
+
module=module,
|
|
77
|
+
function=function,
|
|
78
|
+
attributes=attributes,
|
|
79
|
+
),
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
def info(
|
|
83
|
+
self,
|
|
84
|
+
message: str,
|
|
85
|
+
*,
|
|
86
|
+
call_id: str | None = None,
|
|
87
|
+
parent_call_id: str | None = None,
|
|
88
|
+
parameters: dict[str, Any] | None = None,
|
|
89
|
+
duration_ms: float | None = None,
|
|
90
|
+
module: str | None = None,
|
|
91
|
+
function: str | None = None,
|
|
92
|
+
**attributes: Any,
|
|
93
|
+
) -> InfoLog:
|
|
94
|
+
return cast(
|
|
95
|
+
InfoLog,
|
|
96
|
+
self._log(
|
|
97
|
+
InfoLog,
|
|
98
|
+
message,
|
|
99
|
+
call_id=call_id,
|
|
100
|
+
parent_call_id=parent_call_id,
|
|
101
|
+
parameters=parameters,
|
|
102
|
+
duration_ms=duration_ms,
|
|
103
|
+
module=module,
|
|
104
|
+
function=function,
|
|
105
|
+
attributes=attributes,
|
|
106
|
+
),
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
def warning(
|
|
110
|
+
self,
|
|
111
|
+
message: str,
|
|
112
|
+
*,
|
|
113
|
+
call_id: str | None = None,
|
|
114
|
+
parent_call_id: str | None = None,
|
|
115
|
+
parameters: dict[str, Any] | None = None,
|
|
116
|
+
duration_ms: float | None = None,
|
|
117
|
+
module: str | None = None,
|
|
118
|
+
function: str | None = None,
|
|
119
|
+
**attributes: Any,
|
|
120
|
+
) -> WarningLog:
|
|
121
|
+
return cast(
|
|
122
|
+
WarningLog,
|
|
123
|
+
self._log(
|
|
124
|
+
WarningLog,
|
|
125
|
+
message,
|
|
126
|
+
call_id=call_id,
|
|
127
|
+
parent_call_id=parent_call_id,
|
|
128
|
+
parameters=parameters,
|
|
129
|
+
duration_ms=duration_ms,
|
|
130
|
+
module=module,
|
|
131
|
+
function=function,
|
|
132
|
+
attributes=attributes,
|
|
133
|
+
),
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
def error(
|
|
137
|
+
self,
|
|
138
|
+
message: str,
|
|
139
|
+
*,
|
|
140
|
+
exception: BaseException | None = None,
|
|
141
|
+
call_id: str | None = None,
|
|
142
|
+
parent_call_id: str | None = None,
|
|
143
|
+
parameters: dict[str, Any] | None = None,
|
|
144
|
+
duration_ms: float | None = None,
|
|
145
|
+
module: str | None = None,
|
|
146
|
+
function: str | None = None,
|
|
147
|
+
**attributes: Any,
|
|
148
|
+
) -> ErrorLog:
|
|
149
|
+
return cast(
|
|
150
|
+
ErrorLog,
|
|
151
|
+
self._log_exception(
|
|
152
|
+
ErrorLog,
|
|
153
|
+
message,
|
|
154
|
+
exception=exception,
|
|
155
|
+
call_id=call_id,
|
|
156
|
+
parent_call_id=parent_call_id,
|
|
157
|
+
parameters=parameters,
|
|
158
|
+
duration_ms=duration_ms,
|
|
159
|
+
module=module,
|
|
160
|
+
function=function,
|
|
161
|
+
attributes=attributes,
|
|
162
|
+
),
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
def critical(
|
|
166
|
+
self,
|
|
167
|
+
message: str,
|
|
168
|
+
*,
|
|
169
|
+
exception: BaseException | None = None,
|
|
170
|
+
call_id: str | None = None,
|
|
171
|
+
parent_call_id: str | None = None,
|
|
172
|
+
parameters: dict[str, Any] | None = None,
|
|
173
|
+
duration_ms: float | None = None,
|
|
174
|
+
module: str | None = None,
|
|
175
|
+
function: str | None = None,
|
|
176
|
+
**attributes: Any,
|
|
177
|
+
) -> CriticalLog:
|
|
178
|
+
return cast(
|
|
179
|
+
CriticalLog,
|
|
180
|
+
self._log_exception(
|
|
181
|
+
CriticalLog,
|
|
182
|
+
message,
|
|
183
|
+
exception=exception,
|
|
184
|
+
call_id=call_id,
|
|
185
|
+
parent_call_id=parent_call_id,
|
|
186
|
+
parameters=parameters,
|
|
187
|
+
duration_ms=duration_ms,
|
|
188
|
+
module=module,
|
|
189
|
+
function=function,
|
|
190
|
+
attributes=attributes,
|
|
191
|
+
),
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
def _log(
|
|
195
|
+
self,
|
|
196
|
+
log_type: StandardLogType,
|
|
197
|
+
message: str,
|
|
198
|
+
*,
|
|
199
|
+
call_id: str | None,
|
|
200
|
+
parent_call_id: str | None,
|
|
201
|
+
parameters: dict[str, Any] | None,
|
|
202
|
+
duration_ms: float | None,
|
|
203
|
+
module: str | None,
|
|
204
|
+
function: str | None,
|
|
205
|
+
attributes: dict[str, Any],
|
|
206
|
+
) -> StandardLog:
|
|
207
|
+
resolved_module, resolved_function = self._resolve_caller(
|
|
208
|
+
module=module,
|
|
209
|
+
function=function,
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
log = log_type(
|
|
213
|
+
message=message,
|
|
214
|
+
context=self.context,
|
|
215
|
+
call_id=call_id,
|
|
216
|
+
parent_call_id=parent_call_id,
|
|
217
|
+
parameters=self._prepare_parameters(
|
|
218
|
+
parameters
|
|
219
|
+
),
|
|
220
|
+
duration_ms=duration_ms,
|
|
221
|
+
module=resolved_module,
|
|
222
|
+
function=resolved_function,
|
|
223
|
+
attributes=self._prepare_attributes(
|
|
224
|
+
attributes
|
|
225
|
+
),
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
self._write(log)
|
|
229
|
+
|
|
230
|
+
return log
|
|
231
|
+
|
|
232
|
+
def _log_exception(
|
|
233
|
+
self,
|
|
234
|
+
log_type: ExceptionLogType,
|
|
235
|
+
message: str,
|
|
236
|
+
*,
|
|
237
|
+
exception: BaseException | None,
|
|
238
|
+
call_id: str | None,
|
|
239
|
+
parent_call_id: str | None,
|
|
240
|
+
parameters: dict[str, Any] | None,
|
|
241
|
+
duration_ms: float | None,
|
|
242
|
+
module: str | None,
|
|
243
|
+
function: str | None,
|
|
244
|
+
attributes: dict[str, Any],
|
|
245
|
+
) -> ExceptionLog:
|
|
246
|
+
resolved_module, resolved_function = self._resolve_caller(
|
|
247
|
+
module=module,
|
|
248
|
+
function=function,
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
(
|
|
252
|
+
error_type,
|
|
253
|
+
error_message,
|
|
254
|
+
traceback_lines,
|
|
255
|
+
) = self._serialize_exception(exception)
|
|
256
|
+
|
|
257
|
+
log = log_type(
|
|
258
|
+
message=message,
|
|
259
|
+
context=self.context,
|
|
260
|
+
call_id=call_id,
|
|
261
|
+
parent_call_id=parent_call_id,
|
|
262
|
+
parameters=self._prepare_parameters(
|
|
263
|
+
parameters
|
|
264
|
+
),
|
|
265
|
+
duration_ms=duration_ms,
|
|
266
|
+
module=resolved_module,
|
|
267
|
+
function=resolved_function,
|
|
268
|
+
attributes=self._prepare_attributes(
|
|
269
|
+
attributes
|
|
270
|
+
),
|
|
271
|
+
error_type=error_type,
|
|
272
|
+
error_message=error_message,
|
|
273
|
+
traceback=traceback_lines,
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
self._write(log)
|
|
277
|
+
|
|
278
|
+
return log
|
|
279
|
+
|
|
280
|
+
@staticmethod
|
|
281
|
+
def _prepare_parameters(
|
|
282
|
+
parameters: dict[str, Any] | None,
|
|
283
|
+
) -> dict[str, Any]:
|
|
284
|
+
"""
|
|
285
|
+
Convert parameters to JSON-safe values.
|
|
286
|
+
|
|
287
|
+
Parameter redaction and size limiting are performed by
|
|
288
|
+
Observability.trace(). This method provides the final safety
|
|
289
|
+
boundary before parameters are stored in the log model.
|
|
290
|
+
"""
|
|
291
|
+
if not parameters:
|
|
292
|
+
return {}
|
|
293
|
+
|
|
294
|
+
return json_safe_dict(parameters)
|
|
295
|
+
|
|
296
|
+
@staticmethod
|
|
297
|
+
def _prepare_attributes(
|
|
298
|
+
attributes: dict[str, Any],
|
|
299
|
+
) -> dict[str, Any]:
|
|
300
|
+
"""
|
|
301
|
+
Convert arbitrary structured attributes to JSON-safe values.
|
|
302
|
+
|
|
303
|
+
This protects all sinks from unsupported objects such as Path,
|
|
304
|
+
UUID, datetime, Enum, set, Pydantic models, and custom classes.
|
|
305
|
+
"""
|
|
306
|
+
if not attributes:
|
|
307
|
+
return {}
|
|
308
|
+
|
|
309
|
+
return json_safe_dict(attributes)
|
|
310
|
+
|
|
311
|
+
@staticmethod
|
|
312
|
+
def _serialize_exception(
|
|
313
|
+
exception: BaseException | None,
|
|
314
|
+
) -> tuple[
|
|
315
|
+
str | None,
|
|
316
|
+
str | None,
|
|
317
|
+
list[str],
|
|
318
|
+
]:
|
|
319
|
+
"""
|
|
320
|
+
Convert an exception into serialisable error fields.
|
|
321
|
+
|
|
322
|
+
The raw exception object is never stored in a log model or
|
|
323
|
+
passed to a sink.
|
|
324
|
+
"""
|
|
325
|
+
if exception is None:
|
|
326
|
+
return None, None, []
|
|
327
|
+
|
|
328
|
+
return (
|
|
329
|
+
type(exception).__name__,
|
|
330
|
+
str(exception),
|
|
331
|
+
traceback.format_exception(
|
|
332
|
+
type(exception),
|
|
333
|
+
exception,
|
|
334
|
+
exception.__traceback__,
|
|
335
|
+
),
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
@staticmethod
|
|
339
|
+
def _report_sink_failure(
|
|
340
|
+
*,
|
|
341
|
+
sink: Sink,
|
|
342
|
+
exception: Exception,
|
|
343
|
+
) -> None:
|
|
344
|
+
print(
|
|
345
|
+
(
|
|
346
|
+
"monitaudit sink failure: "
|
|
347
|
+
f"{type(sink).__name__}: "
|
|
348
|
+
f"{type(exception).__name__}: "
|
|
349
|
+
f"{exception}"
|
|
350
|
+
),
|
|
351
|
+
file=sys.stderr,
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
def _write(
|
|
355
|
+
self,
|
|
356
|
+
log: BaseLog,
|
|
357
|
+
) -> None:
|
|
358
|
+
failures: list[
|
|
359
|
+
tuple[Sink, Exception]
|
|
360
|
+
] = []
|
|
361
|
+
|
|
362
|
+
for sink in self.sinks:
|
|
363
|
+
try:
|
|
364
|
+
sink.write(log)
|
|
365
|
+
|
|
366
|
+
except Exception as exception:
|
|
367
|
+
failures.append(
|
|
368
|
+
(
|
|
369
|
+
sink,
|
|
370
|
+
exception,
|
|
371
|
+
)
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
self._report_sink_failure(
|
|
375
|
+
sink=sink,
|
|
376
|
+
exception=exception,
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
if (
|
|
380
|
+
failures
|
|
381
|
+
and self.sink_failure_mode == "raise"
|
|
382
|
+
):
|
|
383
|
+
sink_names = ", ".join(
|
|
384
|
+
type(sink).__name__
|
|
385
|
+
for sink, _ in failures
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
raise RuntimeError(
|
|
389
|
+
f"monitaudit sink failure(s): {sink_names}"
|
|
390
|
+
) from failures[0][1]
|
|
391
|
+
|
|
392
|
+
def _resolve_caller(
|
|
393
|
+
self,
|
|
394
|
+
*,
|
|
395
|
+
module: str | None,
|
|
396
|
+
function: str | None,
|
|
397
|
+
) -> tuple[
|
|
398
|
+
str | None,
|
|
399
|
+
str | None,
|
|
400
|
+
]:
|
|
401
|
+
if (
|
|
402
|
+
module is not None
|
|
403
|
+
and function is not None
|
|
404
|
+
):
|
|
405
|
+
return module, function
|
|
406
|
+
|
|
407
|
+
(
|
|
408
|
+
detected_module,
|
|
409
|
+
detected_function,
|
|
410
|
+
) = self._caller()
|
|
411
|
+
|
|
412
|
+
return (
|
|
413
|
+
module or detected_module,
|
|
414
|
+
function or detected_function,
|
|
415
|
+
)
|
|
416
|
+
|
|
417
|
+
@staticmethod
|
|
418
|
+
def _caller() -> tuple[
|
|
419
|
+
str | None,
|
|
420
|
+
str | None,
|
|
421
|
+
]:
|
|
422
|
+
frame = inspect.currentframe()
|
|
423
|
+
|
|
424
|
+
if frame is None:
|
|
425
|
+
return None, None
|
|
426
|
+
|
|
427
|
+
try:
|
|
428
|
+
caller = frame.f_back
|
|
429
|
+
|
|
430
|
+
while caller is not None:
|
|
431
|
+
module = caller.f_globals.get(
|
|
432
|
+
"__name__"
|
|
433
|
+
)
|
|
434
|
+
function = (
|
|
435
|
+
caller.f_code.co_name
|
|
436
|
+
)
|
|
437
|
+
|
|
438
|
+
if module not in {
|
|
439
|
+
__name__,
|
|
440
|
+
"monitaudit.models.monitaudit",
|
|
441
|
+
}:
|
|
442
|
+
return module, function
|
|
443
|
+
|
|
444
|
+
caller = caller.f_back
|
|
445
|
+
|
|
446
|
+
return None, None
|
|
447
|
+
|
|
448
|
+
finally:
|
|
449
|
+
del frame
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# src/monitaudit/models/__init__.py
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from .base import BaseLog
|
|
6
|
+
from .context import LogContext
|
|
7
|
+
from .log import (
|
|
8
|
+
CriticalLog,
|
|
9
|
+
DebugLog,
|
|
10
|
+
ErrorLog,
|
|
11
|
+
InfoLog,
|
|
12
|
+
WarningLog,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"BaseLog",
|
|
17
|
+
"CriticalLog",
|
|
18
|
+
"DebugLog",
|
|
19
|
+
"ErrorLog",
|
|
20
|
+
"InfoLog",
|
|
21
|
+
"LogContext",
|
|
22
|
+
"WarningLog",
|
|
23
|
+
]
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from datetime import datetime, timezone
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
7
|
+
|
|
8
|
+
from monitaudit.models.context import LogContext
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class BaseLog(BaseModel):
|
|
12
|
+
model_config = ConfigDict(extra="forbid")
|
|
13
|
+
|
|
14
|
+
timestamp: datetime = Field(
|
|
15
|
+
default_factory=lambda: datetime.now(timezone.utc)
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
level: str
|
|
19
|
+
message: str
|
|
20
|
+
context: LogContext
|
|
21
|
+
|
|
22
|
+
call_id: str | None = None
|
|
23
|
+
parent_call_id: str | None = None
|
|
24
|
+
|
|
25
|
+
parameters: dict[str, Any] = Field(default_factory=dict)
|
|
26
|
+
|
|
27
|
+
duration_ms: float | None = Field(default=None, ge=0)
|
|
28
|
+
|
|
29
|
+
module: str | None = None
|
|
30
|
+
function: str | None = None
|
|
31
|
+
|
|
32
|
+
attributes: dict[str, Any] = Field(default_factory=dict)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
from uuid import uuid4
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class LogContext(BaseModel):
|
|
10
|
+
model_config = ConfigDict(
|
|
11
|
+
extra="forbid",
|
|
12
|
+
frozen=True,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
application: str = Field(min_length=1)
|
|
16
|
+
environment: str = Field(min_length=1)
|
|
17
|
+
|
|
18
|
+
correlation_id: str = Field(
|
|
19
|
+
default_factory=lambda: str(uuid4())
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
run_id: str | None = None
|
|
23
|
+
|
|
24
|
+
attributes: dict[str, Any] = Field(default_factory=dict)
|
monitaudit/models/log.py
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# src/monitaudit/models/log.py
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Literal
|
|
6
|
+
|
|
7
|
+
from pydantic import Field
|
|
8
|
+
|
|
9
|
+
from monitaudit.models.base import BaseLog
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class DebugLog(BaseLog):
|
|
13
|
+
level: Literal["DEBUG"] = "DEBUG"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class InfoLog(BaseLog):
|
|
17
|
+
level: Literal["INFO"] = "INFO"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class WarningLog(BaseLog):
|
|
21
|
+
level: Literal["WARNING"] = "WARNING"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ErrorLog(BaseLog):
|
|
25
|
+
level: Literal["ERROR"] = "ERROR"
|
|
26
|
+
error_type: str | None = None
|
|
27
|
+
error_message: str | None = None
|
|
28
|
+
traceback: list[str] = Field( default_factory=list )
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class CriticalLog(BaseLog):
|
|
32
|
+
level: Literal["CRITICAL"] = "CRITICAL"
|
|
33
|
+
error_type: str | None = None
|
|
34
|
+
error_message: str | None = None
|
|
35
|
+
traceback: list[str] = Field( default_factory=list )
|