elven-logs-interceptor-python 0.1.8__tar.gz → 0.1.10__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.
Files changed (90) hide show
  1. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/PKG-INFO +7 -6
  2. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/README.md +1 -0
  3. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/pyproject.toml +11 -11
  4. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/__init__.py +3 -0
  5. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/application/config_service.py +5 -0
  6. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/config.py +2 -0
  7. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/transport/loki_json_transport.py +4 -3
  8. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/utils.py +3 -0
  9. elven_logs_interceptor_python-0.1.8/examples/basic_app.py +0 -18
  10. elven_logs_interceptor_python-0.1.8/examples/fastapi_integration.py +0 -26
  11. elven_logs_interceptor_python-0.1.8/examples/full_config_reference.py +0 -67
  12. elven_logs_interceptor_python-0.1.8/examples/high_volume.py +0 -30
  13. elven_logs_interceptor_python-0.1.8/examples/tracking_usage.py +0 -14
  14. elven_logs_interceptor_python-0.1.8/scripts/publish.sh +0 -180
  15. elven_logs_interceptor_python-0.1.8/test-apps/elven-live-demo/.env.example +0 -49
  16. elven_logs_interceptor_python-0.1.8/test-apps/elven-live-demo/README.md +0 -17
  17. elven_logs_interceptor_python-0.1.8/test-apps/elven-live-demo/app.py +0 -97
  18. elven_logs_interceptor_python-0.1.8/test-apps/elven-live-demo/run.sh +0 -21
  19. elven_logs_interceptor_python-0.1.8/test-apps/elven-observability-smoke/.env.example +0 -167
  20. elven_logs_interceptor_python-0.1.8/test-apps/elven-observability-smoke/README.md +0 -27
  21. elven_logs_interceptor_python-0.1.8/test-apps/elven-observability-smoke/app.py +0 -90
  22. elven_logs_interceptor_python-0.1.8/test-apps/elven-observability-smoke/run.sh +0 -21
  23. elven_logs_interceptor_python-0.1.8/tests/integration/test_api.py +0 -122
  24. elven_logs_interceptor_python-0.1.8/tests/unit/test_circuit_breaker_extra.py +0 -48
  25. elven_logs_interceptor_python-0.1.8/tests/unit/test_config_service.py +0 -128
  26. elven_logs_interceptor_python-0.1.8/tests/unit/test_core_components.py +0 -77
  27. elven_logs_interceptor_python-0.1.8/tests/unit/test_env_config.py +0 -59
  28. elven_logs_interceptor_python-0.1.8/tests/unit/test_integration_filters.py +0 -119
  29. elven_logs_interceptor_python-0.1.8/tests/unit/test_log_filter_extra.py +0 -68
  30. elven_logs_interceptor_python-0.1.8/tests/unit/test_log_service_unit.py +0 -578
  31. elven_logs_interceptor_python-0.1.8/tests/unit/test_loguru_sink.py +0 -137
  32. elven_logs_interceptor_python-0.1.8/tests/unit/test_loki_json_transport.py +0 -143
  33. elven_logs_interceptor_python-0.1.8/tests/unit/test_memory_buffer_extra.py +0 -145
  34. elven_logs_interceptor_python-0.1.8/tests/unit/test_protobuf_transport_safety.py +0 -141
  35. elven_logs_interceptor_python-0.1.8/tests/unit/test_resilient_transport.py +0 -211
  36. elven_logs_interceptor_python-0.1.8/tests/unit/test_runtime_interceptor.py +0 -88
  37. elven_logs_interceptor_python-0.1.8/tests/unit/test_utils_extra.py +0 -274
  38. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/.gitignore +0 -0
  39. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/ARCHITECTURE.md +0 -0
  40. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/application/__init__.py +0 -0
  41. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/application/log_service.py +0 -0
  42. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/domain/__init__.py +0 -0
  43. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/domain/entities.py +0 -0
  44. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/domain/interfaces.py +0 -0
  45. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/domain/value_objects.py +0 -0
  46. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/__init__.py +0 -0
  47. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/buffer/__init__.py +0 -0
  48. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/buffer/memory_buffer.py +0 -0
  49. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/circuit_breaker/__init__.py +0 -0
  50. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/circuit_breaker/circuit_breaker.py +0 -0
  51. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/compression/__init__.py +0 -0
  52. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/compression/base.py +0 -0
  53. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/compression/brotli_compressor.py +0 -0
  54. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/compression/factory.py +0 -0
  55. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/compression/gzip_compressor.py +0 -0
  56. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/compression/noop_compressor.py +0 -0
  57. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/context/__init__.py +0 -0
  58. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/context/context_provider.py +0 -0
  59. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/dlq/__init__.py +0 -0
  60. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/dlq/file_dlq.py +0 -0
  61. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/dlq/memory_dlq.py +0 -0
  62. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/filter/__init__.py +0 -0
  63. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/filter/log_filter.py +0 -0
  64. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/interceptors/__init__.py +0 -0
  65. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/interceptors/runtime_interceptor.py +0 -0
  66. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/internal_capture_guard.py +0 -0
  67. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/log_noise_filter.py +0 -0
  68. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/log_record_extra.py +0 -0
  69. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/memory/__init__.py +0 -0
  70. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/memory/memory_tracker.py +0 -0
  71. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/metrics/__init__.py +0 -0
  72. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/metrics/metrics_collector.py +0 -0
  73. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/transport/__init__.py +0 -0
  74. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/transport/loki_protobuf_transport.py +0 -0
  75. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/transport/resilient_transport.py +0 -0
  76. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/transport/transport_factory.py +0 -0
  77. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/workers/__init__.py +0 -0
  78. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/infrastructure/workers/worker_pool.py +0 -0
  79. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/integrations/__init__.py +0 -0
  80. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/integrations/celery.py +0 -0
  81. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/integrations/django.py +0 -0
  82. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/integrations/fastapi.py +0 -0
  83. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/integrations/flask.py +0 -0
  84. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/integrations/logging_handler.py +0 -0
  85. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/integrations/loguru.py +0 -0
  86. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/integrations/structlog.py +0 -0
  87. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/preload.py +0 -0
  88. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/presentation/__init__.py +0 -0
  89. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/src/logs_interceptor/presentation/factory.py +0 -0
  90. {elven_logs_interceptor_python-0.1.8 → elven_logs_interceptor_python-0.1.10}/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.8
