obsforge 0.1.2__tar.gz → 0.1.3__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.
- {obsforge-0.1.2 → obsforge-0.1.3}/CHANGELOG.md +12 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/PKG-INFO +12 -4
- {obsforge-0.1.2 → obsforge-0.1.3}/README.md +11 -3
- {obsforge-0.1.2 → obsforge-0.1.3}/pyproject.toml +1 -1
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/config/settings.py +1 -1
- {obsforge-0.1.2 → obsforge-0.1.3}/.gitignore +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/LICENSE +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/__init__.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/api/__init__.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/api/context.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/api/decorators.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/api/events.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/api/logger.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/config/__init__.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/config/bootstrap.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/config/state.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/core/__init__.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/core/contracts.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/core/errors.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/core/models.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/core/taxonomy.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/encoding/__init__.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/encoding/json.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/encoding/serializers.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/__init__.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/db/__init__.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/db/aiomysql.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/db/asyncpg.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/db/django.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/db/engine.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/db/pool.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/db/psycopg.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/db/sql.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/db/sqlalchemy.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/db/state.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/db/transactions.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/exceptions/__init__.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/exceptions/classification.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/exceptions/dedupe.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/exceptions/engine.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/exceptions/sanitization.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/exceptions/state.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/http/__init__.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/http/aiohttp.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/http/classification.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/http/dependency.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/http/engine.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/http/httpx.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/http/requests.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/http/sanitization.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/instrumentation/http/state.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/integrations/__init__.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/integrations/asyncio.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/integrations/celery/__init__.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/integrations/celery/signals.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/integrations/django/__init__.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/integrations/django/middleware.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/integrations/django/settings.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/integrations/django/signals.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/integrations/drf/__init__.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/integrations/drf/exception_handler.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/integrations/fastapi/__init__.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/integrations/fastapi/dependencies.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/integrations/fastapi/exception_handlers.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/integrations/fastapi/middleware.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/integrations/kafka.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/integrations/logging_bridge.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/integrations/rabbitmq.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/integrations/workers.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/plugins/__init__.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/plugins/builtin.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/plugins/manager.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/plugins/registry.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/plugins/spec.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/propagation/__init__.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/propagation/baggage.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/propagation/correlation.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/propagation/distributed.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/propagation/state.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/propagation/tracecontext.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/py.typed +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/runtime/__init__.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/runtime/pii.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/runtime/pipeline.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/runtime/policies/__init__.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/runtime/policies/loki_policy.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/runtime/processors.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/runtime/redaction.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/runtime/sampling.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/telemetry/__init__.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/telemetry/mapping.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/telemetry/otel_logs.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/telemetry/otel_traces.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/testing/__init__.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/testing/capture.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/testing/fakes.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/transport/__init__.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/transport/sink.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/src/obsforge/transport/stdout.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/conftest.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/integration/db/test_sqlalchemy_sqlite.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/integration/http/test_fastapi_middleware.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/integration/http/test_http_clients.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/integration/otel/test_otel_export.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/integration/propagation/test_carriers.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/integration/propagation/test_context_isolation.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/integration/propagation/test_workers.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/integration/test_celery_correlation.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/integration/test_logging_bridge.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/regression/test_baggage_caps.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/regression/test_dedupe_eviction.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/regression/test_no_high_cardinality_labels.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/regression/test_pii_never_serialized.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/regression/test_pipeline_fail_open.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/regression/test_pipeline_sync_async_parity.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/test_architecture_smoke.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/test_benchmark_smoke.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/unit/test_default_engine_state.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/unit/test_exception_sanitization.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/unit/test_http_classification.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/unit/test_loki_policy.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/unit/test_payload_sanitizer.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/unit/test_pii_scrubber.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/unit/test_pool_tracker.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/unit/test_settings.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/unit/test_sql_normalizer.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/unit/test_telemetry_mapping.py +0 -0
- {obsforge-0.1.2 → obsforge-0.1.3}/tests/unit/test_transactions.py +0 -0
|
@@ -7,6 +7,18 @@ All notable changes to obsforge are documented here. Format loosely follows
|
|
|
7
7
|
|
|
8
8
|
_Nothing yet._
|
|
9
9
|
|
|
10
|
+
## [0.1.3] — 2026-06-06
|
|
11
|
+
|
|
12
|
+
Documentation-only release so the PyPI project page reflects the current docs. No
|
|
13
|
+
code or behavior changes from 0.1.2.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- Documented the **PII scrubbing scope** honestly in the README and SECURITY.md:
|
|
17
|
+
the exception stacktrace is now covered (since 0.1.2), but pattern scrubbing does
|
|
18
|
+
not catch IPv6, phone numbers, or generic cloud keys unless under a redacted key
|
|
19
|
+
name, and key-based redaction does not recurse into nested `extra` dicts.
|
|
20
|
+
- Reconciled stale `0.1.0` references across the docs to the published state.
|
|
21
|
+
|
|
10
22
|
## [0.1.2] — 2026-06-06
|
|
11
23
|
|
|
12
24
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: obsforge
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: Zero-infra drop-in structured logging & observability for Python (Grafana/Loki, Elastic, any stack)
|
|
5
5
|
Project-URL: Homepage, https://github.com/AnthonyGrullonA/OBSFORGE
|
|
6
6
|
Project-URL: Repository, https://github.com/AnthonyGrullonA/OBSFORGE
|
|
@@ -295,9 +295,17 @@ Full promtail/Alloy + OTLP reference: [docs/operational/loki_otel_setup.md](http
|
|
|
295
295
|
|
|
296
296
|
- **No cardinality footguns:** `trace_id`, `user_id`, `tenant_id`, `request_id`,
|
|
297
297
|
`correlation_id`, `session_id`, `event_id` can never be emitted as labels.
|
|
298
|
-
- **PII scrubbing:** emails, bearer/JWT tokens, card numbers, SSNs and
|
|
299
|
-
redacted from every string field — message, payload
|
|
300
|
-
|
|
298
|
+
- **PII scrubbing:** emails, bearer/JWT tokens, card numbers, SSNs and **IPv4**
|
|
299
|
+
addresses are pattern-redacted from every string field — message, payload
|
|
300
|
+
previews, headers, exception message **and stacktrace**, DB query text — and
|
|
301
|
+
configured `redact_keys` (`password`, `token`, …) are replaced wholesale.
|
|
302
|
+
|
|
303
|
+
**Scope (know the edges):** pattern scrubbing covers the shapes above; it does
|
|
304
|
+
**not** yet catch IPv6, phone numbers, or generic cloud keys (e.g. `AKIA…`)
|
|
305
|
+
unless they sit under a redacted key name. Key-based redaction applies to
|
|
306
|
+
top-level fields; secrets buried inside a nested dict passed as a single `extra`
|
|
307
|
+
value are flattened to a string, so only pattern scrubbing reaches them. Treat
|
|
308
|
+
redaction as defense-in-depth, not a guarantee — don't deliberately log secrets.
|
|
301
309
|
- **Fail-open:** any error inside the pipeline is logged-and-dropped, never raised
|
|
302
310
|
into your hot path.
|
|
303
311
|
- **Trusted propagation:** inbound identifiers are length- and control-char-validated;
|
|
@@ -235,9 +235,17 @@ Full promtail/Alloy + OTLP reference: [docs/operational/loki_otel_setup.md](http
|
|
|
235
235
|
|
|
236
236
|
- **No cardinality footguns:** `trace_id`, `user_id`, `tenant_id`, `request_id`,
|
|
237
237
|
`correlation_id`, `session_id`, `event_id` can never be emitted as labels.
|
|
238
|
-
- **PII scrubbing:** emails, bearer/JWT tokens, card numbers, SSNs and
|
|
239
|
-
redacted from every string field — message, payload
|
|
240
|
-
|
|
238
|
+
- **PII scrubbing:** emails, bearer/JWT tokens, card numbers, SSNs and **IPv4**
|
|
239
|
+
addresses are pattern-redacted from every string field — message, payload
|
|
240
|
+
previews, headers, exception message **and stacktrace**, DB query text — and
|
|
241
|
+
configured `redact_keys` (`password`, `token`, …) are replaced wholesale.
|
|
242
|
+
|
|
243
|
+
**Scope (know the edges):** pattern scrubbing covers the shapes above; it does
|
|
244
|
+
**not** yet catch IPv6, phone numbers, or generic cloud keys (e.g. `AKIA…`)
|
|
245
|
+
unless they sit under a redacted key name. Key-based redaction applies to
|
|
246
|
+
top-level fields; secrets buried inside a nested dict passed as a single `extra`
|
|
247
|
+
value are flattened to a string, so only pattern scrubbing reaches them. Treat
|
|
248
|
+
redaction as defense-in-depth, not a guarantee — don't deliberately log secrets.
|
|
241
249
|
- **Fail-open:** any error inside the pipeline is logged-and-dropped, never raised
|
|
242
250
|
into your hot path.
|
|
243
251
|
- **Trusted propagation:** inbound identifiers are length- and control-char-validated;
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "obsforge"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.3"
|
|
8
8
|
description = "Zero-infra drop-in structured logging & observability for Python (Grafana/Loki, Elastic, any stack)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -147,7 +147,7 @@ class ObsforgeSettings(BaseModel):
|
|
|
147
147
|
k8s_cluster_name: str | None = None
|
|
148
148
|
k8s_namespace_name: str | None = None
|
|
149
149
|
k8s_deployment_name: str | None = None
|
|
150
|
-
telemetry_sdk_version: str = "0.1.
|
|
150
|
+
telemetry_sdk_version: str = "0.1.3"
|
|
151
151
|
min_severity: Severity = Severity.INFO
|
|
152
152
|
redact_keys: set[str] = Field(
|
|
153
153
|
default_factory=lambda: {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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
|