logbrew-fastapi 0.1.8__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.8 → logbrew_fastapi-0.1.9}/PKG-INFO +5 -5
  2. {logbrew_fastapi-0.1.8 → logbrew_fastapi-0.1.9}/README.md +2 -2
  3. {logbrew_fastapi-0.1.8 → logbrew_fastapi-0.1.9}/pyproject.toml +3 -3
  4. {logbrew_fastapi-0.1.8 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/__init__.py +11 -7
  5. {logbrew_fastapi-0.1.8 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi.egg-info/PKG-INFO +5 -5
  6. logbrew_fastapi-0.1.9/src/logbrew_fastapi.egg-info/requires.txt +5 -0
  7. {logbrew_fastapi-0.1.8 → logbrew_fastapi-0.1.9}/tests/test_fastapi_integration.py +10 -0
  8. logbrew_fastapi-0.1.8/src/logbrew_fastapi.egg-info/requires.txt +0 -5
  9. {logbrew_fastapi-0.1.8 → logbrew_fastapi-0.1.9}/setup.cfg +0 -0
  10. {logbrew_fastapi-0.1.8 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/examples/__init__.py +0 -0
  11. {logbrew_fastapi-0.1.8 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/examples/__main__.py +0 -0
  12. {logbrew_fastapi-0.1.8 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/examples/dependency_spans.py +0 -0
  13. {logbrew_fastapi-0.1.8 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/examples/outbound_http.py +0 -0
  14. {logbrew_fastapi-0.1.8 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/examples/readme_example.py +0 -0
  15. {logbrew_fastapi-0.1.8 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/examples/real_user_smoke.py +0 -0
  16. {logbrew_fastapi-0.1.8 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi/py.typed +0 -0
  17. {logbrew_fastapi-0.1.8 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi.egg-info/SOURCES.txt +0 -0
  18. {logbrew_fastapi-0.1.8 → logbrew_fastapi-0.1.9}/src/logbrew_fastapi.egg-info/dependency_links.txt +0 -0
  19. {logbrew_fastapi-0.1.8 → 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.8
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,9 +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.7
22
+ Requires-Dist: logbrew-sdk<0.2.0,>=0.1.9
23
23
  Provides-Extra: celery
24
- Requires-Dist: logbrew-sdk[celery]<0.2.0,>=0.1.7; extra == "celery"
24
+ Requires-Dist: logbrew-sdk[celery]<0.2.0,>=0.1.9; extra == "celery"
25
25
 
26
26
  # logbrew-fastapi
27
27
 
@@ -67,7 +67,7 @@ def health() -> dict[str, bool]:
67
67
  return {"ok": True}
68
68
  ```
69
69
 
70
- `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.
71
71
 
72
72
  The returned runtime exposes content-free delivery diagnostics:
73
73
 
@@ -212,7 +212,7 @@ celery_telemetry = instrument_celery_app_with_logbrew_spans(
212
212
 
213
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
214
 
215
- Request duration metrics are opt-in. Set `capture_request_metrics=True` to emit an explicit `http.server.duration` histogram for completed requests:
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:
216
216
 
217
217
  ```python
218
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
 
@@ -187,7 +187,7 @@ celery_telemetry = instrument_celery_app_with_logbrew_spans(
187
187
 
188
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
189
 
190
- Request duration metrics are opt-in. Set `capture_request_metrics=True` to emit an explicit `http.server.duration` histogram for completed requests:
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:
191
191
 
192
192
  ```python
193
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.8"
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,11 +27,11 @@ classifiers = [
27
27
  ]
28
28
  dependencies = [
29
29
  "fastapi>=0.111.1",
30
- "logbrew-sdk>=0.1.7,<0.2.0"
30
+ "logbrew-sdk>=0.1.9,<0.2.0"
31
31
  ]
32
32
 
33
33
  [project.optional-dependencies]
34
- celery = ["logbrew-sdk[celery]>=0.1.7,<0.2.0"]
34
+ celery = ["logbrew-sdk[celery]>=0.1.9,<0.2.0"]
35
35
 
36
36
  [project.urls]
37
37
  Repository = "https://github.com/LogBrewCo/sdk"
@@ -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.8
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,9 +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.7
22
+ Requires-Dist: logbrew-sdk<0.2.0,>=0.1.9
23
23
  Provides-Extra: celery
24
- Requires-Dist: logbrew-sdk[celery]<0.2.0,>=0.1.7; extra == "celery"
24
+ Requires-Dist: logbrew-sdk[celery]<0.2.0,>=0.1.9; extra == "celery"
25
25
 
26
26
  # logbrew-fastapi
27
27
 
@@ -67,7 +67,7 @@ def health() -> dict[str, bool]:
67
67
  return {"ok": True}
68
68
  ```
69
69
 
70
- `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.
71
71
 
72
72
  The returned runtime exposes content-free delivery diagnostics:
73
73
 
@@ -212,7 +212,7 @@ celery_telemetry = instrument_celery_app_with_logbrew_spans(
212
212
 
213
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
214
 
215
- Request duration metrics are opt-in. Set `capture_request_metrics=True` to emit an explicit `http.server.duration` histogram for completed requests:
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:
216
216
 
217
217
  ```python
218
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,5 +0,0 @@
1
- fastapi>=0.111.1
2
- logbrew-sdk<0.2.0,>=0.1.7
3
-
4
- [celery]
5
- logbrew-sdk[celery]<0.2.0,>=0.1.7