3
+ Version: 0.1.10
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
@@ -14,20 +14,20 @@ Classifier: Programming Language :: Python :: 3.11
14
14
  Classifier: Programming Language :: Python :: 3.12
15
15
  Classifier: Topic :: System :: Logging
16
16
  Requires-Python: >=3.10
17
- Requires-Dist: httpx>=0.27.0
17
+ Requires-Dist: httpx<0.29.0,>=0.24.1
18
18
  Requires-Dist: typing-extensions>=4.12.0
19
19
  Provides-Extra: all
20
20
  Requires-Dist: brotli>=1.1.0; extra == 'all'
21
21
  Requires-Dist: celery>=5.4.0; extra == 'all'
22
22
  Requires-Dist: django>=4.2; extra == 'all'
23
- Requires-Dist: fastapi>=0.111.0; extra == 'all'
23
+ Requires-Dist: fastapi>=0.100.0; extra == 'all'
24
24
  Requires-Dist: flask>=3.0.0; extra == 'all'
25
25
  Requires-Dist: loguru>=0.7.2; extra == 'all'
26
26
  Requires-Dist: opentelemetry-api>=1.24.0; extra == 'all'
27
27
  Requires-Dist: orjson>=3.10.0; extra == 'all'
28
28
  Requires-Dist: protobuf>=5.0.0; extra == 'all'
29
29
  Requires-Dist: python-snappy>=0.7.1; extra == 'all'
30
- Requires-Dist: starlette>=0.37.0; extra == 'all'
30
+ Requires-Dist: starlette>=0.27.0; extra == 'all'
31
31
  Requires-Dist: structlog>=24.0.0; extra == 'all'
32
32
  Provides-Extra: celery
33
33
  Requires-Dist: celery>=5.4.0; extra == 'celery'
@@ -42,8 +42,8 @@ Requires-Dist: twine>=5.1.1; extra == 'dev'
42
42
  Provides-Extra: django
43
43
  Requires-Dist: django>=4.2; extra == 'django'
44
44
  Provides-Extra: fastapi
45
- Requires-Dist: fastapi>=0.111.0; extra == 'fastapi'
46
- Requires-Dist: starlette>=0.37.0; extra == 'fastapi'
45
+ Requires-Dist: fastapi>=0.100.0; extra == 'fastapi'
46
+ Requires-Dist: starlette>=0.27.0; extra == 'fastapi'
47
47
  Provides-Extra: flask
