Skip to content

Commit cc2c50f

Browse files
antonpirkersentrivanaszokeasaurusrex
authored
[Python] Overhaul "Setup tracing" > "Custom instrumentation" (#11341)
- Add documentation for manual span creation (without context manager) - Clean up code snippets - Made all callout boxes the same color, to make page more calm. --------- Co-authored-by: Ivana Kellyer <[email protected]> Co-authored-by: Daniel Szoke <[email protected]>
1 parent 5c9cf4a commit cc2c50f

File tree

1 file changed

+49
-23
lines changed
  • docs/platforms/python/tracing/instrumentation/custom-instrumentation

1 file changed

+49
-23
lines changed

docs/platforms/python/tracing/instrumentation/custom-instrumentation/index.mdx

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ The Sentry SDK for Python does a very good job of auto instrumenting your applic
99

1010
Adding transactions will allow you to instrument and capture certain regions of your code.
1111

12-
<Note>
12+
<Alert level="info">
1313

1414
If you're using one of Sentry's SDK integrations, transactions will be created for you automatically.
1515

16-
</Note>
16+
</Alert>
1717

1818
The following example creates a transaction for an expensive operation (in this case, `eat_pizza`), and then sends the result to Sentry:
1919

@@ -35,8 +35,9 @@ The [API reference](https://getsentry.github.io/sentry-python/api.html#sentry_sd
3535

3636
If you want to have more fine-grained performance monitoring, you can add child spans to your transaction, which can be done by either:
3737

38-
- Using a context manager or
39-
- Using a decorator, (this works on sync and `async` functions)
38+
- Using a context manager
39+
- Using a decorator (this works on sync and async functions)
40+
- Manually starting and finishing a span
4041

4142
Calling a `sentry_sdk.start_span()` will find the current active transaction and attach the span to it.
4243

@@ -53,7 +54,6 @@ def eat_pizza(pizza):
5354
while pizza.slices > 0:
5455
with sentry_sdk.start_span(description="Eat Slice"):
5556
eat_slice(pizza.slices.pop())
56-
5757
```
5858

5959
### Using a Decorator
@@ -69,15 +69,32 @@ def eat_pizza(pizza):
6969
with sentry_sdk.start_transaction(op="task", name="Eat Pizza"):
7070
while pizza.slices > 0:
7171
eat_slice(pizza.slices.pop())
72-
7372
```
7473

75-
<Alert title="Static & Class Methods" level="warning">
74+
<Alert title="Static & Class Methods" level="info">
7675

7776
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!
7877

7978
</Alert>
8079

80+
### Manually Starting and Finishing a Span
81+
82+
```python
83+
import sentry_sdk
84+
85+
def eat_slice(slice):
86+
...
87+
88+
def eat_pizza(pizza):
89+
with sentry_sdk.start_transaction(op="task", name="Eat Pizza"):
90+
while pizza.slices > 0:
91+
span = sentry_sdk.start_span(description="Eat Slice")
92+
eat_slice(pizza.slices.pop())
93+
span.finish()
94+
```
95+
96+
When you create your span manually, make sure to call `span.finish()` after the block of code you want to wrap in a span to finish the span. If you do not finish the span it will not be sent to Sentry.
97+
8198
## Nested Spans
8299

83100
Spans can be nested to form a span tree. If you'd like to learn more, read our [distributed tracing](/product/sentry-basics/tracing/distributed-tracing/) documentation.
@@ -90,16 +107,10 @@ import sentry_sdk
90107
def chew():
91108
...
92109

93-
def swallow():
94-
...
95-
96110
def eat_slice(slice):
97111
with sentry_sdk.start_span(description="Eat Slice"):
98112
with sentry_sdk.start_span(description="Chew"):
99113
chew()
100-
with sentry_sdk.start_span(description="Swallow"):
101-
swallow()
102-
103114
```
104115

105116
### Using a Decorator
@@ -112,15 +123,32 @@ def chew():
112123
...
113124

114125
@sentry_sdk.trace
115-
def swallow():
126+
def eat_slice(slice):
127+
chew()
128+
```
129+
130+
### Manually
131+
132+
```python
133+
import sentry_sdk
134+
135+
def chew():
116136
...
117137

118-
@sentry_sdk.trace
119138
def eat_slice(slice):
139+
parent_span = sentry_sdk.start_span(description="Eat Slice")
140+
141+
child_span = parent_span.start_child(description="Chew")
120142
chew()
121-
swallow()
143+
child_span.finish()
144+
145+
parent_span.finish()
122146
```
123147

148+
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.
149+
150+
When you create your span manually, make sure to call `span.finish()` after the block of code you want to wrap in a span to finish the span. If you do not finish the span it will not be sent to Sentry.
151+
124152
## Define Span Creation in a Central Place
125153

126154
To avoid having custom performance instrumentation code scattered all over your code base, pass a parameter <PlatformIdentifier name="functions-to-trace" /> to your `sentry_sdk.init()` call.
@@ -145,21 +173,21 @@ sentry_sdk.init(
145173

146174
Now, whenever a function specified in `functions_to_trace` will be executed, a span will be created and attached as a child to the currently running span.
147175

148-
<Alert level="warning" title="Important">
176+
<Alert title="Important" level="info">
149177

150178
To enable performance monitoring for the functions specified in `functions_to_trace`, the SDK needs to load the function modules. Be aware, there may be code being executed in modules during module loading. To avoid this, use the method described above to trace your functions.
151179

152180
</Alert>
153181

154182
## Accessing the Current Transaction
155183

156-
To change data in an already ongoing transaction, use `Hub.current.scope.transaction`. This property will return a transaction if there's one running, otherwise it will return `None`.
184+
The `sentry_sdk.get_current_scope().transaction` property returns the active transaction or `None` if no transaction is active. You can use this property to modify data on the transaction.
157185

158186
```python
159187
import sentry_sdk
160188

161189
def eat_pizza(pizza):
162-
transaction = sentry_sdk.Hub.current.scope.transaction
190+
transaction = sentry_sdk.get_current_scope().transaction
163191

164192
if transaction is not None:
165193
transaction.set_tag("num_of_slices", len(pizza.slices))
@@ -170,7 +198,7 @@ def eat_pizza(pizza):
170198

171199
## Accessing the Current Span
172200

173-
To change data in the current span, use `sentry_sdk.Hub.current.scope.span`. This property will return a span if there's one running, otherwise it will return `None`.
201+
To change data in the current span, use ` sentry_sdk.get_current_span()`. This function will return a span if there's one running, otherwise it will return `None`.
174202

175203
In this example, we'll set a tag in the span created by the `@sentry_sdk.trace` decorator.
176204

@@ -179,10 +207,8 @@ import sentry_sdk
179207

180208
@sentry_sdk.trace
181209
def eat_slice(slice):
182-
span = sentry_sdk.Hub.current.scope.span
210+
span = sentry_sdk.get_current_span()
183211

184212
if span is not None:
185213
span.set_tag("slice_id", slice.id)
186-
187-
...
188214
```

0 commit comments

Comments
 (0)