Skip to content

Commit 82d60e1

Browse files
authored
feat(python): Update troubleshooting page for 3.x (#14435)
- updated example on Troubleshooting page - created a new copy of the Troubleshooting page for the upcoming SDK 3.0 with the following changes: - remove the section on Context Variables vs Thread Locals since it's only relevant for Python older than 3.7 which is not supported in SDK 3.0
1 parent cd3a6fe commit 82d60e1

File tree

2 files changed

+224
-4
lines changed

2 files changed

+224
-4
lines changed

docs/platforms/python/troubleshooting.mdx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,13 +197,14 @@ If you don't see any profiling data in [sentry.io](https://sentry.io), you can t
197197

198198
The transaction-based profiling feature was experimental prior to version `1.18.0`. To update your SDK to the latest version, remove `profiles_sample_rate` from `_experiments` and set it in the top-level options.
199199

200-
```python
200+
```python diff
201201
sentry_sdk.init(
202202
dsn="___PUBLIC_DSN___",
203203
traces_sample_rate=1.0,
204-
_experiments={
205-
"profiles_sample_rate": 1.0, # for versions before 1.18.0
206-
},
204+
- _experiments={
205+
- "profiles_sample_rate": 1.0, # for versions before 1.18.0
206+
- },
207+
+ profiles_sample_rate=1.0,
207208
)
208209
```
209210

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
---
2+
title: Troubleshooting
3+
description: "While we don't expect most users of our SDK to run into these issues, we document edge cases here."
4+
sidebar_order: 9000
5+
---
6+
7+
## General
8+
9+
Use the information in this page to help answer these questions:
10+
11+
- "What do I do if scope data is leaking between requests?"
12+
- "What do I do if my transaction has nested spans when they should be parallel?"
13+
- "What do I do if the SDK has trouble sending events to Sentry?"
14+
15+
<Expandable title="Addressing Concurrency Issues">
16+
The short answer to the first two questions: make sure your `contextvars` work and
17+
that your isolation scope was cloned for each concurrency unit.
18+
19+
Python supports several distinct solutions to concurrency, including threads and
20+
coroutines.
21+
22+
The Python SDK does its best to figure out how contextual data such as tags set
23+
with `sentry_sdk.set_tags` is supposed to flow along your control flow. In most
24+
cases it works perfectly, but in a few situations some special care must be
25+
taken. This is specially true when working with a code base doing concurrency
26+
outside of the provided framework integrations.
27+
28+
The general recommendation is to have one isolation scope per "concurrency unit"
29+
(thread/coroutine/etc). The SDK ensures every thread has an independent scope via the `ThreadingIntegration`.
30+
If you do concurrency with `asyncio` coroutines, make sure to use the `AsyncioIntegration`
31+
which will clone the correct scope in your `Task`s.
32+
33+
The general pattern of usage for creating a new isolation scope is:
34+
35+
```python
36+
with sentry_sdk.isolation_scope() as scope:
37+
# In this block scope refers to a new fork of the original isolation scope,
38+
# with the same client and the same initial scope data.
39+
```
40+
41+
See the <PlatformLink to="/integrations/default-integrations/#threading">Threading</PlatformLink> section
42+
for a more complete example that involves forking the isolation scope.
43+
</Expandable>
44+
45+
<Expandable title="Context Variables vs gevent/eventlet">
46+
If you are using `gevent` (older than 20.5) or `eventlet` in your application and
47+
have configured it to monkeypatch the stdlib, the SDK will abstain from using
48+
`contextvars` even if it is available.
49+
50+
The reason for that is that both of those libraries will monkeypatch the
51+
`threading` module only, and not the `contextvars` module.
52+
53+
The real-world usecase where this actually comes up is if you're using Django
54+
3.0 within a `gunicorn+gevent` worker on Python 3.7. In such a scenario the
55+
monkeypatched `threading` module will honor the control flow of a gunicorn
56+
worker while the unpatched `contextvars` will not.
57+
58+
It gets more complicated if you're using Django Channels in the same app, but a
59+
separate server process, as this is a legitimate usage of `asyncio` for which
60+
`contextvars` behaves more correctly. Make sure that your channels websocket
61+
server does not import or use gevent at all (and much less call
62+
`gevent.monkey.patch_all`), and you should be good.
63+
64+
Even then there are still edge cases where this behavior is flat-out broken,
65+
such as mixing asyncio code with gevent/eventlet-based code. In that case there
66+
is no right, _static_ answer as to which context library to use. Even then
67+
gevent's aggressive monkeypatching is likely to interfere in a way that cannot
68+
be fixed from within the SDK.
69+
70+
This [issue has been fixed with gevent 20.5](https://github.com/gevent/gevent/issues/1407) but continues to be one for
71+
eventlet.
72+
</Expandable>
73+
74+
<Expandable title="Network Issues">
75+
76+
Your SDK might have issues sending events to Sentry. You might see
77+
`"Remote end closed connection without response"`, `"Connection aborted"`,
78+
`"Connection reset by peer"`, or similar error messages in your logs.
79+
In case of errors and tracing data, this manifests as errors and transactions
80+
missing in Sentry. In case of cron monitors, you might be seeing crons
81+
marked as timed out in Sentry when you know they've run successfully. The SDK
82+
itself might be logging errors about the connection getting reset or the
83+
server closing the connection without response.
84+
85+
If you experience this, try turning on the <PlatformLink to="/configuration/options/#keep-alive">keep-alive</PlatformLink> configuration option, available in SDK
86+
versions `1.43.0` and up.
87+
88+
```python
89+
import sentry_sdk
90+
91+
sentry_sdk.init(
92+
# your usual options
93+
keep_alive=True,
94+
)
95+
```
96+
97+
If you need more fine-grained control over the behavior of the socket, check out
98+
<PlatformLink to="/configuration/options/#socket-options">socket-options</PlatformLink>.
99+
</Expandable>
100+
101+
<Expandable title="Multiprocessing deprecation after Python 3.12">
102+
103+
If you're on Python version 3.12 or greater, you might see the following deprecation warning on Linux environments since the SDK spawns several threads.
104+
105+
```
106+
DeprecationWarning: This process is multi-threaded, use of fork() may lead to deadlocks in the child.
107+
```
108+
109+
To remove this deprecation warning, set the [multiprocessing start method to `spawn` or `forkserver`](https://docs.python.org/3.14/library/multiprocessing.html#contexts-and-start-methods).
110+
Remember to do this only in the `__main__` block.
111+
112+
```python
113+
import sentry_sdk
114+
import multiprocessing
115+
import concurrent.futures
116+
117+
sentry_sdk.init()
118+
119+
if __name__ == "__main__":
120+
multiprocessing.set_start_method("spawn")
121+
pool = concurrent.futures.ProcessPoolExecutor()
122+
pool.submit(sentry_sdk.capture_message, "world")
123+
```
124+
</Expandable>
125+
126+
<Expandable title="Why was my tag value truncated?">
127+
128+
Currently, every tag has a maximum character limit of 200 characters. Tags over the 200 character limit will become truncated, losing potentially important information. To retain this data, you can split data over several tags instead.
129+
130+
For example, a 200+ character tagged request:
131+
132+
`https://empowerplant.io/api/0/projects/ep/setup_form/?user_id=314159265358979323846264338327&tracking_id=EasyAsABC123OrSimpleAsDoReMi&product_name=PlantToHumanTranslator&product_id=161803398874989484820458683436563811772030917980576`
133+
134+
The 200+ character request above will become truncated to:
135+
136+
`https://empowerplant.io/api/0/projects/ep/setup_form/?user_id=314159265358979323846264338327&tracking_id=EasyAsABC123OrSimpleAsDoReMi&product_name=PlantToHumanTranslator&product_id=1618033988749894848`
137+
138+
<PlatformContent includePath="performance/control-data-truncation" />
139+
140+
</Expandable>
141+
142+
143+
## Profiling
144+
145+
<Expandable title="Why am I not seeing any profiling data?">
146+
147+
If you don't see any profiling data in [sentry.io](https://sentry.io), you can try the following:
148+
149+
- Ensure that <PlatformLink to="/tracing/">Tracing is enabled</PlatformLink>.
150+
- Ensure that the automatic instrumentation is sending performance data to Sentry by going to the **Performance** page in [sentry.io](https://sentry.io).
151+
- If the automatic instrumentation is not sending performance data, try using <PlatformLink to="/tracing/instrumentation/custom-instrumentation">custom instrumentation</PlatformLink>.
152+
- Enable <PlatformLink to="/configuration/options/#debug">debug mode</PlatformLink> in the SDK and check the logs.
153+
154+
### Upgrading From Older SDK Versions
155+
156+
#### Transaction-Based Profiling
157+
158+
The transaction-based profiling feature was experimental prior to version `1.18.0`. To update your SDK to the latest version, remove `profiles_sample_rate` from `_experiments` and set it in the top-level options.
159+
160+
```python diff
161+
sentry_sdk.init(
162+
dsn="___PUBLIC_DSN___",
163+
traces_sample_rate=1.0,
164+
- _experiments={
165+
- "profiles_sample_rate": 1.0, # for versions before 1.18.0
166+
- },
167+
+ profiles_sample_rate=1.0,
168+
)
169+
```
170+
171+
#### Continuous Profiling
172+
173+
The continuous profiling feature was experimental prior to version `2.24.1`. To upgrade your SDK to the latest version:
174+
175+
- Remove `continuous_profiling_auto_start` from `_experiments` and set `profile_lifecycle="trace"` in the top-level options.
176+
- Add `profile_session_sample_rate` to the top-level options.
177+
178+
</Expandable>
179+
180+
181+
## Crons
182+
183+
<PlatformContent includePath="crons/troubleshooting" />
184+
185+
<Expandable title="Why aren't recurring job errors showing up on my monitor details page?">
186+
187+
You may not have <PlatformLink to="/crons/#connecting-errors-to-cron-monitors">linked errors to your monitor</PlatformLink>.
188+
189+
</Expandable>
190+
191+
<Expandable title="Why are my monitors showing up as failed?">
192+
193+
The SDK might be experiencing network issues. Learn more about <PlatformLink to="/troubleshooting/#network-issues">troubleshooting network issues</PlatformLink>.
194+
195+
</Expandable>
196+
197+
<Expandable title="Why am I not receiving alerts when my monitor fails?">
198+
199+
You may not have <PlatformLink to="/crons/#alerts">set up alerts for your monitor</PlatformLink>.
200+
201+
</Expandable>
202+
203+
<Expandable title="What is the crons data retention policy for check-ins?">
204+
205+
Our current data retention policy is 90 days.
206+
207+
</Expandable>
208+
209+
<Expandable title="Do you support a monitor schedule with a six-field crontab expression?">
210+
211+
Currently, we only support crontab expressions with five fields.
212+
213+
</Expandable>
214+
215+
<Expandable title="Can I monitor async tasks as well?">
216+
217+
Yes, just make sure you're using SDK version `1.44.1` or higher since that's when support for monitoring async functions was added.
218+
219+
</Expandable>

0 commit comments

Comments
 (0)