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.
Files changed (19) hide show
  1. {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/PKG-INFO +30 -4
  2. {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/README.md +26 -2
  3. {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/pyproject.toml +5 -2
  4. {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/__init__.py +11 -7
  5. {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi.egg-info/PKG-INFO +30 -4
  6. logbrew_fastapi-0.1.9/src/logbrew_fastapi.egg-info/requires.txt +5 -0
  7. {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/tests/test_fastapi_integration.py +10 -0
  8. logbrew_fastapi-0.1.7/src/logbrew_fastapi.egg-info/requires.txt +0 -2
  9. {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/setup.cfg +0 -0
  10. {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/examples/__init__.py +0 -0
  11. {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/examples/__main__.py +0 -0
  12. {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/examples/dependency_spans.py +0 -0
  13. {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/examples/outbound_http.py +0 -0
  14. {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/examples/readme_example.py +0 -0
  15. {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/examples/real_user_smoke.py +0 -0
  16. {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/py.typed +0 -0
  17. {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi.egg-info/SOURCES.txt +0 -0
  18. {logbrew_fastapi-0.1.7 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi.egg-info/dependency_links.txt +0 -0
  19. {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.7
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.6
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
- Request duration metrics are opt-in. Set `capture_request_metrics=True` to emit an explicit `http.server.duration` histogram for completed requests:
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
- Request duration metrics are opt-in. Set `capture_request_metrics=True` to emit an explicit `http.server.duration` histogram for completed requests:
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"
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.6,<0.2.0"
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
- timestamp or utc_timestamp(),
422
- {
423
- "title": f"{request_name(request)} failed",
424
- "level": "error",
425
- "message": str(exc) or exc.__class__.__name__,
426
- "metadata": {
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.7
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.6
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
- Request duration metrics are opt-in. Set `capture_request_metrics=True` to emit an explicit `http.server.duration` histogram for completed requests:
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(
@@ -0,0 +1,5 @@
1
+ fastapi>=0.111.1
2
+ logbrew-sdk<0.2.0,>=0.1.9
3
+
4
+ [celery]
5
+ logbrew-sdk[celery]<0.2.0,>=0.1.9
@@ -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)
@@ -1,2 +0,0 @@
1
- fastapi>=0.111.1
2
- logbrew-sdk<0.2.0,>=0.1.6