elven-logs-interceptor-python 0.1.11__tar.gz → 0.1.13__tar.gz
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.
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/PKG-INFO +9 -7
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/README.md +8 -6
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/pyproject.toml +1 -1
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/interceptors/runtime_interceptor.py +4 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/integrations/logging_handler.py +4 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/utils.py +1 -17
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/.gitignore +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/ARCHITECTURE.md +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/__init__.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/application/__init__.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/application/config_service.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/application/log_service.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/config.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/domain/__init__.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/domain/entities.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/domain/interfaces.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/domain/value_objects.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/__init__.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/buffer/__init__.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/buffer/memory_buffer.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/circuit_breaker/__init__.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/circuit_breaker/circuit_breaker.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/compression/__init__.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/compression/base.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/compression/brotli_compressor.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/compression/factory.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/compression/gzip_compressor.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/compression/noop_compressor.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/context/__init__.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/context/context_provider.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/dlq/__init__.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/dlq/file_dlq.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/dlq/memory_dlq.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/filter/__init__.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/filter/log_filter.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/interceptors/__init__.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/internal_capture_guard.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/log_noise_filter.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/log_record_extra.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/memory/__init__.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/memory/memory_tracker.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/metrics/__init__.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/metrics/metrics_collector.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/transport/__init__.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/transport/loki_json_transport.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/transport/loki_protobuf_transport.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/transport/otlp_json_transport.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/transport/resilient_transport.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/transport/transport_factory.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/workers/__init__.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/infrastructure/workers/worker_pool.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/integrations/__init__.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/integrations/celery.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/integrations/django.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/integrations/fastapi.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/integrations/flask.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/integrations/loguru.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/integrations/structlog.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/preload.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/presentation/__init__.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/presentation/factory.py +0 -0
- {elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/src/logs_interceptor/types.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: elven-logs-interceptor-python
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.13
|
|
4
4
|
Summary: Production-grade logs interceptor for Python with Loki transport, resilience, batching, and framework integrations.
|
|
5
5
|
Author: Elven Observability
|
|
6
6
|
License: MIT
|
|
@@ -132,17 +132,19 @@ data is explicitly required and approved.
|
|
|
132
132
|
The package supports the Python `LOGS_*` configuration surface aligned with
|
|
133
133
|
the JS v3 design where applicable.
|
|
134
134
|
|
|
135
|
-
Required:
|
|
135
|
+
Required for direct Loki mode:
|
|
136
136
|
|
|
137
137
|
- `LOGS_URL`
|
|
138
138
|
- `LOGS_TENANT`
|
|
139
139
|
- `LOGS_APP_NAME`
|
|
140
140
|
|
|
141
141
|
For collector-first mode, set `LOGS_EXPORTER=otlp` (or `collector`) and use
|
|
142
|
-
`
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
142
|
+
`OTEL_EXPORTER_OTLP_LOGS_ENDPOINT`. In this mode `LOGS_URL`, `LOKI_URL`,
|
|
143
|
+
`LOGS_TENANT` and `LOGS_TOKEN` are not required by the library. `LOGS_URL` is
|
|
144
|
+
intentionally ignored in collector mode to avoid accidentally posting OTLP logs
|
|
145
|
+
to a direct Loki `/loki/api/v1/push` endpoint. Put tenant or auth headers in
|
|
146
|
+
`OTEL_EXPORTER_OTLP_HEADERS`/`LOGS_OTLP_HEADERS` if your collector gateway
|
|
147
|
+
requires them.
|
|
146
148
|
|
|
147
149
|
Core:
|
|
148
150
|
|
|
@@ -153,7 +155,7 @@ Core:
|
|
|
153
155
|
Transport:
|
|
154
156
|
|
|
155
157
|
- `LOGS_EXPORTER` (`loki|otlp`, aliases: `collector`, `otel`)
|
|
156
|
-
- `
|
|
158
|
+
- `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` (collector logs endpoint, e.g. `http://collector:4318/v1/logs`)
|
|
157
159
|
- `LOGS_OTLP_HEADERS` (comma-separated headers, e.g. `x-tenant=team-a`)
|
|
158
160
|
- `LOGS_COMPRESSION` (`none|gzip|brotli|snappy`)
|
|
159
161
|
- `LOGS_COMPRESSION_LEVEL`
|
|
@@ -71,17 +71,19 @@ data is explicitly required and approved.
|
|
|
71
71
|
The package supports the Python `LOGS_*` configuration surface aligned with
|
|
72
72
|
the JS v3 design where applicable.
|
|
73
73
|
|
|
74
|
-
Required:
|
|
74
|
+
Required for direct Loki mode:
|
|
75
75
|
|
|
76
76
|
- `LOGS_URL`
|
|
77
77
|
- `LOGS_TENANT`
|
|
78
78
|
- `LOGS_APP_NAME`
|
|
79
79
|
|
|
80
80
|
For collector-first mode, set `LOGS_EXPORTER=otlp` (or `collector`) and use
|
|
81
|
-
`
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
`OTEL_EXPORTER_OTLP_LOGS_ENDPOINT`. In this mode `LOGS_URL`, `LOKI_URL`,
|
|
82
|
+
`LOGS_TENANT` and `LOGS_TOKEN` are not required by the library. `LOGS_URL` is
|
|
83
|
+
intentionally ignored in collector mode to avoid accidentally posting OTLP logs
|
|
84
|
+
to a direct Loki `/loki/api/v1/push` endpoint. Put tenant or auth headers in
|
|
85
|
+
`OTEL_EXPORTER_OTLP_HEADERS`/`LOGS_OTLP_HEADERS` if your collector gateway
|
|
86
|
+
requires them.
|
|
85
87
|
|
|
86
88
|
Core:
|
|
87
89
|
|
|
@@ -92,7 +94,7 @@ Core:
|
|
|
92
94
|
Transport:
|
|
93
95
|
|
|
94
96
|
- `LOGS_EXPORTER` (`loki|otlp`, aliases: `collector`, `otel`)
|
|
95
|
-
- `
|
|
97
|
+
- `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` (collector logs endpoint, e.g. `http://collector:4318/v1/logs`)
|
|
96
98
|
- `LOGS_OTLP_HEADERS` (comma-separated headers, e.g. `x-tenant=team-a`)
|
|
97
99
|
- `LOGS_COMPRESSION` (`none|gzip|brotli|snappy`)
|
|
98
100
|
- `LOGS_COMPRESSION_LEVEL`
|
{elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/pyproject.toml
RENAMED
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "elven-logs-interceptor-python"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.13"
|
|
8
8
|
description = "Production-grade logs interceptor for Python with Loki transport, resilience, batching, and framework integrations."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -14,6 +14,8 @@ from ..internal_capture_guard import is_internal_log_capture_suppressed
|
|
|
14
14
|
from ..log_noise_filter import normalize_excluded_logger_prefixes, should_drop_log_record
|
|
15
15
|
from ..log_record_extra import extract_log_record_extra
|
|
16
16
|
|
|
17
|
+
_LOG_RECORD_CAPTURED_ATTR = "_elven_uo_captured"
|
|
18
|
+
|
|
17
19
|
|
|
18
20
|
class _BridgeLoggingHandler(logging.Handler):
|
|
19
21
|
def __init__(self, logger: ILogger, exclude_prefixes: list[str] | None = None) -> None:
|
|
@@ -23,6 +25,8 @@ class _BridgeLoggingHandler(logging.Handler):
|
|
|
23
25
|
|
|
24
26
|
def emit(self, record: logging.LogRecord) -> None:
|
|
25
27
|
try:
|
|
28
|
+
if getattr(record, _LOG_RECORD_CAPTURED_ATTR, False):
|
|
29
|
+
return
|
|
26
30
|
if is_internal_log_capture_suppressed():
|
|
27
31
|
return
|
|
28
32
|
if should_drop_log_record(
|
|
@@ -13,6 +13,8 @@ from ..infrastructure.log_noise_filter import (
|
|
|
13
13
|
from ..infrastructure.log_record_extra import extract_log_record_extra
|
|
14
14
|
from ..types import LogLevel
|
|
15
15
|
|
|
16
|
+
_LOG_RECORD_CAPTURED_ATTR = "_elven_uo_captured"
|
|
17
|
+
|
|
16
18
|
|
|
17
19
|
class LoggingHandler(logging.Handler):
|
|
18
20
|
def __init__(self, logger: ILogger, exclude_prefixes: list[str] | None = None) -> None:
|
|
@@ -22,6 +24,8 @@ class LoggingHandler(logging.Handler):
|
|
|
22
24
|
|
|
23
25
|
def emit(self, record: logging.LogRecord) -> None:
|
|
24
26
|
try:
|
|
27
|
+
if getattr(record, _LOG_RECORD_CAPTURED_ATTR, False):
|
|
28
|
+
return
|
|
25
29
|
if is_internal_log_capture_suppressed():
|
|
26
30
|
return
|
|
27
31
|
if should_drop_log_record(
|
|
@@ -96,26 +96,10 @@ def _parse_kv_csv(raw: str | None) -> dict[str, str]:
|
|
|
96
96
|
return headers
|
|
97
97
|
|
|
98
98
|
|
|
99
|
-
def _otlp_logs_endpoint_from_base(endpoint: str | None) -> str:
|
|
100
|
-
if not endpoint:
|
|
101
|
-
return ""
|
|
102
|
-
normalized = endpoint.rstrip("/")
|
|
103
|
-
if normalized.endswith("/v1/logs"):
|
|
104
|
-
return normalized
|
|
105
|
-
if normalized.endswith("/v1/traces") or normalized.endswith("/v1/metrics"):
|
|
106
|
-
return normalized.rsplit("/", 1)[0] + "/logs"
|
|
107
|
-
return normalized + "/v1/logs"
|
|
108
|
-
|
|
109
|
-
|
|
110
99
|
def _resolve_logs_url(env: Mapping[str, str], exporter: str) -> str:
|
|
111
100
|
if exporter != "otlp":
|
|
112
101
|
return env.get("LOGS_URL", "")
|
|
113
|
-
return (
|
|
114
|
-
env.get("LOGS_URL")
|
|
115
|
-
or env.get("LOGS_OTLP_ENDPOINT")
|
|
116
|
-
or env.get("OTEL_EXPORTER_OTLP_LOGS_ENDPOINT")
|
|
117
|
-
or _otlp_logs_endpoint_from_base(env.get("OTEL_EXPORTER_OTLP_ENDPOINT"))
|
|
118
|
-
)
|
|
102
|
+
return env.get("OTEL_EXPORTER_OTLP_LOGS_ENDPOINT", "")
|
|
119
103
|
|
|
120
104
|
|
|
121
105
|
def is_debug_enabled() -> bool:
|
|
File without changes
|
{elven_logs_interceptor_python-0.1.11 → elven_logs_interceptor_python-0.1.13}/ARCHITECTURE.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|