48
48
  Requires-Dist: flask>=3.0.0; extra == 'flask'
49
49
  Provides-Extra: loguru
@@ -154,6 +154,7 @@ Transport:
154
154
  - `LOGS_WORKER_TIMEOUT`
155
155
  - `LOGS_CONNECTION_POOLING`
156
156
  - `LOGS_MAX_SOCKETS`
157
+ - `LOGS_ENABLE_STRUCTURED_METADATA` (`false` by default; enable only when Loki allows `limits_config.allow_structured_metadata`)
157
158
  - `LOGS_TIMEOUT`
158
159
  - `LOGS_MAX_RETRIES`
159
160
  - `LOGS_RETRY_DELAY`
@@ -93,6 +93,7 @@ Transport:
93
93
  - `LOGS_WORKER_TIMEOUT`
94
94
  - `LOGS_CONNECTION_POOLING`
95
95
  - `LOGS_MAX_SOCKETS`
96
+ - `LOGS_ENABLE_STRUCTURED_METADATA` (`false` by default; enable only when Loki allows `limits_config.allow_structured_metadata`)
96
97
  - `LOGS_TIMEOUT`
97
98
  - `LOGS_MAX_RETRIES`
98
99
  - `LOGS_RETRY_DELAY`
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "elven-logs-interceptor-python"
7
- version = "0.1.8"
7
+ version = "0.1.10"
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"
@@ -32,7 +32,7 @@ classifiers = [
32
32
  "Topic :: System :: Logging",
33
33
  ]
34
34
  dependencies = [
35
- "httpx>=0.27.0",
35
+ "httpx>=0.24.1,<0.29.0",
36
36
  "typing-extensions>=4.12.0",
37
37
  ]
38
38
 
@@ -47,8 +47,8 @@ otel = [
47
47
  "opentelemetry-api>=1.24.0",
48
48
  ]
49
49
  fastapi = [
50
- "fastapi>=0.111.0",
51
- "starlette>=0.37.0",
50
+ "fastapi>=0.100.0",
51
+ "starlette>=0.27.0",
52
52
  ]
53
53
  django = [
54
54
  "django>=4.2",
@@ -71,8 +71,8 @@ all = [
71
71
  "python-snappy>=0.7.1",
72
72
  "brotli>=1.1.0",
73
73
  "opentelemetry-api>=1.24.0",
74
- "fastapi>=0.111.0",
75
- "starlette>=0.37.0",
74
+ "fastapi>=0.100.0",
75
+ "starlette>=0.27.0",
76
76
  "django>=4.2",
77
77
  "flask>=3.0.0",
78
78
  "celery>=5.4.0",
@@ -93,22 +93,22 @@ dev = [
93
93
  packages = ["src/logs_interceptor"]
94
94
 
95
95
  [tool.hatch.build.targets.sdist]
96
- include = [
96
+ only-include = [
97
97
  "/ARCHITECTURE.md",
98
98
  "/README.md",
99
- "/examples",
100
99
  "/pyproject.toml",
101
- "/scripts",
102
100
  "/src",
103
- "/test-apps",
104
- "/tests",
105
101
  ]
106
102
  exclude = [
103
+ "/.mypy_cache",
104
+ "/.pytest_cache",
105
+ "/.ruff_cache",
107
106
  "/.venv*",
108
107
  "/.logs-dlq",
109
108
  "/build",
110
109
  "/collector",
111
110
  "/dist",
111
+ "/test-apps",
112
112
  ]
113
113
 
114
114
  [tool.pytest.ini_options]
@@ -104,6 +104,9 @@ def _coerce_config(user_config: LogsInterceptorConfig | dict[str, Any] | None) -
104
104
  transport_raw, "enable_connection_pooling", "enableConnectionPooling"
105
105
  ),
106
106
  max_sockets=_pick(transport_raw, "max_sockets", "maxSockets"),
107
+ enable_structured_metadata=_pick(
108
+ transport_raw, "enable_structured_metadata", "enableStructuredMetadata"
109
+ ),
107
110
  ),
108
111
  app_name=_pick(user_config, "app_name", "appName", ""),
109
112
  version=_pick(user_config, "version", "version"),
@@ -170,6 +170,11 @@ class ConfigService:
170
170
  True if transport.enable_connection_pooling is None else transport.enable_connection_pooling
171
171
  ),
172
172
  max_sockets=transport.max_sockets if transport.max_sockets is not None else 50,
173
+ enable_structured_metadata=(
174
+ False
175
+ if transport.enable_structured_metadata is None
176
+ else transport.enable_structured_metadata
177
+ ),
173
178
  )
