fastapi-observer 1.3.1__tar.gz → 1.3.2__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.
- {fastapi_observer-1.3.1/src/fastapi_observer.egg-info → fastapi_observer-1.3.2}/PKG-INFO +1 -1
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2/src/fastapi_observer.egg-info}/PKG-INFO +1 -1
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapi_observer.egg-info/SOURCES.txt +1 -0
- fastapi_observer-1.3.2/src/fastapiobserver/_version.py +1 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/fastapi.py +8 -7
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/logging/setup.py +51 -0
- fastapi_observer-1.3.2/tests/test_fork_queue_listener.py +61 -0
- fastapi_observer-1.3.1/src/fastapiobserver/_version.py +0 -1
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/LICENSE +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/README.md +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/pyproject.toml +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/setup.cfg +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapi_observer.egg-info/dependency_links.txt +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapi_observer.egg-info/requires.txt +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapi_observer.egg-info/top_level.txt +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/__init__.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/audit/__init__.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/audit/formatter.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/audit/providers.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/audit/verify.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/config.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/control_plane.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/db_tracing.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/integrations/__init__.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/integrations/strawberry.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/logging/__init__.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/logging/circuit_breaker.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/logging/filters.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/logging/formatter.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/logging/queueing.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/logging/state.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/loguru.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/metrics/__init__.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/metrics/builder.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/metrics/contracts.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/metrics/endpoint.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/metrics/noop.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/metrics/pathing.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/metrics/prometheus/__init__.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/metrics/prometheus/backend.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/metrics/prometheus/client.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/metrics/prometheus/collector.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/metrics/prometheus/exemplars.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/metrics/prometheus/multiprocess.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/metrics/registry.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/middleware/__init__.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/middleware/body_capture.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/middleware/context.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/middleware/events.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/middleware/headers.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/middleware/ip.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/middleware/metrics.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/middleware/request_logging.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/middleware/span_errors.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/otel/__init__.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/otel/lifecycle.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/otel/logs.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/otel/metrics.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/otel/resource.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/otel/settings.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/otel/tracing.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/otel/types.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/plugins.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/profiles.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/propagation.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/py.typed +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/request_context.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/security/__init__.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/security/normalize.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/security/policy.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/security/proxies.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/security/redaction.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/sinks/__init__.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/sinks/builtin.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/sinks/discovery.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/sinks/factory.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/sinks/logtail/__init__.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/sinks/logtail/dlq.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/sinks/logtail/handler.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/sinks/logtail/sink.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/sinks/protocol.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/sinks/registry.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/sinks/stats.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/utils.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_audit_chain.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_body_media_allowlist.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_config_settings.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_db_tracing.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_dx_parity.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_excluded_url_precedence.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_fastapi_install.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_graphql_integrations.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_lifespan_teardown.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_log_queue_controls.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_logging_schema_contract.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_logtail_dlq.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_loguru_bridge.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_metrics_contracts.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_metrics_optional_dependency.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_middleware.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_negotiate_content_type.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_otel_integration.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_otel_lifecycle.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_otel_log_correlation.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_otel_logs_from_env.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_otel_logs_pipeline.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_otel_metrics_from_env.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_otlp_export_integration.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_plugin_isolation.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_profiles.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_propagation.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_redaction_presets.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_route_template_cardinality.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_runtime_control_auth.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_security_audit_fixes.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_security_redaction.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_sink_circuit_breaker.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_sinks.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_trust_boundary.py +0 -0
- {fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/tests/test_utils_refactors.py +0 -0
|
@@ -85,6 +85,7 @@ tests/test_db_tracing.py
|
|
|
85
85
|
tests/test_dx_parity.py
|
|
86
86
|
tests/test_excluded_url_precedence.py
|
|
87
87
|
tests/test_fastapi_install.py
|
|
88
|
+
tests/test_fork_queue_listener.py
|
|
88
89
|
tests/test_graphql_integrations.py
|
|
89
90
|
tests/test_lifespan_teardown.py
|
|
90
91
|
tests/test_log_queue_controls.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.3.2"
|
|
@@ -213,6 +213,9 @@ def _auto_discover_excluded_routes(app: FastAPI, settings: ObservabilitySettings
|
|
|
213
213
|
"""Auto-discover routes like /docs, /openapi.json, or include_in_schema=False."""
|
|
214
214
|
# Build a set of paths to exclude
|
|
215
215
|
excluded = set(settings.metrics_exclude_paths)
|
|
216
|
+
if settings.metrics_path:
|
|
217
|
+
excluded.update(_build_exclude_path_variants(settings.metrics_path))
|
|
218
|
+
|
|
216
219
|
for route in app.routes:
|
|
217
220
|
path = getattr(route, "path", None)
|
|
218
221
|
if not path:
|
|
@@ -233,7 +236,10 @@ def _auto_discover_excluded_routes(app: FastAPI, settings: ObservabilitySettings
|
|
|
233
236
|
while hasattr(current, "app"):
|
|
234
237
|
# Check by name since we don't want a hard dependency
|
|
235
238
|
if current.__class__.__name__ == "OpenTelemetryMiddleware":
|
|
236
|
-
|
|
239
|
+
try:
|
|
240
|
+
from opentelemetry.util.http import parse_excluded_urls
|
|
241
|
+
except ImportError:
|
|
242
|
+
break
|
|
237
243
|
|
|
238
244
|
current_excluded: set[str] = set()
|
|
239
245
|
for attr_name in ("excluded_urls", "_excluded_urls"):
|
|
@@ -293,10 +299,7 @@ def _register_logging_shutdown_hook(app: FastAPI) -> None:
|
|
|
293
299
|
async def auto_observability_lifespan(
|
|
294
300
|
app_inst: FastAPI,
|
|
295
301
|
) -> typing.AsyncGenerator[typing.Any, None]:
|
|
296
|
-
|
|
297
|
-
_auto_discover_excluded_routes(app_inst, app_inst.state._observability_settings)
|
|
298
|
-
|
|
299
|
-
try:
|
|
302
|
+
async with observability_lifespan(app_inst):
|
|
300
303
|
if original_lifespan:
|
|
301
304
|
# If the user is explicitly using observability_lifespan inside their
|
|
302
305
|
# original_lifespan, this will safely no-op during cleanup because
|
|
@@ -305,8 +308,6 @@ def _register_logging_shutdown_hook(app: FastAPI) -> None:
|
|
|
305
308
|
yield state
|
|
306
309
|
else:
|
|
307
310
|
yield {}
|
|
308
|
-
finally:
|
|
309
|
-
_teardown_observability(app_inst)
|
|
310
311
|
|
|
311
312
|
app.router.lifespan_context = auto_observability_lifespan
|
|
312
313
|
_REGISTERED_APPS.add(app)
|
|
@@ -193,6 +193,7 @@ def setup_logging(
|
|
|
193
193
|
state._QUEUE_LISTENER = listener
|
|
194
194
|
state._MANAGED_OUTPUT_HANDLERS = managed_output_handlers
|
|
195
195
|
_ensure_atexit_shutdown_hook_locked()
|
|
196
|
+
_ensure_fork_reinitialization_locked()
|
|
196
197
|
|
|
197
198
|
for name in ("uvicorn", "uvicorn.error", "uvicorn.access"):
|
|
198
199
|
uvicorn_logger = logging.getLogger(name)
|
|
@@ -217,6 +218,56 @@ def _ensure_atexit_shutdown_hook_locked() -> None:
|
|
|
217
218
|
state._ATEXIT_SHUTDOWN_REGISTERED = True
|
|
218
219
|
|
|
219
220
|
|
|
221
|
+
def _ensure_fork_reinitialization_locked() -> None:
|
|
222
|
+
import os
|
|
223
|
+
import fastapiobserver.logging.state as state
|
|
224
|
+
if getattr(state, "_FORK_HOOK_REGISTERED", False):
|
|
225
|
+
return
|
|
226
|
+
if hasattr(os, "register_at_fork"):
|
|
227
|
+
os.register_at_fork(after_in_child=_restart_queue_listener_in_child)
|
|
228
|
+
setattr(state, "_FORK_HOOK_REGISTERED", True)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def _restart_queue_listener_in_child() -> None:
|
|
232
|
+
import fastapiobserver.logging.state as state
|
|
233
|
+
|
|
234
|
+
listener = state._QUEUE_LISTENER
|
|
235
|
+
if listener is not None:
|
|
236
|
+
# The inherited queue's Condition lock might be held by the parent
|
|
237
|
+
# or left in an inconsistent state across the fork. To reliably resume
|
|
238
|
+
# processing, we must create a fresh queue and manually drain any
|
|
239
|
+
# inherited records from the old queue.
|
|
240
|
+
old_queue = cast(queue.Queue[logging.LogRecord], listener.queue)
|
|
241
|
+
new_queue: queue.Queue[logging.LogRecord] = queue.Queue(maxsize=old_queue.maxsize)
|
|
242
|
+
|
|
243
|
+
while not old_queue.empty():
|
|
244
|
+
try:
|
|
245
|
+
record = old_queue.get_nowait()
|
|
246
|
+
new_queue.put_nowait(record)
|
|
247
|
+
except queue.Empty:
|
|
248
|
+
break
|
|
249
|
+
except queue.Full:
|
|
250
|
+
break
|
|
251
|
+
|
|
252
|
+
# Re-attach the new queue to the OverflowPolicyQueueHandler if present
|
|
253
|
+
for handler in state._MANAGED_HANDLERS:
|
|
254
|
+
from .queueing import OverflowPolicyQueueHandler
|
|
255
|
+
|
|
256
|
+
if (
|
|
257
|
+
isinstance(handler, OverflowPolicyQueueHandler)
|
|
258
|
+
and getattr(handler, "queue", None) is old_queue
|
|
259
|
+
):
|
|
260
|
+
handler.queue = new_queue
|
|
261
|
+
|
|
262
|
+
new_listener = logging.handlers.QueueListener(
|
|
263
|
+
new_queue,
|
|
264
|
+
*listener.handlers,
|
|
265
|
+
respect_handler_level=listener.respect_handler_level,
|
|
266
|
+
)
|
|
267
|
+
state._QUEUE_LISTENER = new_listener
|
|
268
|
+
new_listener.start()
|
|
269
|
+
|
|
270
|
+
|
|
220
271
|
def _wrap_sink_handlers(
|
|
221
272
|
handlers_with_names: list[tuple[logging.Handler, str]],
|
|
222
273
|
*,
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import queue
|
|
3
|
+
from unittest.mock import Mock
|
|
4
|
+
from fastapiobserver.logging.setup import _restart_queue_listener_in_child
|
|
5
|
+
import fastapiobserver.logging.state as state
|
|
6
|
+
from fastapiobserver.logging.queueing import OverflowPolicyQueueHandler
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def test_restart_queue_listener_in_child_drains_and_recreates_queue():
|
|
10
|
+
# Setup mock state
|
|
11
|
+
old_queue = queue.Queue(maxsize=10)
|
|
12
|
+
old_queue.put_nowait(
|
|
13
|
+
logging.LogRecord("test", logging.INFO, "path", 1, "test msg 1", None, None)
|
|
14
|
+
)
|
|
15
|
+
old_queue.put_nowait(
|
|
16
|
+
logging.LogRecord("test", logging.INFO, "path", 1, "test msg 2", None, None)
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
mock_queue_handler = Mock(spec=OverflowPolicyQueueHandler)
|
|
20
|
+
mock_queue_handler.queue = old_queue
|
|
21
|
+
|
|
22
|
+
mock_listener = Mock()
|
|
23
|
+
mock_listener.queue = old_queue
|
|
24
|
+
mock_listener.handlers = []
|
|
25
|
+
mock_listener.respect_handler_level = True
|
|
26
|
+
|
|
27
|
+
# Temporarily override state module
|
|
28
|
+
original_listener = state._QUEUE_LISTENER
|
|
29
|
+
original_handlers = state._MANAGED_HANDLERS
|
|
30
|
+
|
|
31
|
+
state._QUEUE_LISTENER = mock_listener
|
|
32
|
+
state._MANAGED_HANDLERS = {mock_queue_handler}
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
# Action
|
|
36
|
+
_restart_queue_listener_in_child()
|
|
37
|
+
|
|
38
|
+
# Assertions
|
|
39
|
+
assert old_queue.empty()
|
|
40
|
+
|
|
41
|
+
# Verify the new listener was created and started
|
|
42
|
+
new_listener = state._QUEUE_LISTENER
|
|
43
|
+
assert new_listener is not mock_listener
|
|
44
|
+
assert new_listener.queue is not old_queue
|
|
45
|
+
assert isinstance(new_listener, logging.handlers.QueueListener)
|
|
46
|
+
# We cannot reliably assert new_listener.queue.qsize() == 2 because
|
|
47
|
+
# new_listener.start() spins up a thread that immediately begins consuming.
|
|
48
|
+
|
|
49
|
+
# Verify the managed handler got the new queue assigned to its .queue attribute
|
|
50
|
+
assert mock_queue_handler.queue is new_listener.queue
|
|
51
|
+
|
|
52
|
+
# The actual QueueListener thread isn't started in mock but the object is created
|
|
53
|
+
# new_listener.start() was called during _restart_queue_listener_in_child
|
|
54
|
+
|
|
55
|
+
finally:
|
|
56
|
+
# Cleanup threading if start started a thread, and restore state
|
|
57
|
+
if isinstance(state._QUEUE_LISTENER, logging.handlers.QueueListener):
|
|
58
|
+
state._QUEUE_LISTENER.stop()
|
|
59
|
+
|
|
60
|
+
state._QUEUE_LISTENER = original_listener
|
|
61
|
+
state._MANAGED_HANDLERS = original_handlers
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.3.1"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapi_observer.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapi_observer.egg-info/requires.txt
RENAMED
|
File without changes
|
{fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapi_observer.egg-info/top_level.txt
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
|
{fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/integrations/__init__.py
RENAMED
|
File without changes
|
{fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/integrations/strawberry.py
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/logging/circuit_breaker.py
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
|
{fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/metrics/prometheus/__init__.py
RENAMED
|
File without changes
|
{fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/metrics/prometheus/backend.py
RENAMED
|
File without changes
|
{fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/metrics/prometheus/client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/middleware/__init__.py
RENAMED
|
File without changes
|
{fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/middleware/body_capture.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/middleware/request_logging.py
RENAMED
|
File without changes
|
{fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/middleware/span_errors.py
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
|
{fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/sinks/logtail/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_observer-1.3.1 → fastapi_observer-1.3.2}/src/fastapiobserver/sinks/logtail/handler.py
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
|