logbrew-fastapi 0.1.7__tar.gz → 0.1.9__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.
- {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/PKG-INFO +30 -4
- {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/README.md +26 -2
- {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/pyproject.toml +5 -2
- {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/__init__.py +11 -7
- {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi.egg-info/PKG-INFO +30 -4
- logbrew_fastapi-0.1.9/src/logbrew_fastapi.egg-info/requires.txt +5 -0
- {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/tests/test_fastapi_integration.py +10 -0
- logbrew_fastapi-0.1.7/src/logbrew_fastapi.egg-info/requires.txt +0 -2
- {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/setup.cfg +0 -0
- {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/examples/__init__.py +0 -0
- {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/examples/__main__.py +0 -0
- {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/examples/dependency_spans.py +0 -0
- {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/examples/outbound_http.py +0 -0
- {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/examples/readme_example.py +0 -0
- {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/examples/real_user_smoke.py +0 -0
- {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/py.typed +0 -0
- {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi.egg-info/SOURCES.txt +0 -0
- {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi.egg-info/dependency_links.txt +0 -0
- {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: logbrew-fastapi
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.9
|
|
4
4
|
Summary: FastAPI integration for capturing LogBrew request spans and exceptions.
|
|
5
5
|
Author: LogBrew
|
|
6
6
|
License-Expression: MIT
|
|
@@ -19,7 +19,9 @@ Classifier: Typing :: Typed
|
|
|
19
19
|
Requires-Python: >=3.10
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
Requires-Dist: fastapi>=0.111.1
|
|
22
|
-
Requires-Dist: logbrew-sdk<0.2.0,>=0.1.
|
|
22
|
+
Requires-Dist: logbrew-sdk<0.2.0,>=0.1.9
|
|
23
|
+
Provides-Extra: celery
|
|
24
|
+
Requires-Dist: logbrew-sdk[celery]<0.2.0,>=0.1.9; extra == "celery"
|
|
23
25
|
|
|
24
26
|
# logbrew-fastapi
|
|
25
27
|
|
|
@@ -65,7 +67,7 @@ def health() -> dict[str, bool]:
|
|
|
65
67
|
return {"ok": True}
|
|
66
68
|
```
|
|
67
69
|
|
|
68
|
-
`init_logbrew()` records successful requests as spans and unhandled handler exceptions as issues plus error spans. It owns a real `HttpTransport`, uses the core SDK's bounded background delivery, and performs a final exact flush after the app's own default or custom FastAPI lifespan teardown. Network delivery never blocks the request path.
|
|
70
|
+
`init_logbrew()` records successful requests as spans and unhandled handler exceptions as issues plus error spans. Exception issues include first-class exception type, `fastapi.middleware` mechanism, unhandled state, and up to 32 sanitized newest-first traceback frames. The frame projection contains basename and bounded code identity only; it omits raw traceback text, source code, local variables, and absolute paths. Exception messages keep the integration's existing `str(error)` behavior, so applications should avoid sensitive values in exception text. It owns a real `HttpTransport`, uses the core SDK's bounded background delivery, and performs a final exact flush after the app's own default or custom FastAPI lifespan teardown. Network delivery never blocks the request path.
|
|
69
71
|
|
|
70
72
|
The returned runtime exposes content-free delivery diagnostics:
|
|
71
73
|
|
|
@@ -186,7 +188,31 @@ def checkout(order_id: str) -> dict[str, object]:
|
|
|
186
188
|
|
|
187
189
|
Run `python -m logbrew_fastapi.examples dependency-spans` to see a local request span parenting SQLite, cache, and queue child spans from an installed package. LogBrew does not patch database drivers, cache clients, queue frameworks, or broker metadata globally, and the helpers avoid SQL values, cache keys/values, queue bodies, headers, baggage, and tracestate.
|
|
188
190
|
|
|
189
|
-
|
|
191
|
+
## Celery background jobs
|
|
192
|
+
|
|
193
|
+
Install the optional Celery path when a FastAPI service publishes or processes Celery jobs:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
python3 -m pip install "logbrew-fastapi[celery]"
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
The base FastAPI install stays Celery-free. The extra installs the compatible core Celery integration, which you attach only to the Celery app your service owns:
|
|
200
|
+
|
|
201
|
+
```python
|
|
202
|
+
from celery import Celery
|
|
203
|
+
from logbrew_sdk import instrument_celery_app_with_logbrew_spans
|
|
204
|
+
|
|
205
|
+
celery_app = Celery("checkout")
|
|
206
|
+
celery_telemetry = instrument_celery_app_with_logbrew_spans(
|
|
207
|
+
celery_app,
|
|
208
|
+
client=client,
|
|
209
|
+
metadata={"service": "checkout-worker"},
|
|
210
|
+
)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Producer and worker spans share W3C trace context. An unexpected final task failure emits one trace-correlated issue with task name and exception type only; retries and exception types declared through `task.throws` stay span-only. Task IDs, arguments, results, headers, exception messages, and stack traces are excluded. Uninstall direct instrumentation after tasks drain and before shutting down its client. Separate prefork workers need child-owned clients; follow the [core Celery lifecycle and encrypted persistence setup](https://github.com/LogBrewCo/sdk/tree/main/python/logbrew_py#automatic-celery-spans) instead of sharing the FastAPI process client across forks.
|
|
214
|
+
|
|
215
|
+
Request duration metrics are opt-in. Set `capture_request_metrics=True` to emit an explicit `http.server.duration` histogram for completed requests. Each generated metric carries the stable description `Duration of one completed server request.` so its purpose remains clear in investigations:
|
|
190
216
|
|
|
191
217
|
```python
|
|
192
218
|
logbrew = init_logbrew(
|
|
@@ -42,7 +42,7 @@ def health() -> dict[str, bool]:
|
|
|
42
42
|
return {"ok": True}
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
`init_logbrew()` records successful requests as spans and unhandled handler exceptions as issues plus error spans. It owns a real `HttpTransport`, uses the core SDK's bounded background delivery, and performs a final exact flush after the app's own default or custom FastAPI lifespan teardown. Network delivery never blocks the request path.
|
|
45
|
+
`init_logbrew()` records successful requests as spans and unhandled handler exceptions as issues plus error spans. Exception issues include first-class exception type, `fastapi.middleware` mechanism, unhandled state, and up to 32 sanitized newest-first traceback frames. The frame projection contains basename and bounded code identity only; it omits raw traceback text, source code, local variables, and absolute paths. Exception messages keep the integration's existing `str(error)` behavior, so applications should avoid sensitive values in exception text. It owns a real `HttpTransport`, uses the core SDK's bounded background delivery, and performs a final exact flush after the app's own default or custom FastAPI lifespan teardown. Network delivery never blocks the request path.
|
|
46
46
|
|
|
47
47
|
The returned runtime exposes content-free delivery diagnostics:
|
|
48
48
|
|
|
@@ -163,7 +163,31 @@ def checkout(order_id: str) -> dict[str, object]:
|
|
|
163
163
|
|
|
164
164
|
Run `python -m logbrew_fastapi.examples dependency-spans` to see a local request span parenting SQLite, cache, and queue child spans from an installed package. LogBrew does not patch database drivers, cache clients, queue frameworks, or broker metadata globally, and the helpers avoid SQL values, cache keys/values, queue bodies, headers, baggage, and tracestate.
|
|
165
165
|
|
|
166
|
-
|
|
166
|
+
## Celery background jobs
|
|
167
|
+
|
|
168
|
+
Install the optional Celery path when a FastAPI service publishes or processes Celery jobs:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
python3 -m pip install "logbrew-fastapi[celery]"
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
The base FastAPI install stays Celery-free. The extra installs the compatible core Celery integration, which you attach only to the Celery app your service owns:
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
from celery import Celery
|
|
178
|
+
from logbrew_sdk import instrument_celery_app_with_logbrew_spans
|
|
179
|
+
|
|
180
|
+
celery_app = Celery("checkout")
|
|
181
|
+
celery_telemetry = instrument_celery_app_with_logbrew_spans(
|
|
182
|
+
celery_app,
|
|
183
|
+
client=client,
|
|
184
|
+
metadata={"service": "checkout-worker"},
|
|
185
|
+
)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Producer and worker spans share W3C trace context. An unexpected final task failure emits one trace-correlated issue with task name and exception type only; retries and exception types declared through `task.throws` stay span-only. Task IDs, arguments, results, headers, exception messages, and stack traces are excluded. Uninstall direct instrumentation after tasks drain and before shutting down its client. Separate prefork workers need child-owned clients; follow the [core Celery lifecycle and encrypted persistence setup](https://github.com/LogBrewCo/sdk/tree/main/python/logbrew_py#automatic-celery-spans) instead of sharing the FastAPI process client across forks.
|
|
189
|
+
|
|
190
|
+
Request duration metrics are opt-in. Set `capture_request_metrics=True` to emit an explicit `http.server.duration` histogram for completed requests. Each generated metric carries the stable description `Duration of one completed server request.` so its purpose remains clear in investigations:
|
|
167
191
|
|
|
168
192
|
```python
|
|
169
193
|
logbrew = init_logbrew(
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "logbrew-fastapi"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.9"
|
|
8
8
|
description = "FastAPI integration for capturing LogBrew request spans and exceptions."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -27,9 +27,12 @@ classifiers = [
|
|
|
27
27
|
]
|
|
28
28
|
dependencies = [
|
|
29
29
|
"fastapi>=0.111.1",
|
|
30
|
-
"logbrew-sdk>=0.1.
|
|
30
|
+
"logbrew-sdk>=0.1.9,<0.2.0"
|
|
31
31
|
]
|
|
32
32
|
|
|
33
|
+
[project.optional-dependencies]
|
|
34
|
+
celery = ["logbrew-sdk[celery]>=0.1.9,<0.2.0"]
|
|
35
|
+
|
|
33
36
|
[project.urls]
|
|
34
37
|
Repository = "https://github.com/LogBrewCo/sdk"
|
|
35
38
|
|
|
@@ -24,6 +24,7 @@ from logbrew_sdk import (
|
|
|
24
24
|
Transport,
|
|
25
25
|
TransportError,
|
|
26
26
|
TransportResponse,
|
|
27
|
+
create_issue_attributes_from_exception,
|
|
27
28
|
create_logbrew_trace_context,
|
|
28
29
|
get_active_logbrew_trace,
|
|
29
30
|
parse_traceparent,
|
|
@@ -320,6 +321,7 @@ def create_request_metric_attributes(
|
|
|
320
321
|
duration_value = 0.0
|
|
321
322
|
return {
|
|
322
323
|
"name": metric_name,
|
|
324
|
+
"description": "Duration of one completed server request.",
|
|
323
325
|
"kind": "histogram",
|
|
324
326
|
"value": duration_value,
|
|
325
327
|
"unit": "ms",
|
|
@@ -416,19 +418,21 @@ def capture_exception(
|
|
|
416
418
|
|
|
417
419
|
issue_event_id = event_id or f"evt_fastapi_issue_{uuid.uuid4().hex}"
|
|
418
420
|
trace_context = trace or request_logbrew_trace(request) or get_active_logbrew_trace()
|
|
421
|
+
captured_at = timestamp or utc_timestamp()
|
|
419
422
|
client.issue(
|
|
420
423
|
issue_event_id,
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
"
|
|
425
|
-
"
|
|
426
|
-
|
|
424
|
+
captured_at,
|
|
425
|
+
create_issue_attributes_from_exception(
|
|
426
|
+
exc,
|
|
427
|
+
title=f"{request_name(request)} failed",
|
|
428
|
+
mechanism="fastapi.middleware",
|
|
429
|
+
handled=False,
|
|
430
|
+
metadata={
|
|
427
431
|
**request_metadata(request, status_code=500, service_name=service_name),
|
|
428
432
|
"exception_type": exc.__class__.__name__,
|
|
429
433
|
**trace_metadata(trace_context),
|
|
430
434
|
},
|
|
431
|
-
|
|
435
|
+
),
|
|
432
436
|
)
|
|
433
437
|
return issue_event_id
|
|
434
438
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: logbrew-fastapi
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.9
|
|
4
4
|
Summary: FastAPI integration for capturing LogBrew request spans and exceptions.
|
|
5
5
|
Author: LogBrew
|
|
6
6
|
License-Expression: MIT
|
|
@@ -19,7 +19,9 @@ Classifier: Typing :: Typed
|
|
|
19
19
|
Requires-Python: >=3.10
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
Requires-Dist: fastapi>=0.111.1
|
|
22
|
-
Requires-Dist: logbrew-sdk<0.2.0,>=0.1.
|
|
22
|
+
Requires-Dist: logbrew-sdk<0.2.0,>=0.1.9
|
|
23
|
+
Provides-Extra: celery
|
|
24
|
+
Requires-Dist: logbrew-sdk[celery]<0.2.0,>=0.1.9; extra == "celery"
|
|
23
25
|
|
|
24
26
|
# logbrew-fastapi
|
|
25
27
|
|
|
@@ -65,7 +67,7 @@ def health() -> dict[str, bool]:
|
|
|
65
67
|
return {"ok": True}
|
|
66
68
|
```
|
|
67
69
|
|
|
68
|
-
`init_logbrew()` records successful requests as spans and unhandled handler exceptions as issues plus error spans. It owns a real `HttpTransport`, uses the core SDK's bounded background delivery, and performs a final exact flush after the app's own default or custom FastAPI lifespan teardown. Network delivery never blocks the request path.
|
|
70
|
+
`init_logbrew()` records successful requests as spans and unhandled handler exceptions as issues plus error spans. Exception issues include first-class exception type, `fastapi.middleware` mechanism, unhandled state, and up to 32 sanitized newest-first traceback frames. The frame projection contains basename and bounded code identity only; it omits raw traceback text, source code, local variables, and absolute paths. Exception messages keep the integration's existing `str(error)` behavior, so applications should avoid sensitive values in exception text. It owns a real `HttpTransport`, uses the core SDK's bounded background delivery, and performs a final exact flush after the app's own default or custom FastAPI lifespan teardown. Network delivery never blocks the request path.
|
|
69
71
|
|
|
70
72
|
The returned runtime exposes content-free delivery diagnostics:
|
|
71
73
|
|
|
@@ -186,7 +188,31 @@ def checkout(order_id: str) -> dict[str, object]:
|
|
|
186
188
|
|
|
187
189
|
Run `python -m logbrew_fastapi.examples dependency-spans` to see a local request span parenting SQLite, cache, and queue child spans from an installed package. LogBrew does not patch database drivers, cache clients, queue frameworks, or broker metadata globally, and the helpers avoid SQL values, cache keys/values, queue bodies, headers, baggage, and tracestate.
|
|
188
190
|
|
|
189
|
-
|
|
191
|
+
## Celery background jobs
|
|
192
|
+
|
|
193
|
+
Install the optional Celery path when a FastAPI service publishes or processes Celery jobs:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
python3 -m pip install "logbrew-fastapi[celery]"
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
The base FastAPI install stays Celery-free. The extra installs the compatible core Celery integration, which you attach only to the Celery app your service owns:
|
|
200
|
+
|
|
201
|
+
```python
|
|
202
|
+
from celery import Celery
|
|
203
|
+
from logbrew_sdk import instrument_celery_app_with_logbrew_spans
|
|
204
|
+
|
|
205
|
+
celery_app = Celery("checkout")
|
|
206
|
+
celery_telemetry = instrument_celery_app_with_logbrew_spans(
|
|
207
|
+
celery_app,
|
|
208
|
+
client=client,
|
|
209
|
+
metadata={"service": "checkout-worker"},
|
|
210
|
+
)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Producer and worker spans share W3C trace context. An unexpected final task failure emits one trace-correlated issue with task name and exception type only; retries and exception types declared through `task.throws` stay span-only. Task IDs, arguments, results, headers, exception messages, and stack traces are excluded. Uninstall direct instrumentation after tasks drain and before shutting down its client. Separate prefork workers need child-owned clients; follow the [core Celery lifecycle and encrypted persistence setup](https://github.com/LogBrewCo/sdk/tree/main/python/logbrew_py#automatic-celery-spans) instead of sharing the FastAPI process client across forks.
|
|
214
|
+
|
|
215
|
+
Request duration metrics are opt-in. Set `capture_request_metrics=True` to emit an explicit `http.server.duration` histogram for completed requests. Each generated metric carries the stable description `Duration of one completed server request.` so its purpose remains clear in investigations:
|
|
190
216
|
|
|
191
217
|
```python
|
|
192
218
|
logbrew = init_logbrew(
|
|
@@ -234,6 +234,7 @@ class FastAPIIntegrationTests(unittest.TestCase):
|
|
|
234
234
|
self.assertEqual([event["type"] for event in payload["events"]], ["metric"])
|
|
235
235
|
metric = payload["events"][0]["attributes"]
|
|
236
236
|
self.assertEqual(metric["name"], "http.server.duration")
|
|
237
|
+
self.assertEqual(metric["description"], "Duration of one completed server request.")
|
|
237
238
|
self.assertEqual(metric["kind"], "histogram")
|
|
238
239
|
self.assertGreaterEqual(metric["value"], 0)
|
|
239
240
|
self.assertEqual(metric["unit"], "ms")
|
|
@@ -379,6 +380,15 @@ class FastAPIIntegrationTests(unittest.TestCase):
|
|
|
379
380
|
span = payload["events"][1]["attributes"]
|
|
380
381
|
self.assertEqual(issue["title"], "GET /boom failed")
|
|
381
382
|
self.assertEqual(issue["message"], "broken handler")
|
|
383
|
+
self.assertEqual(
|
|
384
|
+
issue["exception"],
|
|
385
|
+
{
|
|
386
|
+
"type": "RuntimeError",
|
|
387
|
+
"mechanism": {"type": "fastapi.middleware", "handled": False},
|
|
388
|
+
},
|
|
389
|
+
)
|
|
390
|
+
self.assertEqual(issue["stackFrames"][0]["filename"], "test_fastapi_integration.py")
|
|
391
|
+
self.assertEqual(issue["stackFrames"][0]["function"], "boom")
|
|
382
392
|
self.assertEqual(issue["metadata"]["exception_type"], "RuntimeError")
|
|
383
393
|
self.assertEqual(span["status"], "error")
|
|
384
394
|
self.assertEqual(span["metadata"]["status_code"], 500)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/examples/dependency_spans.py
RENAMED
|
File without changes
|
{logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/examples/outbound_http.py
RENAMED
|
File without changes
|
{logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/examples/readme_example.py
RENAMED
|
File without changes
|
{logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/examples/real_user_smoke.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|