diff --git a/docs/platforms/python/crons/troubleshooting.mdx b/docs/platforms/python/crons/troubleshooting.mdx deleted file mode 100644 index 8e6478f1945f0..0000000000000 --- a/docs/platforms/python/crons/troubleshooting.mdx +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: Troubleshooting -description: "Learn how to troubleshoot your Cron Monitoring setup." -sidebar_order: 9000 ---- - - - - - -You may not have linked errors to your monitor. - - - - - -The SDK might be experiencing network issues. Learn more about troubleshooting network issues. - - - - - -You may not have set up alerts for your monitor. - - - - - -Our current data retention policy is 90 days. - - - - - -Currently, we only support crontab expressions with five fields. - - - - - -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. - - diff --git a/docs/platforms/python/profiling/troubleshooting/index.mdx b/docs/platforms/python/profiling/troubleshooting/index.mdx deleted file mode 100644 index 09bc08df9eb11..0000000000000 --- a/docs/platforms/python/profiling/troubleshooting/index.mdx +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: Troubleshooting -description: "Learn how to troubleshoot your profiling setup." -sidebar_order: 9000 ---- - -If you don't see any profiling data in [sentry.io](https://sentry.io), you can try the following: - -- Ensure that Tracing is enabled. -- Ensure that the automatic instrumentation is sending performance data to Sentry by going to the **Performance** page in [sentry.io](https://sentry.io). -- If the automatic instrumentation is not sending performance data, try using custom instrumentation. -- Enable debug mode in the SDK and check the logs. - - -### Upgrading From Older SDK Versions - -The feature was experimental prior to version `1.17.0`. To update your SDK to the latest version, remove `profiles_sample_rate` from `_experiments` and set it in the top-level options. - - -```python -sentry_sdk.init( - dsn="___PUBLIC_DSN___", - traces_sample_rate=1.0, - _experiments={ - "profiles_sample_rate": 1.0, # for versions before 1.17.0 - }, -) -``` diff --git a/docs/platforms/python/tracing/troubleshooting/index.mdx b/docs/platforms/python/tracing/troubleshooting/index.mdx deleted file mode 100644 index 91680e839de3e..0000000000000 --- a/docs/platforms/python/tracing/troubleshooting/index.mdx +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: Troubleshooting -description: "Learn how to troubleshoot your tracing setup." -sidebar_order: 9000 ---- - -If you need help managing transactions, you can read more here. If you need additional help, you can ask on GitHub. Customers on a paid plan may also contact support. - -## Control Data Truncation - -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. - -For example, a 200+ character tagged request: - -`https://empowerplant.io/api/0/projects/ep/setup_form/?user_id=314159265358979323846264338327&tracking_id=EasyAsABC123OrSimpleAsDoReMi&product_name=PlantToHumanTranslator&product_id=161803398874989484820458683436563811772030917980576` - -The 200+ character request above will become truncated to: - -`https://empowerplant.io/api/0/projects/ep/setup_form/?user_id=314159265358979323846264338327&tracking_id=EasyAsABC123OrSimpleAsDoReMi&product_name=PlantToHumanTranslator&product_id=1618033988749894848` - - diff --git a/docs/platforms/python/troubleshooting.mdx b/docs/platforms/python/troubleshooting.mdx index 8452279457f96..bf5f243022802 100644 --- a/docs/platforms/python/troubleshooting.mdx +++ b/docs/platforms/python/troubleshooting.mdx @@ -4,8 +4,7 @@ description: "While we don't expect most users of our SDK to run into these issu sidebar_order: 9000 --- -We expect most users of the Python SDK not to run into any of the problems -documented here. +## General Use the information in this page to help answer these questions: @@ -13,105 +12,106 @@ Use the information in this page to help answer these questions: - "What do I do if my transaction has nested spans when they should be parallel?" - "What do I do if the SDK has trouble sending events to Sentry?" -## Addressing Concurrency Issues + + The short answer to the first two questions: make sure your `contextvars` work and + that your isolation scope was cloned for each concurrency unit. -The short answer to the first two questions: make sure your `contextvars` work and -that your isolation scope was cloned for each concurrency unit. + Python supports several distinct solutions to concurrency, including threads and + coroutines. -Python supports several distinct solutions to concurrency, including threads and -coroutines. + The Python SDK does its best to figure out how contextual data such as tags set + with `sentry_sdk.set_tags` is supposed to flow along your control flow. In most + cases it works perfectly, but in a few situations some special care must be + taken. This is specially true when working with a code base doing concurrency + outside of the provided framework integrations. -The Python SDK does its best to figure out how contextual data such as tags set -with `sentry_sdk.set_tags` is supposed to flow along your control flow. In most -cases it works perfectly, but in a few situations some special care must be -taken. This is specially true when working with a code base doing concurrency -outside of the provided framework integrations. + The general recommendation is to have one isolation scope per "concurrency unit" + (thread/coroutine/etc). The SDK ensures every thread has an independent scope via the `ThreadingIntegration`. + If you do concurrency with `asyncio` coroutines, make sure to use the `AsyncioIntegration` + which will clone the correct scope in your `Task`s. -The general recommendation is to have one isolation scope per "concurrency unit" -(thread/coroutine/etc). The SDK ensures every thread has an independent scope via the `ThreadingIntegration`. -If you do concurrency with `asyncio` coroutines, make sure to use the `AsyncioIntegration` -which will clone the correct scope in your `Task`s. + The general pattern of usage for creating a new isolation scope is: -The general pattern of usage for creating a new isolation scope is: + ```python + with sentry_sdk.isolation_scope() as scope: + # In this block scope refers to a new fork of the original isolation scope, + # with the same client and the same initial scope data. + ``` -```python -with sentry_sdk.isolation_scope() as scope: - # In this block scope refers to a new fork of the original isolation scope, - # with the same client and the same initial scope data. -``` - -See the Threading section -for a more complete example that involves forking the isolation scope. + See the Threading section + for a more complete example that involves forking the isolation scope. + -## Context Variables vs Thread Locals + -The Python SDK uses [thread -locals](https://docs.python.org/3/library/threading.html#thread-local-data) to -keep contextual data where it belongs. There are a few situations where this -approach fails. + The Python SDK uses [thread locals](https://docs.python.org/3/library/threading.html#thread-local-data) to + keep contextual data where it belongs. There are a few situations where this + approach fails. -Read along if you cannot figure out why contextual data is leaking across HTTP -requests, or data is missing or popping up at the wrong place and time. + Read along if you cannot figure out why contextual data is leaking across HTTP + requests, or data is missing or popping up at the wrong place and time. -### Python 2: Thread Locals and gevent +#### Python 2: Thread Locals and gevent -If the SDK is installed on Python 2, there is not much else to use than the -aforementioned thread locals, so the SDK will use just that. + If the SDK is installed on Python 2, there is not much else to use than the + aforementioned thread locals, so the SDK will use just that. -Code that uses async libraries such as **`twisted` is not supported** in the -sense that you will experience context data leaking across tasks/any logical -boundaries, at least out of the box. + Code that uses async libraries such as **`twisted` is not supported** in the + sense that you will experience context data leaking across tasks/any logical + boundaries, at least out of the box. -Code that uses more "magical" async libraries such as **`gevent` or `eventlet` -will work just fine** provided those libraries are configured to monkeypatch -the stdlib. If you are only using those libraries in the context of running -`gunicorn` that is the case, for example. + Code that uses more "magical" async libraries such as **`gevent` or `eventlet` + will work just fine** provided those libraries are configured to monkeypatch + the stdlib. If you are only using those libraries in the context of running + `gunicorn` that is the case, for example. -### Python 3: Context Variables or Thread Locals +#### Python 3: Context Variables or Thread Locals -Python 3 introduced `asyncio`, which, just like Twisted, had the problem of not -having any concept of attaching contextual data to your control flow. That -means in Python 3.6 and lower, the SDK is not able to prevent leaks of -contextual data. + Python 3 introduced `asyncio`, which, just like Twisted, had the problem of not + having any concept of attaching contextual data to your control flow. That + means in Python 3.6 and lower, the SDK is not able to prevent leaks of + contextual data. -Python 3.7 rectified this problem with the `contextvars` stdlib module which is -basically thread locals that also work in asyncio-based code. The SDK will -attempt to use that module instead of thread locals if available. + Python 3.7 rectified this problem with the `contextvars` stdlib module which is + basically thread locals that also work in asyncio-based code. The SDK will + attempt to use that module instead of thread locals if available. -**For Python 3.6 and older, install `aiocontextvars` from PyPI** which is a -fully-functional backport of `contextvars`. The SDK will check for this package -and use it instead of thread locals. + **For Python 3.6 and older, install `aiocontextvars` from PyPI** which is a + fully-functional backport of `contextvars`. The SDK will check for this package + and use it instead of thread locals. -## Context Variables vs gevent/eventlet + -If you are using `gevent` (older than 20.5) or `eventlet` in your application and -have configured it to monkeypatch the stdlib, the SDK will abstain from using -`contextvars` even if it is available. + + If you are using `gevent` (older than 20.5) or `eventlet` in your application and + have configured it to monkeypatch the stdlib, the SDK will abstain from using + `contextvars` even if it is available. -The reason for that is that both of those libraries will monkeypatch the -`threading` module only, and not the `contextvars` module. + The reason for that is that both of those libraries will monkeypatch the + `threading` module only, and not the `contextvars` module. -The real-world usecase where this actually comes up is if you're using Django -3.0 within a `gunicorn+gevent` worker on Python 3.7. In such a scenario the -monkeypatched `threading` module will honor the control flow of a gunicorn -worker while the unpatched `contextvars` will not. + The real-world usecase where this actually comes up is if you're using Django + 3.0 within a `gunicorn+gevent` worker on Python 3.7. In such a scenario the + monkeypatched `threading` module will honor the control flow of a gunicorn + worker while the unpatched `contextvars` will not. -It gets more complicated if you're using Django Channels in the same app, but a -separate server process, as this is a legitimate usage of `asyncio` for which -`contextvars` behaves more correctly. Make sure that your channels websocket -server does not import or use gevent at all (and much less call -`gevent.monkey.patch_all`), and you should be good. + It gets more complicated if you're using Django Channels in the same app, but a + separate server process, as this is a legitimate usage of `asyncio` for which + `contextvars` behaves more correctly. Make sure that your channels websocket + server does not import or use gevent at all (and much less call + `gevent.monkey.patch_all`), and you should be good. -Even then there are still edge cases where this behavior is flat-out broken, -such as mixing asyncio code with gevent/eventlet-based code. In that case there -is no right, _static_ answer as to which context library to use. Even then -gevent's aggressive monkeypatching is likely to interfere in a way that cannot -be fixed from within the SDK. + Even then there are still edge cases where this behavior is flat-out broken, + such as mixing asyncio code with gevent/eventlet-based code. In that case there + is no right, _static_ answer as to which context library to use. Even then + gevent's aggressive monkeypatching is likely to interfere in a way that cannot + be fixed from within the SDK. -This [issue has been fixed with gevent 20.5](https://github.com/gevent/gevent/issues/1407) but continues to be one for -eventlet. + This [issue has been fixed with gevent 20.5](https://github.com/gevent/gevent/issues/1407) but continues to be one for + eventlet. + -## Network Issues + Your SDK might have issues sending events to Sentry. You might see `"Remote end closed connection without response"`, `"Connection aborted"`, @@ -136,8 +136,9 @@ sentry_sdk.init( If you need more fine-grained control over the behavior of the socket, check out socket-options. + -## Multiprocessing deprecation after Python 3.12 + 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. @@ -160,3 +161,88 @@ if __name__ == "__main__": pool = concurrent.futures.ProcessPoolExecutor() pool.submit(sentry_sdk.capture_message, "world") ``` + + + + + 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. + + For example, a 200+ character tagged request: + + `https://empowerplant.io/api/0/projects/ep/setup_form/?user_id=314159265358979323846264338327&tracking_id=EasyAsABC123OrSimpleAsDoReMi&product_name=PlantToHumanTranslator&product_id=161803398874989484820458683436563811772030917980576` + + The 200+ character request above will become truncated to: + + `https://empowerplant.io/api/0/projects/ep/setup_form/?user_id=314159265358979323846264338327&tracking_id=EasyAsABC123OrSimpleAsDoReMi&product_name=PlantToHumanTranslator&product_id=1618033988749894848` + + + + + + +## Profiling + + + +If you don't see any profiling data in [sentry.io](https://sentry.io), you can try the following: + +- Ensure that Tracing is enabled. +- Ensure that the automatic instrumentation is sending performance data to Sentry by going to the **Performance** page in [sentry.io](https://sentry.io). +- If the automatic instrumentation is not sending performance data, try using custom instrumentation. +- Enable debug mode in the SDK and check the logs. + +### Upgrading From Older SDK Versions + +The feature was experimental prior to version `1.17.0`. To update your SDK to the latest version, remove `profiles_sample_rate` from `_experiments` and set it in the top-level options. + +```python +sentry_sdk.init( + dsn="___PUBLIC_DSN___", + traces_sample_rate=1.0, + _experiments={ + "profiles_sample_rate": 1.0, # for versions before 1.17.0 + }, +) +``` + + + +## Crons + + + + + + You may not have linked errors to your monitor. + + + + + + The SDK might be experiencing network issues. Learn more about troubleshooting network issues. + + + + + + You may not have set up alerts for your monitor. + + + + + + Our current data retention policy is 90 days. + + + + + + Currently, we only support crontab expressions with five fields. + + + + + + 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. + + diff --git a/redirects.js b/redirects.js index 5ce5c460f4765..3977f72f35287 100644 --- a/redirects.js +++ b/redirects.js @@ -964,6 +964,10 @@ const userDocsRedirects = [ source: '/product/explore/feature-flags/:path*', destination: '/product/issues/issue-details/feature-flags/:path*', }, + { + source: '/platforms/python/:productfeature/troubleshooting/:path*', + destination: '/platforms/python/troubleshooting/:path*', + }, { source: '/platforms/ruby/guides/:guide/:productfeature/troubleshooting/:path*', destination: '/platforms/ruby/guides/:guide/troubleshooting/:path*',