docs(python): Update stream mode in main tracing files (tracing part 1/3)#18531
docs(python): Update stream mode in main tracing files (tracing part 1/3)#18531inventarSarah wants to merge 4 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
09d3da9 to
1125f9f
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 01ddcd6. Configure here.
| def before_send_span(span, hint): | ||
| # Runs once per span, as it's flushed. | ||
| # Only attributes set at span-creation time are available here. | ||
| span["attributes"].update({ |
There was a problem hiding this comment.
Bug: The before_send_span example accesses span["attributes"] without checking if the key exists, which could cause a KeyError at runtime.
Severity: MEDIUM
Suggested Fix
Update the code example to be more defensive. Before accessing span["attributes"], check if the key exists. If it does not, initialize it as an empty dictionary. For example: if "attributes" not in span: span["attributes"] = {}.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: platform-includes/tracing/span-metrics/add-all-spans/python.mdx#L45
Potential issue: The Python code example for the `before_send_span` callback directly
accesses `span["attributes"]` to update it. However, the span protocol specifies that
the `attributes` field is optional. If a span is processed that does not have an
`attributes` key, this code will raise a `KeyError`, crashing the callback. The example
code does not defensively check for the existence of the `attributes` key before
attempting to access it.
There was a problem hiding this comment.
@alexander-alderman-webb @ericapisani
is attributes always present on the span object here or can it be missing? This also affects one example on the New Spans page
| root_function() | ||
| ``` | ||
|
|
||
| ```python {tabTitle:Stream Mode} | ||
| import sentry_sdk | ||
|
|
||
| @sentry_sdk.traces.trace(name="Paul", attributes={"sentry.op": "my_op", "x": True}) |
There was a problem hiding this comment.
Bug: The Python code examples for custom instrumentation have incorrect leading spaces, which will cause an IndentationError when copied and run.
Severity: MEDIUM
Suggested Fix
Remove the extra leading spaces from the lines within the Python code blocks in the index.mdx file. Ensure that the indentation level is correct for all lines of code in both the 'Transaction Mode' and 'Stream Mode' examples.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location:
docs/platforms/python/tracing/instrumentation/custom-instrumentation/index.mdx#L337-L343
Potential issue: The Python code examples for custom instrumentation using the
`@sentry_sdk.trace` decorator have incorrect indentation. In the 'Transaction Mode'
example, most lines have an extra leading space. In the 'Stream Mode' example, lines
after the `import` statement also have an extra leading space. This will cause a Python
`IndentationError: unexpected indent` for users who copy and paste the code, preventing
them from running the examples successfully.
sentrivana
left a comment
There was a problem hiding this comment.
Approving to not block, but please see comments.
| with sentry_sdk.traces.start_span( | ||
| name="Eat Pizza", | ||
| attributes={"sentry.op": "task"}, | ||
| # remove the parent span to create service span |
There was a problem hiding this comment.
| # remove the parent span to create service span | |
| # set parent span to None to create service span |
| <Alert> | ||
|
|
||
| Note that `sentry_sdk.start_transaction()` is meant be used as a context manager. This ensures that the transaction will be properly set as active and any spans created within will be attached to it. | ||
| Note that `sentry_sdk.start_transaction()` (transaction mode) and `sentry_sdk.traces.start_span()` (stream mode) are meant be used as context managers. This ensures that the transaction/service span will be properly set as active and any spans created within will be attached to it. |
There was a problem hiding this comment.
| Note that `sentry_sdk.start_transaction()` (transaction mode) and `sentry_sdk.traces.start_span()` (stream mode) are meant be used as context managers. This ensures that the transaction/service span will be properly set as active and any spans created within will be attached to it. | |
| Note that `sentry_sdk.start_transaction()` (transaction mode) is meant be used as a context manager. This ensures that the transaction/service span will be properly set as active and any spans created within will be attached to it. | |
| In stream mode, `sentry_sdk.traces.start_span()` can, but doesn't have to be, used as a context manager. If you don't use it as a context manager, make sure to call `span.end()` to finish the span. |
| <Alert level="warning" title="Static & class methods"> | ||
|
|
||
| When tracing a static or class method, you **must** add the `@sentry_sdk.trace` decorator **after** the `@staticmethod` or `@classmethod` decorator (i.e., **closer** to the function definition). Otherwise, your function will break! | ||
| When tracing a static or class method, you **must** add the `@sentry_sdk.trace` decorator **after** the `@staticmethod` or `@classmethod` decorator (i.e., **closer** to the function definition). Otherwise, your function will break! This applies in both transaction mode and stream mode. |
There was a problem hiding this comment.
| When tracing a static or class method, you **must** add the `@sentry_sdk.trace` decorator **after** the `@staticmethod` or `@classmethod` decorator (i.e., **closer** to the function definition). Otherwise, your function will break! This applies in both transaction mode and stream mode. | |
| When tracing a static or class method, you **must** add the `@sentry_sdk.trace` (transaction mode)/`@sentry.sdk.traces.trace` (stream mode) decorator **after** the `@staticmethod` or `@classmethod` decorator (i.e., **closer** to the function definition). Otherwise, your function will break! This applies in both transaction mode and stream mode. |
| while pizza.slices > 0: | ||
| span = sentry_sdk.traces.start_span(name="Eat Slice") | ||
| eat_slice(pizza.slices.pop()) | ||
| span.finish() |
There was a problem hiding this comment.
finish will work too, but it's deprecated.
| span.finish() | |
| span.end() |
| child_span.finish() | ||
|
|
||
| parent_span.finish() |
There was a problem hiding this comment.
| child_span.finish() | |
| parent_span.finish() | |
| child_span.end() | |
| parent_span.end() |
|
|
||
| The parameters of `start_span()` and `start_child()` are the same. See the [API reference](https://getsentry.github.io/sentry-python/api.html#sentry_sdk.api.start_span) for more details. | ||
| In transaction mode, the parameters of `start_span()` and `start_child()` are the same. See the [API reference](https://getsentry.github.io/sentry-python/api.html#sentry_sdk.api.start_span) for more details. | ||
| In stream mode, however, there's no separate `start_child()` method. Instead, pass the parent span explicitly via `parent_span` when starting the child (as shown in the example above). |
There was a problem hiding this comment.
| In stream mode, however, there's no separate `start_child()` method. Instead, pass the parent span explicitly via `parent_span` when starting the child (as shown in the example above). | |
| In stream mode, however, there's no separate `start_child()` method. Instead, the span will become the child of the currently active span. Alternatively, you can pass the parent span explicitly via `parent_span` when starting the child (as shown in the example above). |
| | `name` | `string` | The name of the span. | | ||
| | `attributes` | `dict` | Structured metadata for the span, including `sentry.op` for the operation. | | ||
| | `start_timestamp` | `datetime/float` | The start time of the span. | | ||
| | `parent_span` | `Span/None` | The parent to attach to. Pass None to force a service span. | |
There was a problem hiding this comment.
| | `parent_span` | `Span/None` | The parent to attach to. Pass None to force a service span. | | |
| | `parent_span` | `StreamedSpan/None` | The parent to attach to. Pass None to force a service span. | |
|
|
||
| <Alert>Service spans are only available in stream mode.</Alert> | ||
|
|
||
| In stream mode, a service span (the equivalent of a transaction) is just a span started with no parent. Pass `parent_span=None` to force this, even if a span is currently active: |
There was a problem hiding this comment.
| In stream mode, a service span (the equivalent of a transaction) is just a span started with no parent. Pass `parent_span=None` to force this, even if a span is currently active: | |
| In stream mode, a service span (the equivalent of a transaction) is just a span started with no parent in the current application. Pass `parent_span=None` to force this, even if a span is currently active: |
Not sure if this is worth adding though. Might make things more confusing. But the service span might have an external parent from another service.
| - Transaction mode: `before_send_transaction` runs after the entire transaction finishes and has access to all data set during the span's lifetime. | ||
| - Stream mode: `before_send_span` (set under `_experiments`) can only work with attributes set at span start time. Attributes added later during the span's lifetime are **not available**. |
There was a problem hiding this comment.
This is incorrect -- before_send_span, unlike ignore_spans, is called on the span before it's sent, with all attributes on it.
Since there's no distinction between tracing and stream mode, maybe we can remove this list altogether?
| - Transaction mode: `before_send_transaction` runs after the entire transaction finishes and has access to all data set during the span's lifetime. | |
| - Stream mode: `before_send_span` (set under `_experiments`) can only work with attributes set at span start time. Attributes added later during the span's lifetime are **not available**. |
|
|
||
| def before_send_span(span, hint): | ||
| # Runs once per span, as it's flushed. | ||
| # Only attributes set at span-creation time are available here. |
There was a problem hiding this comment.
| # Only attributes set at span-creation time are available here. |

DESCRIBE YOUR PR
This PR updates pages under Tracing with information about the new stream mode and the new Span APIs.
Part 1 out of 3
(result of splitting up PR #18511 into smaller parts)
Important
Broken links: I added links to the New Spans guide on these pages, but since this guide does not exist in this branch, we get a linting error.
Should only be merged after #18456
IS YOUR CHANGE URGENT?
Help us prioritize incoming PRs by letting us know when the change needs to go live.
SLA
Thanks in advance for your help!
PRE-MERGE CHECKLIST
Make sure you've checked the following before merging your changes:
LEGAL BOILERPLATE
Look, I get it. The entity doing business as "Sentry" was incorporated in the State of Delaware in 2015 as Functional Software, Inc. and is gonna need some rights from me in order to utilize my contributions in this here PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Sentry can use, modify, copy, and redistribute my contributions, under Sentry's choice of terms.
EXTRA RESOURCES