174
179
 
175
180
  @staticmethod
@@ -26,6 +26,7 @@ class TransportConfig:
26
26
  worker_timeout: int | None = None
27
27
  enable_connection_pooling: bool | None = None
28
28
  max_sockets: int | None = None
29
+ enable_structured_metadata: bool | None = None
29
30
 
30
31
 
31
32
  @dataclass(slots=True)
@@ -131,6 +132,7 @@ class ResolvedTransportConfig:
131
132
  worker_timeout: int
132
133
  enable_connection_pooling: bool
133
134
  max_sockets: int
135
+ enable_structured_metadata: bool = False
134
136
 
135
137
 
136
138
  @dataclass(slots=True)
@@ -210,9 +210,10 @@ class LokiJsonTransport:
210
210
 
211
211
  timestamp_ns = self._timestamp_to_ns(entry.timestamp)
212
212
  value: list[Any] = [str(timestamp_ns), self._dumps(payload).decode("utf-8")]
213
- structured_metadata = self._format_structured_metadata(entry.metadata)
214
- if structured_metadata:
215
- value.append(structured_metadata)
213
+ if self._config.enable_structured_metadata:
214
+ structured_metadata = self._format_structured_metadata(entry.metadata)
215
+ if structured_metadata:
216
+ value.append(structured_metadata)
216
217
  values_map[key].append(value)
217
218
  streams[key] = labels
218
219
 
@@ -530,6 +530,9 @@ def load_config_from_env() -> LogsInterceptorConfig:
530
530
  enable_connection_pooling=parse_bool(env.get("LOGS_CONNECTION_POOLING"), True),
531
531
  max_sockets=parse_int_range(env.get("LOGS_MAX_SOCKETS"), 50, 1, 1024),
532
532
  worker_timeout=parse_int_range(env.get("LOGS_WORKER_TIMEOUT"), 30_000, 1000, 300_000),
533
+ enable_structured_metadata=parse_bool(
534
+ env.get("LOGS_ENABLE_STRUCTURED_METADATA"), False
535
+ ),
533
536
  ),
534
537
  app_name=env.get("LOGS_APP_NAME", ""),
535
538
  version=env.get("LOGS_APP_VERSION", "1.0.0"),
