debugbundle-python 1.5.0__py3-none-any.whl → 2.0.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.
@@ -0,0 +1,65 @@
1
+ """Logger adapter and bounded capture admission for callback-heavy paths."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import logging
6
+ import re
7
+ import time
8
+ from typing import TYPE_CHECKING
9
+
10
+ from .process_support import ensure_current_process
11
+
12
+ if TYPE_CHECKING:
13
+ from .core import DebugBundleSdk
14
+
15
+
16
+ def try_capture_lock(sdk: DebugBundleSdk) -> bool:
17
+ ensure_current_process(sdk)
18
+ for _ in range(8):
19
+ if sdk._lock.acquire(blocking=False):
20
+ return True
21
+ time.sleep(0)
22
+ return False
23
+
24
+
25
+ class DebugBundleLogHandler(logging.Handler):
26
+ def __init__(self, sdk: DebugBundleSdk) -> None:
27
+ super().__init__()
28
+ self._sdk = sdk
29
+
30
+ def emit(self, record: logging.LogRecord) -> None:
31
+ if not self._sdk._log_level_eligible(record.levelname.lower()):
32
+ return
33
+ self._sdk.capture_log(
34
+ safe_log_message(record),
35
+ level=record.levelname.lower(),
36
+ context={
37
+ "logger_name": record.name,
38
+ "pathname": record.pathname,
39
+ "lineno": record.lineno,
40
+ },
41
+ )
42
+
43
+
44
+ _PLACEHOLDER = re.compile(r"%[sdif]")
45
+
46
+
47
+ def safe_log_message(record: logging.LogRecord) -> str:
48
+ template = record.msg
49
+ if type(template) is not str:
50
+ return "[non-string log message withheld]"
51
+ template = template[:16_384]
52
+ args = record.args
53
+ if not args:
54
+ return template
55
+ if type(args) is not tuple or len(args) > 8:
56
+ return template + " [log arguments withheld]"
57
+ safe_args = [
58
+ value[:1024] if type(value) is str else str(value) if type(value) in (int, float, bool)
59
+ else "[unsupported argument]"
60
+ for value in args
61
+ ]
62
+ if len(_PLACEHOLDER.findall(template)) != len(safe_args):
63
+ return (template + " [args: " + ", ".join(safe_args) + "]")[:16_384]
64
+ iterator = iter(safe_args)
65
+ return _PLACEHOLDER.sub(lambda _match: next(iterator), template)[:16_384]