- creating a client span for an outgoing HTTP request,
- annotating spans with events and attributes,
- recording exceptions explicitly, and
- using the built-in helper to capture exception type, message, and stack trace.
requests.get call will raise an exception. You can catch that exception and add it to the span as a plain event:
Using
span.record_exception(err) will include the exception type, message, and stack trace in the span. You can also set the span status to error with span.set_status(...) to make the error state explicit.- Prefer
span.record_exception(err)when you want structured exception data (type, message, stack trace) in the span. - Use
span.set_status(trace.Status(trace.StatusCode.ERROR, "..."))if you want the span to be explicitly marked as an error in UI/analytics. - You do not always need an explicit try/except: if an exception propagates out of a span and your instrumentation/exporter is configured to capture uncaught exceptions, the tracing system may automatically record the exception on that span.
- For richer context, include relevant attributes (HTTP method, URL, status code, and other request metadata) so backends can correlate exceptions with request details.
| Approach | Captures | Use when |
|---|---|---|
span.add_event("exception", attributes={...}) | Arbitrary attributes you add (e.g. {"error": "Connection refused"}) | You want custom, lightweight event data. |
span.record_exception(err) | Exception type, message, stack trace | You want structured exception data for debugging and stack traces. |
| Automatic capture by instrumentation | Depends on instrumentation/exporter configuration | You rely on automatic capture for uncaught exceptions and minimal code changes. |
- OpenTelemetry Python API: https://opentelemetry.io/docs/instrumentation/python/
- Jaeger tracing: https://www.jaegertracing.io/