@@ -1,18 +0,0 @@
1
- from logs_interceptor import init
2
-
3
- init(
4
- {
5
- "appName": "my-service",
6
- "interceptConsole": True,
7
- "transport": {
8
- "url": "http://localhost:3100/loki/api/v1/push",
9
- "tenantId": "my-tenant",
10
- "compression": "gzip",
11
- "enableConnectionPooling": True,
12
- },
13
- "deadLetterQueue": {"enabled": True, "type": "file"},
14
- "circuitBreaker": {"enabled": True},
15
- }
16
- )
17
-
18
- print("service started")
@@ -1,26 +0,0 @@
1
- from fastapi import FastAPI
2
-
3
- from logs_interceptor import init, logger
4
- from logs_interceptor.integrations import FastAPIMiddleware
5
-
6
- init(
7
- {
8
- "transport": {
9
- "url": "http://localhost:3100/loki/api/v1/push",
10
- "tenantId": "my-tenant",
11
- "compression": "brotli",
12
- },
13
- "appName": "my-api",
14
- "interceptConsole": True,
15
- "deadLetterQueue": {"enabled": True, "type": "file"},
16
- }
17
- )
18
-
19
- app = FastAPI()
20
- app.add_middleware(FastAPIMiddleware, logger=logger)
21
-
22
-
23
- @app.get("/ping")
24
- def ping() -> dict[str, str]:
25
- logger.info("ping called")
26
- return {"message": "pong"}
@@ -1,67 +0,0 @@
1
- from logs_interceptor import init
2
-
3
- init(
4
- {
5
- "appName": "my-service-name",
6
- "version": "1.2.0",
7
- "environment": "production",
8
- "interceptConsole": True,
9
- "preserveOriginalConsole": True,
10
- "silentErrors": False,
11
- "debug": False,
12
- "labels": {"region": "us-east-1", "tier": "gold"},
13
- "dynamicLabels": {
14
- "pod_id": lambda: "unknown",
15
- },
16
- "transport": {
17
- "url": "http://localhost:3100/loki/api/v1/push",
18
- "tenantId": "my-tenant-id",
19
- "timeout": 10000,
20
- "maxRetries": 3,
21
- "retryDelay": 1000,
22
- "enableConnectionPooling": True,
23
- "maxSockets": 50,
24
- "compression": "snappy",
25
- "compressionLevel": 6,
26
- "compressionThreshold": 1024,
27
- "useWorkers": True,
28
- "maxWorkers": 2,
29
- "workerTimeout": 30000,
30
- },
31
- "buffer": {
32
- "maxSize": 1000,
33
- "flushInterval": 5000,
34
- "maxMemoryMB": 50,
35
- "maxAge": 30000,
36
- "autoFlush": True,
37
- },
38
- "filter": {
39
- "levels": ["info", "warn", "error", "fatal"],
40
- "patterns": ["health/check"],
41
- "samplingRate": 1.0,
42
- "sanitize": True,
43
- "sensitivePatterns": ["password", "token", "secret"],
44
- "maxMessageLength": 8192,
45
- },
46
- "circuitBreaker": {
47
- "enabled": True,
48
- "failureThreshold": 20,
49
- "resetTimeout": 30000,
50
- "halfOpenRequests": 3,
51
- },
52
- "deadLetterQueue": {
53
- "enabled": True,
54
- "type": "file",
55
- "basePath": "./.logs-dlq",
56
- "maxSize": 1000,
57
- "maxRetries": 10,
58
- },
59
- "performance": {
60
- "useWorkers": True,
61
- "maxConcurrentFlushes": 5,
62
- "workerTimeout": 30000,
63
- },
64
- "enableMetrics": True,
65
- "enableHealthCheck": True,
66
- }
67
- )
@@ -1,30 +0,0 @@
1
- from logs_interceptor import init, logger
2
-
3
- init(
4
- {
5
- "appName": "high-volume-service",
6
- "interceptConsole": True,
7
- "transport": {
8
- "url": "http://localhost:3100/loki/api/v1/push",
9
- "tenantId": "production",
10
- "compression": "snappy",
11
- "maxSockets": 100,
12
- "timeout": 10000,
13
- "useWorkers": True,
14
- "maxWorkers": 4,
15
- "compressionThreshold": 4096,
16
- "compressionLevel": 6,
17
- },
18
- "buffer": {
19
- "maxSize": 2000,
20
- "flushInterval": 2000,
21
- "maxMemoryMB": 512,
22
- },
23
- "performance": {
24
- "maxConcurrentFlushes": 10,
25
- },
26
- }
27
- )
28
-
29
- for i in range(10000):
30
- logger.info("High volume event", {"index": i})
@@ -1,14 +0,0 @@
1
- from logs_interceptor import init, logger
2
-
3
- init(
4
- {
5
- "appName": "analytics-service",
6
- "transport": {
7
- "url": "http://localhost:3100/loki/api/v1/push",
8
- "tenantId": "analytics",
9
- },
10
- }
11
- )
12
-
13
- logger.track_event("user_signup", {"user_id": "u_123", "plan": "pro"})
14
- logger.track_event("api_request", {"endpoint": "/users", "status_code": 200})
@@ -1,180 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -Eeuo pipefail
3
-
4
- ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
- cd "${ROOT_DIR}"
6
-
7
- PYTHON_BIN="${PYTHON_BIN:-python3}"
8
- REPOSITORY="testpypi"
9
- TOKEN_ENV=""
10
- SKIP_CHECKS=0
11
- SKIP_BUILD=0
12
- DRY_RUN=0
13
- SKIP_EXISTING=1
14
-
15
- TEST_PYPI_URL="https://test.pypi.org/legacy/"
16
- PYPI_URL="https://upload.pypi.org/legacy/"
17
-
18
- usage() {
19
- cat <<'EOF'
20
- Usage:
21
- ./scripts/publish.sh [options]
22
-
23
- Options:
24
- --repository {testpypi|pypi} Publish target (default: testpypi)
25
- --token-env NAME Env var with API token
26
- --skip-checks Skip ruff + mypy + pytest
27
- --skip-build Skip build and twine check steps
28
- --no-skip-existing Do not pass --skip-existing to twine upload
29
- --dry-run Run validations/build but do not upload
30
- -h, --help Show this message
31
-
32
- Env:
33
- PYTHON_BIN Python executable (default: python3)
34
- TEST_PYPI_API_TOKEN Default token env for --repository testpypi
35
- PYPI_API_TOKEN Default token env for --repository pypi
36
- EOF
37
- }
38
-
39
- require_python_module() {
40
- local module_name="$1"
41
- if ! "${PYTHON_BIN}" -c "import ${module_name}" >/dev/null 2>&1; then
42
- echo "Missing Python module: ${module_name}" >&2
43
- echo "Install dependencies with: ${PYTHON_BIN} -m pip install -e \".[dev]\"" >&2
44
- exit 1
45
- fi
46
- }
47
-
48
- run_checks() {
49
- echo "[publish] running quality gates..."
50
- "${PYTHON_BIN}" -m ruff check .
51
- "${PYTHON_BIN}" -m mypy src
52
- "${PYTHON_BIN}" -m pytest -q
53
- }
54
-
55
- clean_artifacts() {
56
- rm -rf build dist
57
- find . -maxdepth 1 -type d -name "*.egg-info" -exec rm -rf {} +
58
- }
59
-
60
- build_artifacts() {
61
- echo "[publish] building distribution artifacts..."
62
- clean_artifacts
63
- "${PYTHON_BIN}" -m build
64
- "${PYTHON_BIN}" -m twine check dist/*
65
- }
66
-
67
- resolve_repository_url() {
68
- if [[ "${REPOSITORY}" == "testpypi" ]]; then
69
- echo "${TEST_PYPI_URL}"
70
- return
71
- fi
72
- echo "${PYPI_URL}"
73
- }
74
-
75
- resolve_token_env() {
76
- if [[ -n "${TOKEN_ENV}" ]]; then
77
- echo "${TOKEN_ENV}"
78
- return
79
- fi
80
- if [[ "${REPOSITORY}" == "testpypi" ]]; then
81
- echo "TEST_PYPI_API_TOKEN"
82
- return
83
- fi
84
- echo "PYPI_API_TOKEN"
85
- }
86
-
87
- while [[ $# -gt 0 ]]; do
88
- case "$1" in
89
- --repository)
90
- REPOSITORY="$2"
91
- shift 2
92
- ;;
93
- --token-env)
94
- TOKEN_ENV="$2"
95
- shift 2
96
- ;;
97
- --skip-checks)
98
- SKIP_CHECKS=1
99
- shift
100
- ;;
101
- --skip-build)
102
- SKIP_BUILD=1
103
- shift
104
- ;;
105
- --no-skip-existing)
106
- SKIP_EXISTING=0
107
- shift
108
- ;;
109
- --dry-run)
110
- DRY_RUN=1
111
- shift
112
- ;;
113
- -h|--help)
114
- usage
115
- exit 0
116
- ;;
117
- *)
118
- echo "Unknown option: $1" >&2
119
- usage
120
- exit 1
121
- ;;
122
- esac
123
- done
124
-
125
- if [[ "${REPOSITORY}" != "testpypi" && "${REPOSITORY}" != "pypi" ]]; then
126
- echo "Invalid --repository value: ${REPOSITORY}" >&2
127
- exit 1
128
- fi
129
-
130
- if [[ "${SKIP_CHECKS}" -eq 0 ]]; then
131
- require_python_module "ruff"
132
- require_python_module "mypy"
133
- require_python_module "pytest"
134
- fi
135
-
136
- if [[ "${SKIP_BUILD}" -eq 0 ]]; then
137
- require_python_module "build"
138
- require_python_module "twine"
139
- elif [[ "${DRY_RUN}" -eq 0 ]]; then
140
- require_python_module "twine"
141
- fi
142
-
143
- if [[ "${SKIP_CHECKS}" -eq 0 ]]; then
144
- run_checks
145
- fi
146
-
147
- if [[ "${SKIP_BUILD}" -eq 0 ]]; then
148
- build_artifacts
149
- fi
150
-
151
- if [[ "${DRY_RUN}" -eq 1 ]]; then
152
- echo "[publish] dry-run enabled, upload skipped."
153
- echo "[publish] built files:"
154
- ls -1 dist/* 2>/dev/null || true
155
- exit 0
156
- fi
157
-
158
- repository_url="$(resolve_repository_url)"
159
- token_env_name="$(resolve_token_env)"
160
- token_value="${!token_env_name-}"
161
-
162
- if [[ -z "${token_value}" ]]; then
163
- echo "Missing publish token in env var: ${token_env_name}" >&2
164
- exit 1
165
- fi
166
-
167
- twine_args=(
168
- upload
169
- --repository-url "${repository_url}"
170
- --non-interactive
171
- )
172
- if [[ "${SKIP_EXISTING}" -eq 1 ]]; then
173
- twine_args+=(--skip-existing)
174
- fi
175
- twine_args+=(dist/*)
176
-
177
- echo "[publish] uploading to ${REPOSITORY} (${repository_url})..."
178
- TWINE_USERNAME="__token__" TWINE_PASSWORD="${token_value}" "${PYTHON_BIN}" -m twine "${twine_args[@]}"
179
-
180
- echo "[publish] done."
@@ -1,49 +0,0 @@
1
- LOGS_URL=https://loki.elvenobservability.com/loki/api/v1/push
2
- LOGS_TENANT=elven
3
- LOGS_TOKEN=replace-with-your-token
4
- LOGS_APP_NAME=elven-live-demo
5
- LOGS_APP_VERSION=1.0.0
6
- LOGS_ENVIRONMENT=local
7
-
8
- LOGS_COMPRESSION=gzip
9
- LOGS_COMPRESSION_LEVEL=4
10
- LOGS_COMPRESSION_THRESHOLD=1024
11
- LOGS_CONNECTION_POOLING=true
12
- LOGS_MAX_SOCKETS=50
13
- LOGS_TIMEOUT=10000
14
- LOGS_MAX_RETRIES=3
15
- LOGS_RETRY_DELAY=1000
16
-
17
- LOGS_BUFFER_MAX_SIZE=25
18
- LOGS_BUFFER_FLUSH_INTERVAL=1500
19
- LOGS_BUFFER_MAX_MEMORY_MB=128
20
- LOGS_BUFFER_MAX_AGE=30000
21
- LOGS_BUFFER_AUTO_FLUSH=true
22
-
23
- LOGS_FILTER_LEVELS=debug,info,warn,error,fatal
24
- LOGS_FILTER_SAMPLING_RATE=1.0
25
- LOGS_FILTER_SANITIZE=true
26
- LOGS_FILTER_MAX_MESSAGE_LENGTH=8192
27
-
28
- LOGS_CIRCUIT_BREAKER_ENABLED=true
29
- LOGS_CIRCUIT_BREAKER_FAILURE_THRESHOLD=20
30
- LOGS_CIRCUIT_BREAKER_RESET_TIMEOUT=15000
31
- LOGS_CIRCUIT_BREAKER_HALF_OPEN_REQUESTS=3
32
-
33
- LOGS_DLQ_ENABLED=true
34
- LOGS_DLQ_TYPE=file
35
- LOGS_DLQ_MAX_SIZE=1000
36
- LOGS_DLQ_MAX_RETRIES=3
37
- LOGS_DLQ_BASE_PATH=./.logs-dlq
38
-
39
- LOGS_MAX_CONCURRENT_FLUSHES=5
40
- LOGS_INTERCEPT_CONSOLE=true
41
- LOGS_PRESERVE_ORIGINAL_CONSOLE=true
42
- LOGS_ENABLE_METRICS=true
43
- LOGS_ENABLE_HEALTH_CHECK=true
44
- LOGS_DEBUG=false
45
- LOGS_SILENT_ERRORS=false
46
- LOGS_ENABLED=true
47
-
48
- LOGS_LABEL_SERVICE=elven-live-demo
49
- LOGS_LABEL_ENVIRONMENT=local
@@ -1,17 +0,0 @@
1
- # Elven Live Demo
2
-
3
- Local Python app to exercise `elven-logs-interceptor-python` against the Elven Loki endpoint.
4
-
5
- ## Run
6
-
7
- ```bash
8
- cd /Users/leonardozwirtes/Documents/Projects/logs-interceptor-python
9
- chmod +x test-apps/elven-live-demo/run.sh
10
- ./test-apps/elven-live-demo/run.sh
11
- ```
12
-
13
- ## Notes
14
-
15
- - The tracked config template is `.env.example`.
16
- - The real token lives only in local `.env`, which is ignored by Git.
17
- - The package import remains `logs_interceptor`.