fastapi-observer 0.3.1__tar.gz → 0.4.0__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-0.3.1/src/fastapi_observer.egg-info → fastapi_observer-0.4.0}/PKG-INFO +95 -5
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/README.md +93 -4
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/pyproject.toml +1 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0/src/fastapi_observer.egg-info}/PKG-INFO +95 -5
- fastapi_observer-0.4.0/src/fastapi_observer.egg-info/SOURCES.txt +104 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapi_observer.egg-info/requires.txt +1 -0
- fastapi_observer-0.4.0/src/fastapiobserver/_version.py +1 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapiobserver/control_plane.py +7 -1
- fastapi_observer-0.4.0/src/fastapiobserver/logging/__init__.py +36 -0
- fastapi_observer-0.4.0/src/fastapiobserver/logging/circuit_breaker.py +158 -0
- fastapi_observer-0.4.0/src/fastapiobserver/logging/filters.py +53 -0
- fastapi_observer-0.4.0/src/fastapiobserver/logging/formatter.py +157 -0
- fastapi_observer-0.4.0/src/fastapiobserver/logging/queueing.py +197 -0
- fastapi_observer-0.4.0/src/fastapiobserver/logging/setup.py +239 -0
- fastapi_observer-0.4.0/src/fastapiobserver/logging/state.py +17 -0
- fastapi_observer-0.4.0/src/fastapiobserver/metrics/__init__.py +41 -0
- fastapi_observer-0.4.0/src/fastapiobserver/metrics/builder.py +48 -0
- fastapi_observer-0.4.0/src/fastapiobserver/metrics/contracts.py +39 -0
- fastapi_observer-0.4.0/src/fastapiobserver/metrics/endpoint.py +176 -0
- fastapi_observer-0.4.0/src/fastapiobserver/metrics/noop.py +15 -0
- fastapi_observer-0.4.0/src/fastapiobserver/metrics/pathing.py +18 -0
- fastapi_observer-0.4.0/src/fastapiobserver/metrics/prometheus/__init__.py +21 -0
- fastapi_observer-0.4.0/src/fastapiobserver/metrics/prometheus/backend.py +126 -0
- fastapi_observer-0.4.0/src/fastapiobserver/metrics/prometheus/client.py +19 -0
- fastapi_observer-0.4.0/src/fastapiobserver/metrics/prometheus/collector.py +170 -0
- fastapi_observer-0.4.0/src/fastapiobserver/metrics/prometheus/exemplars.py +19 -0
- fastapi_observer-0.4.0/src/fastapiobserver/metrics/prometheus/multiprocess.py +38 -0
- fastapi_observer-0.4.0/src/fastapiobserver/metrics/registry.py +42 -0
- fastapi_observer-0.4.0/src/fastapiobserver/middleware/__init__.py +27 -0
- fastapi_observer-0.4.0/src/fastapiobserver/middleware/body_capture.py +37 -0
- fastapi_observer-0.4.0/src/fastapiobserver/middleware/context.py +63 -0
- fastapi_observer-0.4.0/src/fastapiobserver/middleware/events.py +81 -0
- fastapi_observer-0.4.0/src/fastapiobserver/middleware/headers.py +21 -0
- fastapi_observer-0.4.0/src/fastapiobserver/middleware/ip.py +40 -0
- fastapi_observer-0.4.0/src/fastapiobserver/middleware/metrics.py +61 -0
- fastapi_observer-0.4.0/src/fastapiobserver/middleware/request_logging.py +154 -0
- fastapi_observer-0.4.0/src/fastapiobserver/middleware/span_errors.py +34 -0
- fastapi_observer-0.4.0/src/fastapiobserver/security/__init__.py +31 -0
- fastapi_observer-0.4.0/src/fastapiobserver/security/normalize.py +8 -0
- fastapi_observer-0.3.1/src/fastapiobserver/security.py → fastapi_observer-0.4.0/src/fastapiobserver/security/policy.py +19 -195
- fastapi_observer-0.4.0/src/fastapiobserver/security/proxies.py +49 -0
- fastapi_observer-0.4.0/src/fastapiobserver/security/redaction.py +150 -0
- fastapi_observer-0.4.0/src/fastapiobserver/sinks/__init__.py +25 -0
- fastapi_observer-0.4.0/src/fastapiobserver/sinks/builtin.py +56 -0
- fastapi_observer-0.4.0/src/fastapiobserver/sinks/discovery.py +68 -0
- fastapi_observer-0.4.0/src/fastapiobserver/sinks/factory.py +73 -0
- fastapi_observer-0.4.0/src/fastapiobserver/sinks/logtail/__init__.py +5 -0
- fastapi_observer-0.4.0/src/fastapiobserver/sinks/logtail/dlq.py +130 -0
- fastapi_observer-0.4.0/src/fastapiobserver/sinks/logtail/handler.py +205 -0
- fastapi_observer-0.4.0/src/fastapiobserver/sinks/logtail/sink.py +66 -0
- fastapi_observer-0.4.0/src/fastapiobserver/sinks/protocol.py +15 -0
- fastapi_observer-0.4.0/src/fastapiobserver/sinks/registry.py +33 -0
- fastapi_observer-0.4.0/src/fastapiobserver/sinks/stats.py +55 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_log_queue_controls.py +17 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_logging_schema_contract.py +33 -12
- fastapi_observer-0.4.0/tests/test_metrics_contracts.py +111 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_metrics_optional_dependency.py +4 -4
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_middleware.py +34 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_sink_circuit_breaker.py +21 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_sinks.py +80 -36
- fastapi_observer-0.3.1/src/fastapi_observer.egg-info/SOURCES.txt +0 -63
- fastapi_observer-0.3.1/src/fastapiobserver/_version.py +0 -1
- fastapi_observer-0.3.1/src/fastapiobserver/logging.py +0 -825
- fastapi_observer-0.3.1/src/fastapiobserver/metrics.py +0 -668
- fastapi_observer-0.3.1/src/fastapiobserver/middleware.py +0 -443
- fastapi_observer-0.3.1/src/fastapiobserver/sinks.py +0 -677
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/LICENSE +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/setup.cfg +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapi_observer.egg-info/dependency_links.txt +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapi_observer.egg-info/top_level.txt +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapiobserver/__init__.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapiobserver/config.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapiobserver/fastapi.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapiobserver/integrations/__init__.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapiobserver/integrations/strawberry.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapiobserver/loguru.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapiobserver/otel/__init__.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapiobserver/otel/lifecycle.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapiobserver/otel/logs.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapiobserver/otel/metrics.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapiobserver/otel/resource.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapiobserver/otel/settings.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapiobserver/otel/tracing.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapiobserver/otel/types.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapiobserver/plugins.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapiobserver/propagation.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapiobserver/py.typed +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapiobserver/request_context.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/src/fastapiobserver/utils.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_body_media_allowlist.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_config_settings.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_excluded_url_precedence.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_fastapi_install.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_graphql_integrations.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_logtail_dlq.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_loguru_bridge.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_negotiate_content_type.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_otel_integration.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_otel_lifecycle.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_otel_log_correlation.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_otel_logs_from_env.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_otel_logs_pipeline.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_otel_metrics_from_env.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_otlp_export_integration.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_plugin_isolation.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_propagation.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_redaction_presets.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_route_template_cardinality.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_runtime_control_auth.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_security_redaction.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_trust_boundary.py +0 -0
- {fastapi_observer-0.3.1 → fastapi_observer-0.4.0}/tests/test_utils_refactors.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastapi-observer
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Zero-glue FastAPI observability with security presets and runtime controls
|
|
5
5
|
Author-email: Vitaee <opensource@vitaee.dev>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -65,6 +65,7 @@ Requires-Dist: pytest>=9.0.2; extra == "dev"
|
|
|
65
65
|
Requires-Dist: pytest-randomly>=3.16.0; extra == "dev"
|
|
66
66
|
Requires-Dist: ruff>=0.15.1; extra == "dev"
|
|
67
67
|
Requires-Dist: cyclonedx-bom>=7.2.1; extra == "dev"
|
|
68
|
+
Requires-Dist: uvicorn>=0.30.0; extra == "dev"
|
|
68
69
|
Dynamic: license-file
|
|
69
70
|
|
|
70
71
|
# fastapi-observer
|
|
@@ -391,6 +392,19 @@ Request arrives
|
|
|
391
392
|
-> context cleared
|
|
392
393
|
```
|
|
393
394
|
|
|
395
|
+
### Internal Package Layout (Contributor Map)
|
|
396
|
+
|
|
397
|
+
The project is now organized as focused subpackages instead of large monolithic modules:
|
|
398
|
+
|
|
399
|
+
- `fastapiobserver/logging/`: formatter, queueing, filters, setup lifecycle, sink circuit-breakers.
|
|
400
|
+
- `fastapiobserver/middleware/`: request logging orchestration, context, IP resolution, headers, body capture, metrics hooks.
|
|
401
|
+
- `fastapiobserver/sinks/`: sink protocol, registry/discovery, built-ins, factory wiring, Logtail + DLQ implementation.
|
|
402
|
+
- `fastapiobserver/metrics/`: backend contracts/registry/builder/endpoint, Prometheus integration subpackage.
|
|
403
|
+
- `fastapiobserver/security/`: policy/settings models, normalization helpers, redaction engine, trusted-proxy utilities.
|
|
404
|
+
- `fastapiobserver/otel/`: OTel settings/resource/tracing/logs/metrics/lifecycle helpers.
|
|
405
|
+
|
|
406
|
+
Public imports remain backward-compatible via package facades (`__init__.py` re-exports).
|
|
407
|
+
|
|
394
408
|
---
|
|
395
409
|
|
|
396
410
|
## Example JSON Log Event
|
|
@@ -570,11 +584,57 @@ kubectl -n observability rollout status deployment/traffic-generator
|
|
|
570
584
|
kubectl -n observability port-forward svc/grafana 3000:3000
|
|
571
585
|
```
|
|
572
586
|
|
|
573
|
-
Open [http://localhost:3000](http://localhost:3000).
|
|
587
|
+
Open [http://localhost:3000](http://localhost:3000).
|
|
574
588
|
Full guide: [`kubernetes.md`](kubernetes.md)
|
|
575
589
|
|
|
576
590
|
---
|
|
577
591
|
|
|
592
|
+
## Low-Overhead & Production Tuning (Advanced)
|
|
593
|
+
|
|
594
|
+
`fastapi-observer` integrates natively with the core OpenTelemetry Python SDK, meaning you can aggressively tune its resource usage purely via standard environment variables without altering your application code.
|
|
595
|
+
|
|
596
|
+
For high-throughput services (e.g. `10k+ RPS`), apply these exact variables to minimize the observer footprint:
|
|
597
|
+
|
|
598
|
+
### 1. Head-Based Sampling
|
|
599
|
+
|
|
600
|
+
Tracing 100% of requests is too expensive at scale. You should configure `fastapi-observer` to respect upstream trace flags, while only sampling a fraction of net-new requests:
|
|
601
|
+
|
|
602
|
+
```bash
|
|
603
|
+
# Keep the parent's sample decision if it exists, otherwise sample 5%
|
|
604
|
+
export OTEL_TRACES_SAMPLER="parentbased_traceidratio"
|
|
605
|
+
export OTEL_TRACES_SAMPLER_ARG="0.05"
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
### 2. Exclude Noisy URLs from the SDK
|
|
609
|
+
|
|
610
|
+
Do not waste cycles generating spans for health checks or static assets. `fastapi-observer` will auto-derive metrics exclusions, but you can explicitly drop them from tracing at the C-extension level:
|
|
611
|
+
|
|
612
|
+
```bash
|
|
613
|
+
export OTEL_PYTHON_FASTAPI_EXCLUDED_URLS="healthz,metrics,favicon.ico"
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
### 3. Cap Span Attributes
|
|
617
|
+
|
|
618
|
+
Prevent large, unmanageable spans from consuming excessive memory in the `BatchSpanProcessor`:
|
|
619
|
+
|
|
620
|
+
```bash
|
|
621
|
+
export OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT="128"
|
|
622
|
+
export OTEL_SPAN_EVENT_COUNT_LIMIT="128"
|
|
623
|
+
export OTEL_SPAN_LINK_COUNT_LIMIT="128"
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
### 4. Optimize Output Buffers
|
|
627
|
+
|
|
628
|
+
The default OpenTelemetry batch limits are too conservative for high-throughput ASGI microservices. Increase the max queue limits so spikes aren't dropped, but decrease the timeout so the process memory is flushed faster:
|
|
629
|
+
|
|
630
|
+
```bash
|
|
631
|
+
export OTEL_BSP_MAX_QUEUE_SIZE="10000"
|
|
632
|
+
export OTEL_BSP_MAX_EXPORT_BATCH_SIZE="5000"
|
|
633
|
+
export OTEL_BSP_SCHEDULE_DELAY="1000"
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
---
|
|
637
|
+
|
|
578
638
|
## Examples
|
|
579
639
|
|
|
580
640
|
The `examples/` directory contains runnable demos:
|
|
@@ -729,7 +789,36 @@ install_observability(app, settings, security_policy=SecurityPolicy(log_request_
|
|
|
729
789
|
app.add_middleware(CORSMiddleware, allow_origins=["*"])
|
|
730
790
|
```
|
|
731
791
|
|
|
732
|
-
### Multi-worker Gunicorn
|
|
792
|
+
### Multi-worker Gunicorn
|
|
793
|
+
|
|
794
|
+
> [!WARNING]
|
|
795
|
+
> `--preload-app` is dangerous if visibility is initialized at the module level.
|
|
796
|
+
>
|
|
797
|
+
> When `--preload-app` is used, the application is loaded into the master process *before* forking the worker processes. `fastapi-observer` uses a highly-performant background thread (`QueueListener`) for non-blocking logging, and OpenTelemetry similarly spawns background export threads.
|
|
798
|
+
>
|
|
799
|
+
> Threads **do not survive** a process fork. If you call `install_observability()` at the module level (e.g., right under `app = FastAPI()`), the background threads will be created in the master process, and all workers will silently drop logs because their logging threads never started.
|
|
800
|
+
>
|
|
801
|
+
> **How to fix:** Either remove `--preload-app`, OR initialize observability inside the FastAPI `lifespan` context manager so it starts safely after the fork inside each worker:
|
|
802
|
+
>
|
|
803
|
+
> ```python
|
|
804
|
+
> from contextlib import asynccontextmanager
|
|
805
|
+
> from fastapi import FastAPI
|
|
806
|
+
> from fastapiobserver import ObservabilitySettings, install_observability
|
|
807
|
+
>
|
|
808
|
+
> settings = ObservabilitySettings(service="api")
|
|
809
|
+
>
|
|
810
|
+
> @asynccontextmanager
|
|
811
|
+
> async def lifespan(app: FastAPI):
|
|
812
|
+
> install_observability(app, settings) # Safely initializes per-worker
|
|
813
|
+
> yield
|
|
814
|
+
> # fastapiobserver automatically registers shutdown hooks so no teardown needed here
|
|
815
|
+
>
|
|
816
|
+
> app = FastAPI(lifespan=lifespan)
|
|
817
|
+
> ```
|
|
818
|
+
|
|
819
|
+
#### Prometheus Multiprocess Mode
|
|
820
|
+
|
|
821
|
+
If you are using Prometheus with multiple Gunicorn workers, you must configure a shared metrics directory:
|
|
733
822
|
|
|
734
823
|
```bash
|
|
735
824
|
export PROMETHEUS_MULTIPROC_DIR=/tmp/prometheus-metrics
|
|
@@ -961,9 +1050,10 @@ Reproducible benchmark harness and methodology:
|
|
|
961
1050
|
|
|
962
1051
|
- `0.1.x`: secure-by-default core
|
|
963
1052
|
- `0.2.x`: OTel interoperability, security presets, allowlists
|
|
1053
|
+
- `0.3.x`: package modularization, sink/metrics hardening, and performance reliability updates
|
|
964
1054
|
- `1.0.0`: dynamic runtime controls and plugin stability
|
|
965
1055
|
|
|
966
|
-
Current release version: `0.
|
|
1056
|
+
Current release version: `0.4.0`
|
|
967
1057
|
|
|
968
1058
|
## Changelog Policy
|
|
969
1059
|
|
|
@@ -1018,4 +1108,4 @@ The pre-push hook runs:
|
|
|
1018
1108
|
|
|
1019
1109
|
## Roadmap Tracking
|
|
1020
1110
|
|
|
1021
|
-
See [NEXT_STEPS.md](NEXT_STEPS.md) for the active
|
|
1111
|
+
See [NEXT_STEPS.md](NEXT_STEPS.md) for the active roadmap and release checklist.
|
|
@@ -322,6 +322,19 @@ Request arrives
|
|
|
322
322
|
-> context cleared
|
|
323
323
|
```
|
|
324
324
|
|
|
325
|
+
### Internal Package Layout (Contributor Map)
|
|
326
|
+
|
|
327
|
+
The project is now organized as focused subpackages instead of large monolithic modules:
|
|
328
|
+
|
|
329
|
+
- `fastapiobserver/logging/`: formatter, queueing, filters, setup lifecycle, sink circuit-breakers.
|
|
330
|
+
- `fastapiobserver/middleware/`: request logging orchestration, context, IP resolution, headers, body capture, metrics hooks.
|
|
331
|
+
- `fastapiobserver/sinks/`: sink protocol, registry/discovery, built-ins, factory wiring, Logtail + DLQ implementation.
|
|
332
|
+
- `fastapiobserver/metrics/`: backend contracts/registry/builder/endpoint, Prometheus integration subpackage.
|
|
333
|
+
- `fastapiobserver/security/`: policy/settings models, normalization helpers, redaction engine, trusted-proxy utilities.
|
|
334
|
+
- `fastapiobserver/otel/`: OTel settings/resource/tracing/logs/metrics/lifecycle helpers.
|
|
335
|
+
|
|
336
|
+
Public imports remain backward-compatible via package facades (`__init__.py` re-exports).
|
|
337
|
+
|
|
325
338
|
---
|
|
326
339
|
|
|
327
340
|
## Example JSON Log Event
|
|
@@ -501,11 +514,57 @@ kubectl -n observability rollout status deployment/traffic-generator
|
|
|
501
514
|
kubectl -n observability port-forward svc/grafana 3000:3000
|
|
502
515
|
```
|
|
503
516
|
|
|
504
|
-
Open [http://localhost:3000](http://localhost:3000).
|
|
517
|
+
Open [http://localhost:3000](http://localhost:3000).
|
|
505
518
|
Full guide: [`kubernetes.md`](kubernetes.md)
|
|
506
519
|
|
|
507
520
|
---
|
|
508
521
|
|
|
522
|
+
## Low-Overhead & Production Tuning (Advanced)
|
|
523
|
+
|
|
524
|
+
`fastapi-observer` integrates natively with the core OpenTelemetry Python SDK, meaning you can aggressively tune its resource usage purely via standard environment variables without altering your application code.
|
|
525
|
+
|
|
526
|
+
For high-throughput services (e.g. `10k+ RPS`), apply these exact variables to minimize the observer footprint:
|
|
527
|
+
|
|
528
|
+
### 1. Head-Based Sampling
|
|
529
|
+
|
|
530
|
+
Tracing 100% of requests is too expensive at scale. You should configure `fastapi-observer` to respect upstream trace flags, while only sampling a fraction of net-new requests:
|
|
531
|
+
|
|
532
|
+
```bash
|
|
533
|
+
# Keep the parent's sample decision if it exists, otherwise sample 5%
|
|
534
|
+
export OTEL_TRACES_SAMPLER="parentbased_traceidratio"
|
|
535
|
+
export OTEL_TRACES_SAMPLER_ARG="0.05"
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
### 2. Exclude Noisy URLs from the SDK
|
|
539
|
+
|
|
540
|
+
Do not waste cycles generating spans for health checks or static assets. `fastapi-observer` will auto-derive metrics exclusions, but you can explicitly drop them from tracing at the C-extension level:
|
|
541
|
+
|
|
542
|
+
```bash
|
|
543
|
+
export OTEL_PYTHON_FASTAPI_EXCLUDED_URLS="healthz,metrics,favicon.ico"
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
### 3. Cap Span Attributes
|
|
547
|
+
|
|
548
|
+
Prevent large, unmanageable spans from consuming excessive memory in the `BatchSpanProcessor`:
|
|
549
|
+
|
|
550
|
+
```bash
|
|
551
|
+
export OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT="128"
|
|
552
|
+
export OTEL_SPAN_EVENT_COUNT_LIMIT="128"
|
|
553
|
+
export OTEL_SPAN_LINK_COUNT_LIMIT="128"
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
### 4. Optimize Output Buffers
|
|
557
|
+
|
|
558
|
+
The default OpenTelemetry batch limits are too conservative for high-throughput ASGI microservices. Increase the max queue limits so spikes aren't dropped, but decrease the timeout so the process memory is flushed faster:
|
|
559
|
+
|
|
560
|
+
```bash
|
|
561
|
+
export OTEL_BSP_MAX_QUEUE_SIZE="10000"
|
|
562
|
+
export OTEL_BSP_MAX_EXPORT_BATCH_SIZE="5000"
|
|
563
|
+
export OTEL_BSP_SCHEDULE_DELAY="1000"
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
---
|
|
567
|
+
|
|
509
568
|
## Examples
|
|
510
569
|
|
|
511
570
|
The `examples/` directory contains runnable demos:
|
|
@@ -660,7 +719,36 @@ install_observability(app, settings, security_policy=SecurityPolicy(log_request_
|
|
|
660
719
|
app.add_middleware(CORSMiddleware, allow_origins=["*"])
|
|
661
720
|
```
|
|
662
721
|
|
|
663
|
-
### Multi-worker Gunicorn
|
|
722
|
+
### Multi-worker Gunicorn
|
|
723
|
+
|
|
724
|
+
> [!WARNING]
|
|
725
|
+
> `--preload-app` is dangerous if visibility is initialized at the module level.
|
|
726
|
+
>
|
|
727
|
+
> When `--preload-app` is used, the application is loaded into the master process *before* forking the worker processes. `fastapi-observer` uses a highly-performant background thread (`QueueListener`) for non-blocking logging, and OpenTelemetry similarly spawns background export threads.
|
|
728
|
+
>
|
|
729
|
+
> Threads **do not survive** a process fork. If you call `install_observability()` at the module level (e.g., right under `app = FastAPI()`), the background threads will be created in the master process, and all workers will silently drop logs because their logging threads never started.
|
|
730
|
+
>
|
|
731
|
+
> **How to fix:** Either remove `--preload-app`, OR initialize observability inside the FastAPI `lifespan` context manager so it starts safely after the fork inside each worker:
|
|
732
|
+
>
|
|
733
|
+
> ```python
|
|
734
|
+
> from contextlib import asynccontextmanager
|
|
735
|
+
> from fastapi import FastAPI
|
|
736
|
+
> from fastapiobserver import ObservabilitySettings, install_observability
|
|
737
|
+
>
|
|
738
|
+
> settings = ObservabilitySettings(service="api")
|
|
739
|
+
>
|
|
740
|
+
> @asynccontextmanager
|
|
741
|
+
> async def lifespan(app: FastAPI):
|
|
742
|
+
> install_observability(app, settings) # Safely initializes per-worker
|
|
743
|
+
> yield
|
|
744
|
+
> # fastapiobserver automatically registers shutdown hooks so no teardown needed here
|
|
745
|
+
>
|
|
746
|
+
> app = FastAPI(lifespan=lifespan)
|
|
747
|
+
> ```
|
|
748
|
+
|
|
749
|
+
#### Prometheus Multiprocess Mode
|
|
750
|
+
|
|
751
|
+
If you are using Prometheus with multiple Gunicorn workers, you must configure a shared metrics directory:
|
|
664
752
|
|
|
665
753
|
```bash
|
|
666
754
|
export PROMETHEUS_MULTIPROC_DIR=/tmp/prometheus-metrics
|
|
@@ -892,9 +980,10 @@ Reproducible benchmark harness and methodology:
|
|
|
892
980
|
|
|
893
981
|
- `0.1.x`: secure-by-default core
|
|
894
982
|
- `0.2.x`: OTel interoperability, security presets, allowlists
|
|
983
|
+
- `0.3.x`: package modularization, sink/metrics hardening, and performance reliability updates
|
|
895
984
|
- `1.0.0`: dynamic runtime controls and plugin stability
|
|
896
985
|
|
|
897
|
-
Current release version: `0.
|
|
986
|
+
Current release version: `0.4.0`
|
|
898
987
|
|
|
899
988
|
## Changelog Policy
|
|
900
989
|
|
|
@@ -949,4 +1038,4 @@ The pre-push hook runs:
|
|
|
949
1038
|
|
|
950
1039
|
## Roadmap Tracking
|
|
951
1040
|
|
|
952
|
-
See [NEXT_STEPS.md](NEXT_STEPS.md) for the active
|
|
1041
|
+
See [NEXT_STEPS.md](NEXT_STEPS.md) for the active roadmap and release checklist.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastapi-observer
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Zero-glue FastAPI observability with security presets and runtime controls
|
|
5
5
|
Author-email: Vitaee <opensource@vitaee.dev>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -65,6 +65,7 @@ Requires-Dist: pytest>=9.0.2; extra == "dev"
|
|
|
65
65
|
Requires-Dist: pytest-randomly>=3.16.0; extra == "dev"
|
|
66
66
|
Requires-Dist: ruff>=0.15.1; extra == "dev"
|
|
67
67
|
Requires-Dist: cyclonedx-bom>=7.2.1; extra == "dev"
|
|
68
|
+
Requires-Dist: uvicorn>=0.30.0; extra == "dev"
|
|
68
69
|
Dynamic: license-file
|
|
69
70
|
|
|
70
71
|
# fastapi-observer
|
|
@@ -391,6 +392,19 @@ Request arrives
|
|
|
391
392
|
-> context cleared
|
|
392
393
|
```
|
|
393
394
|
|
|
395
|
+
### Internal Package Layout (Contributor Map)
|
|
396
|
+
|
|
397
|
+
The project is now organized as focused subpackages instead of large monolithic modules:
|
|
398
|
+
|
|
399
|
+
- `fastapiobserver/logging/`: formatter, queueing, filters, setup lifecycle, sink circuit-breakers.
|
|
400
|
+
- `fastapiobserver/middleware/`: request logging orchestration, context, IP resolution, headers, body capture, metrics hooks.
|
|
401
|
+
- `fastapiobserver/sinks/`: sink protocol, registry/discovery, built-ins, factory wiring, Logtail + DLQ implementation.
|
|
402
|
+
- `fastapiobserver/metrics/`: backend contracts/registry/builder/endpoint, Prometheus integration subpackage.
|
|
403
|
+
- `fastapiobserver/security/`: policy/settings models, normalization helpers, redaction engine, trusted-proxy utilities.
|
|
404
|
+
- `fastapiobserver/otel/`: OTel settings/resource/tracing/logs/metrics/lifecycle helpers.
|
|
405
|
+
|
|
406
|
+
Public imports remain backward-compatible via package facades (`__init__.py` re-exports).
|
|
407
|
+
|
|
394
408
|
---
|
|
395
409
|
|
|
396
410
|
## Example JSON Log Event
|
|
@@ -570,11 +584,57 @@ kubectl -n observability rollout status deployment/traffic-generator
|
|
|
570
584
|
kubectl -n observability port-forward svc/grafana 3000:3000
|
|
571
585
|
```
|
|
572
586
|
|
|
573
|
-
Open [http://localhost:3000](http://localhost:3000).
|
|
587
|
+
Open [http://localhost:3000](http://localhost:3000).
|
|
574
588
|
Full guide: [`kubernetes.md`](kubernetes.md)
|
|
575
589
|
|
|
576
590
|
---
|
|
577
591
|
|
|
592
|
+
## Low-Overhead & Production Tuning (Advanced)
|
|
593
|
+
|
|
594
|
+
`fastapi-observer` integrates natively with the core OpenTelemetry Python SDK, meaning you can aggressively tune its resource usage purely via standard environment variables without altering your application code.
|
|
595
|
+
|
|
596
|
+
For high-throughput services (e.g. `10k+ RPS`), apply these exact variables to minimize the observer footprint:
|
|
597
|
+
|
|
598
|
+
### 1. Head-Based Sampling
|
|
599
|
+
|
|
600
|
+
Tracing 100% of requests is too expensive at scale. You should configure `fastapi-observer` to respect upstream trace flags, while only sampling a fraction of net-new requests:
|
|
601
|
+
|
|
602
|
+
```bash
|
|
603
|
+
# Keep the parent's sample decision if it exists, otherwise sample 5%
|
|
604
|
+
export OTEL_TRACES_SAMPLER="parentbased_traceidratio"
|
|
605
|
+
export OTEL_TRACES_SAMPLER_ARG="0.05"
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
### 2. Exclude Noisy URLs from the SDK
|
|
609
|
+
|
|
610
|
+
Do not waste cycles generating spans for health checks or static assets. `fastapi-observer` will auto-derive metrics exclusions, but you can explicitly drop them from tracing at the C-extension level:
|
|
611
|
+
|
|
612
|
+
```bash
|
|
613
|
+
export OTEL_PYTHON_FASTAPI_EXCLUDED_URLS="healthz,metrics,favicon.ico"
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
### 3. Cap Span Attributes
|
|
617
|
+
|
|
618
|
+
Prevent large, unmanageable spans from consuming excessive memory in the `BatchSpanProcessor`:
|
|
619
|
+
|
|
620
|
+
```bash
|
|
621
|
+
export OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT="128"
|
|
622
|
+
export OTEL_SPAN_EVENT_COUNT_LIMIT="128"
|
|
623
|
+
export OTEL_SPAN_LINK_COUNT_LIMIT="128"
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
### 4. Optimize Output Buffers
|
|
627
|
+
|
|
628
|
+
The default OpenTelemetry batch limits are too conservative for high-throughput ASGI microservices. Increase the max queue limits so spikes aren't dropped, but decrease the timeout so the process memory is flushed faster:
|
|
629
|
+
|
|
630
|
+
```bash
|
|
631
|
+
export OTEL_BSP_MAX_QUEUE_SIZE="10000"
|
|
632
|
+
export OTEL_BSP_MAX_EXPORT_BATCH_SIZE="5000"
|
|
633
|
+
export OTEL_BSP_SCHEDULE_DELAY="1000"
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
---
|
|
637
|
+
|
|
578
638
|
## Examples
|
|
579
639
|
|
|
580
640
|
The `examples/` directory contains runnable demos:
|
|
@@ -729,7 +789,36 @@ install_observability(app, settings, security_policy=SecurityPolicy(log_request_
|
|
|
729
789
|
app.add_middleware(CORSMiddleware, allow_origins=["*"])
|
|
730
790
|
```
|
|
731
791
|
|
|
732
|
-
### Multi-worker Gunicorn
|
|
792
|
+
### Multi-worker Gunicorn
|
|
793
|
+
|
|
794
|
+
> [!WARNING]
|
|
795
|
+
> `--preload-app` is dangerous if visibility is initialized at the module level.
|
|
796
|
+
>
|
|
797
|
+
> When `--preload-app` is used, the application is loaded into the master process *before* forking the worker processes. `fastapi-observer` uses a highly-performant background thread (`QueueListener`) for non-blocking logging, and OpenTelemetry similarly spawns background export threads.
|
|
798
|
+
>
|
|
799
|
+
> Threads **do not survive** a process fork. If you call `install_observability()` at the module level (e.g., right under `app = FastAPI()`), the background threads will be created in the master process, and all workers will silently drop logs because their logging threads never started.
|
|
800
|
+
>
|
|
801
|
+
> **How to fix:** Either remove `--preload-app`, OR initialize observability inside the FastAPI `lifespan` context manager so it starts safely after the fork inside each worker:
|
|
802
|
+
>
|
|
803
|
+
> ```python
|
|
804
|
+
> from contextlib import asynccontextmanager
|
|
805
|
+
> from fastapi import FastAPI
|
|
806
|
+
> from fastapiobserver import ObservabilitySettings, install_observability
|
|
807
|
+
>
|
|
808
|
+
> settings = ObservabilitySettings(service="api")
|
|
809
|
+
>
|
|
810
|
+
> @asynccontextmanager
|
|
811
|
+
> async def lifespan(app: FastAPI):
|
|
812
|
+
> install_observability(app, settings) # Safely initializes per-worker
|
|
813
|
+
> yield
|
|
814
|
+
> # fastapiobserver automatically registers shutdown hooks so no teardown needed here
|
|
815
|
+
>
|
|
816
|
+
> app = FastAPI(lifespan=lifespan)
|
|
817
|
+
> ```
|
|
818
|
+
|
|
819
|
+
#### Prometheus Multiprocess Mode
|
|
820
|
+
|
|
821
|
+
If you are using Prometheus with multiple Gunicorn workers, you must configure a shared metrics directory:
|
|
733
822
|
|
|
734
823
|
```bash
|
|
735
824
|
export PROMETHEUS_MULTIPROC_DIR=/tmp/prometheus-metrics
|
|
@@ -961,9 +1050,10 @@ Reproducible benchmark harness and methodology:
|
|
|
961
1050
|
|
|
962
1051
|
- `0.1.x`: secure-by-default core
|
|
963
1052
|
- `0.2.x`: OTel interoperability, security presets, allowlists
|
|
1053
|
+
- `0.3.x`: package modularization, sink/metrics hardening, and performance reliability updates
|
|
964
1054
|
- `1.0.0`: dynamic runtime controls and plugin stability
|
|
965
1055
|
|
|
966
|
-
Current release version: `0.
|
|
1056
|
+
Current release version: `0.4.0`
|
|
967
1057
|
|
|
968
1058
|
## Changelog Policy
|
|
969
1059
|
|
|
@@ -1018,4 +1108,4 @@ The pre-push hook runs:
|
|
|
1018
1108
|
|
|
1019
1109
|
## Roadmap Tracking
|
|
1020
1110
|
|
|
1021
|
-
See [NEXT_STEPS.md](NEXT_STEPS.md) for the active
|
|
1111
|
+
See [NEXT_STEPS.md](NEXT_STEPS.md) for the active roadmap and release checklist.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/fastapi_observer.egg-info/PKG-INFO
|
|
5
|
+
src/fastapi_observer.egg-info/SOURCES.txt
|
|
6
|
+
src/fastapi_observer.egg-info/dependency_links.txt
|
|
7
|
+
src/fastapi_observer.egg-info/requires.txt
|
|
8
|
+
src/fastapi_observer.egg-info/top_level.txt
|
|
9
|
+
src/fastapiobserver/__init__.py
|
|
10
|
+
src/fastapiobserver/_version.py
|
|
11
|
+
src/fastapiobserver/config.py
|
|
12
|
+
src/fastapiobserver/control_plane.py
|
|
13
|
+
src/fastapiobserver/fastapi.py
|
|
14
|
+
src/fastapiobserver/loguru.py
|
|
15
|
+
src/fastapiobserver/plugins.py
|
|
16
|
+
src/fastapiobserver/propagation.py
|
|
17
|
+
src/fastapiobserver/py.typed
|
|
18
|
+
src/fastapiobserver/request_context.py
|
|
19
|
+
src/fastapiobserver/utils.py
|
|
20
|
+
src/fastapiobserver/integrations/__init__.py
|
|
21
|
+
src/fastapiobserver/integrations/strawberry.py
|
|
22
|
+
src/fastapiobserver/logging/__init__.py
|
|
23
|
+
src/fastapiobserver/logging/circuit_breaker.py
|
|
24
|
+
src/fastapiobserver/logging/filters.py
|
|
25
|
+
src/fastapiobserver/logging/formatter.py
|
|
26
|
+
src/fastapiobserver/logging/queueing.py
|
|
27
|
+
src/fastapiobserver/logging/setup.py
|
|
28
|
+
src/fastapiobserver/logging/state.py
|
|
29
|
+
src/fastapiobserver/metrics/__init__.py
|
|
30
|
+
src/fastapiobserver/metrics/builder.py
|
|
31
|
+
src/fastapiobserver/metrics/contracts.py
|
|
32
|
+
src/fastapiobserver/metrics/endpoint.py
|
|
33
|
+
src/fastapiobserver/metrics/noop.py
|
|
34
|
+
src/fastapiobserver/metrics/pathing.py
|
|
35
|
+
src/fastapiobserver/metrics/registry.py
|
|
36
|
+
src/fastapiobserver/metrics/prometheus/__init__.py
|
|
37
|
+
src/fastapiobserver/metrics/prometheus/backend.py
|
|
38
|
+
src/fastapiobserver/metrics/prometheus/client.py
|
|
39
|
+
src/fastapiobserver/metrics/prometheus/collector.py
|
|
40
|
+
src/fastapiobserver/metrics/prometheus/exemplars.py
|
|
41
|
+
src/fastapiobserver/metrics/prometheus/multiprocess.py
|
|
42
|
+
src/fastapiobserver/middleware/__init__.py
|
|
43
|
+
src/fastapiobserver/middleware/body_capture.py
|
|
44
|
+
src/fastapiobserver/middleware/context.py
|
|
45
|
+
src/fastapiobserver/middleware/events.py
|
|
46
|
+
src/fastapiobserver/middleware/headers.py
|
|
47
|
+
src/fastapiobserver/middleware/ip.py
|
|
48
|
+
src/fastapiobserver/middleware/metrics.py
|
|
49
|
+
src/fastapiobserver/middleware/request_logging.py
|
|
50
|
+
src/fastapiobserver/middleware/span_errors.py
|
|
51
|
+
src/fastapiobserver/otel/__init__.py
|
|
52
|
+
src/fastapiobserver/otel/lifecycle.py
|
|
53
|
+
src/fastapiobserver/otel/logs.py
|
|
54
|
+
src/fastapiobserver/otel/metrics.py
|
|
55
|
+
src/fastapiobserver/otel/resource.py
|
|
56
|
+
src/fastapiobserver/otel/settings.py
|
|
57
|
+
src/fastapiobserver/otel/tracing.py
|
|
58
|
+
src/fastapiobserver/otel/types.py
|
|
59
|
+
src/fastapiobserver/security/__init__.py
|
|
60
|
+
src/fastapiobserver/security/normalize.py
|
|
61
|
+
src/fastapiobserver/security/policy.py
|
|
62
|
+
src/fastapiobserver/security/proxies.py
|
|
63
|
+
src/fastapiobserver/security/redaction.py
|
|
64
|
+
src/fastapiobserver/sinks/__init__.py
|
|
65
|
+
src/fastapiobserver/sinks/builtin.py
|
|
66
|
+
src/fastapiobserver/sinks/discovery.py
|
|
67
|
+
src/fastapiobserver/sinks/factory.py
|
|
68
|
+
src/fastapiobserver/sinks/protocol.py
|
|
69
|
+
src/fastapiobserver/sinks/registry.py
|
|
70
|
+
src/fastapiobserver/sinks/stats.py
|
|
71
|
+
src/fastapiobserver/sinks/logtail/__init__.py
|
|
72
|
+
src/fastapiobserver/sinks/logtail/dlq.py
|
|
73
|
+
src/fastapiobserver/sinks/logtail/handler.py
|
|
74
|
+
src/fastapiobserver/sinks/logtail/sink.py
|
|
75
|
+
tests/test_body_media_allowlist.py
|
|
76
|
+
tests/test_config_settings.py
|
|
77
|
+
tests/test_excluded_url_precedence.py
|
|
78
|
+
tests/test_fastapi_install.py
|
|
79
|
+
tests/test_graphql_integrations.py
|
|
80
|
+
tests/test_log_queue_controls.py
|
|
81
|
+
tests/test_logging_schema_contract.py
|
|
82
|
+
tests/test_logtail_dlq.py
|
|
83
|
+
tests/test_loguru_bridge.py
|
|
84
|
+
tests/test_metrics_contracts.py
|
|
85
|
+
tests/test_metrics_optional_dependency.py
|
|
86
|
+
tests/test_middleware.py
|
|
87
|
+
tests/test_negotiate_content_type.py
|
|
88
|
+
tests/test_otel_integration.py
|
|
89
|
+
tests/test_otel_lifecycle.py
|
|
90
|
+
tests/test_otel_log_correlation.py
|
|
91
|
+
tests/test_otel_logs_from_env.py
|
|
92
|
+
tests/test_otel_logs_pipeline.py
|
|
93
|
+
tests/test_otel_metrics_from_env.py
|
|
94
|
+
tests/test_otlp_export_integration.py
|
|
95
|
+
tests/test_plugin_isolation.py
|
|
96
|
+
tests/test_propagation.py
|
|
97
|
+
tests/test_redaction_presets.py
|
|
98
|
+
tests/test_route_template_cardinality.py
|
|
99
|
+
tests/test_runtime_control_auth.py
|
|
100
|
+
tests/test_security_redaction.py
|
|
101
|
+
tests/test_sink_circuit_breaker.py
|
|
102
|
+
tests/test_sinks.py
|
|
103
|
+
tests/test_trust_boundary.py
|
|
104
|
+
tests/test_utils_refactors.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.4.0"
|
|
@@ -72,7 +72,13 @@ def mount_control_plane(app: FastAPI, settings: RuntimeControlSettings) -> None:
|
|
|
72
72
|
def authorize(
|
|
73
73
|
authorization: Annotated[str | None, Header()] = None,
|
|
74
74
|
) -> None:
|
|
75
|
-
|
|
75
|
+
current_token = os.getenv(settings.token_env_var)
|
|
76
|
+
if not current_token:
|
|
77
|
+
raise HTTPException(
|
|
78
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
79
|
+
detail="Unauthorized",
|
|
80
|
+
)
|
|
81
|
+
expected = f"Bearer {current_token}"
|
|
76
82
|
if not authorization or not secrets.compare_digest(authorization, expected):
|
|
77
83
|
raise HTTPException(
|
|
78
84
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from .circuit_breaker import (
|
|
4
|
+
CircuitBreakerState,
|
|
5
|
+
SinkCircuitBreakerHandler,
|
|
6
|
+
SinkCircuitBreakerSnapshot,
|
|
7
|
+
get_sink_circuit_breaker_stats,
|
|
8
|
+
)
|
|
9
|
+
from .filters import PluginLogFilter, RequestIdFilter, TraceContextFilter
|
|
10
|
+
from .formatter import LOG_SCHEMA_VERSION, StructuredJsonFormatter
|
|
11
|
+
from .queueing import (
|
|
12
|
+
LogQueueStatsSnapshot,
|
|
13
|
+
LogQueueTelemetry,
|
|
14
|
+
OverflowPolicyQueueHandler,
|
|
15
|
+
get_log_queue_stats,
|
|
16
|
+
)
|
|
17
|
+
from .setup import get_managed_output_handlers, setup_logging, shutdown_logging
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"LOG_SCHEMA_VERSION",
|
|
21
|
+
"CircuitBreakerState",
|
|
22
|
+
"LogQueueStatsSnapshot",
|
|
23
|
+
"LogQueueTelemetry",
|
|
24
|
+
"OverflowPolicyQueueHandler",
|
|
25
|
+
"PluginLogFilter",
|
|
26
|
+
"RequestIdFilter",
|
|
27
|
+
"SinkCircuitBreakerHandler",
|
|
28
|
+
"SinkCircuitBreakerSnapshot",
|
|
29
|
+
"StructuredJsonFormatter",
|
|
30
|
+
"TraceContextFilter",
|
|
31
|
+
"get_log_queue_stats",
|
|
32
|
+
"get_managed_output_handlers",
|
|
33
|
+
"get_sink_circuit_breaker_stats",
|
|
34
|
+
"setup_logging",
|
|
35
|
+
"shutdown_logging",
|
|
36
|
+
]
|