The new Python SDK for Sentry.io

Overview

Bad software is everywhere, and we're tired of it. Sentry is on a mission to help developers write better software faster, so we can get back to enjoying technology. If you want to join us Check out our open positions

sentry-python - Sentry SDK for Python

Build Status PyPi page link -- version Discord

This is the next line of the Python SDK for Sentry, intended to replace the raven package on PyPI.

from sentry_sdk import init, capture_message

init("https://[email protected]/123")

capture_message("Hello World")  # Will create an event.

raise ValueError()  # Will also create an event.

Contributing to the SDK

Please refer to CONTRIBUTING.md.

License

Licensed under the BSD license, see LICENSE

Comments
  • Azure Function doesn't capture exceptions on Azure

    Azure Function doesn't capture exceptions on Azure

    I have a Queue Trigger Azure Function in Python with the following code:

    import logging
    import os
    
    import azure.functions as func
    import sentry_sdk
    from sentry_sdk.api import capture_exception, flush, push_scope
    from sentry_sdk.integrations.serverless import serverless_function
    
    # Sentry configuration
    sentry_dsn = "my-dsn"
    environment = "DEV"
    logger = logging.getLogger(__name__)
    sentry_sdk.init(
        sentry_dsn,
        environment=environment,
        send_default_pii=True,
        request_bodies="always",
        with_locals=True,
    )
    sentry_sdk.utils.MAX_STRING_LENGTH = 2048
    
    
    @serverless_function
    def main(msg: func.QueueMessage) -> None:
    
        with push_scope() as scope:
            scope.set_tag("function.name", "ProcessHeadersFile")
            scope.set_context(
                "Queue Message",
                {
                    "id": msg.id,
                    "dequeue_count": msg.dequeue_count,
                    "insertion_time": msg.insertion_time,
                    "expiration_time": msg.expiration_time,
                    "pop_receipt": msg.pop_receipt,
                },
            )
    
            try:
                # code that might raise exceptions here
                function_that_raise()
            except Exception as ex:
                print(ex)
                # Rethrow to fail the execution
                raise
    
    def function_that_raise():
        return 5 / 0
    

    Works locally, but not on Azure. I run multiple invocations, I get all the failures, but then nothing shows on Sentry.

    I have also try manually capturing and flushing, but doesn't work either:

    try:
        # code that might raise exceptions here
        function_that_raise()
    except Exception as ex:
        capture_exception(ex)
        flush(2)
        raise
    

    Using sentry-sdk==0.19.5.

    How can I troubleshoot what's happening? What can be the causes that it works when running the function locally, but not when running on Azure?

    needs-information Integration: Serverless Status: Stale 
    opened by empz 36
  • SentryAsgiMiddleware not compatible with Uvicorn 0.13.0

    SentryAsgiMiddleware not compatible with Uvicorn 0.13.0

    On December 8th Uvicorn updated from 0.12.3 to 0.13.0. This results in an error at startup, see output with minimal example. When downgrading Uvicorn to 0.12.3 the example runs fine.

    Why this error is thrown or which changes resulted in the error, I have no clue. Could you help me with this?

    app.py

    from sanic import Sanic
    from sentry_sdk.integrations.asgi import SentryAsgiMiddleware
    
    app = SentryAsgiMiddleware(Sanic(__name__))
    

    requirements.txt

    sanic==20.9.1
    sentry-sdk==0.19.4
    uvicorn==0.13.0
    

    Command to run:

    uvicorn app:app --port 5000 --workers=1 --debug --reload
    

    Output:

    INFO:     Uvicorn running on http://127.0.0.1:5000 (Press CTRL+C to quit)
    INFO:     Started reloader process [614068] using statreload
    Process SpawnProcess-1:
    Traceback (most recent call last):
      File "/usr/lib/python3.9/multiprocessing/process.py", line 315, in _bootstrap
        self.run()
      File "/usr/lib/python3.9/multiprocessing/process.py", line 108, in run
        self._target(*self._args, **self._kwargs)
      File "/home/lander/.local/share/virtualenvs/san-iJ5wdX60/lib/python3.9/site-packages/uvicorn/subprocess.py", line 61, in subprocess_started
        target(sockets=sockets)
      File "/home/lander/.local/share/virtualenvs/san-iJ5wdX60/lib/python3.9/site-packages/uvicorn/server.py", line 48, in run
        loop.run_until_complete(self.serve(sockets=sockets))
      File "uvloop/loop.pyx", line 1456, in uvloop.loop.Loop.run_until_complete
      File "/home/lander/.local/share/virtualenvs/san-iJ5wdX60/lib/python3.9/site-packages/uvicorn/server.py", line 55, in serve
        config.load()
      File "/home/lander/.local/share/virtualenvs/san-iJ5wdX60/lib/python3.9/site-packages/uvicorn/config.py", line 319, in load
        elif not inspect.signature(self.loaded_app).parameters:
      File "/usr/lib/python3.9/inspect.py", line 3118, in signature
        return Signature.from_callable(obj, follow_wrapped=follow_wrapped)
      File "/usr/lib/python3.9/inspect.py", line 2867, in from_callable
        return _signature_from_callable(obj, sigcls=cls,
      File "/usr/lib/python3.9/inspect.py", line 2409, in _signature_from_callable
        sig = _signature_from_callable(
      File "/usr/lib/python3.9/inspect.py", line 2242, in _signature_from_callable
        raise TypeError('{!r} is not a callable object'.format(obj))
    TypeError: <member '__call__' of 'SentryAsgiMiddleware' objects> is not a callable object
    
    bug 
    opened by LanderMoerkerke 33
  • Version 0.17.8 broke Celery tasks with custom Task class

    Version 0.17.8 broke Celery tasks with custom Task class

    I am using tenant-schemas-celery package, which generates it's own TenantTask (extends celery.app.task.Task) class in it's own CeleryApp (extends celery.Celery). After updating from sentry-sdk from 0.17.7 to 0.17.8 the TenantTask's tenant context switching stopped working. I suspect this is because of the following change in 0.17.8:

    diff --git a/sentry_sdk/integrations/celery.py b/sentry_sdk/integrations/celery.py
    index 1a11d4a..2b51fe1 100644
    --- a/sentry_sdk/integrations/celery.py
    +++ b/sentry_sdk/integrations/celery.py
    @@ -60,9 +60,8 @@ class CeleryIntegration(Integration):
                     # Need to patch both methods because older celery sometimes
                     # short-circuits to task.run if it thinks it's safe.
                     task.__call__ = _wrap_task_call(task, task.__call__)
                     task.run = _wrap_task_call(task, task.run)
    -                task.apply_async = _wrap_apply_async(task, task.apply_async)
    
                     # `build_tracer` is apparently called for every task
                     # invocation. Can't wrap every celery task for every invocation
                     # or we will get infinitely nested wrapper functions.
    @@ -71,8 +70,12 @@ class CeleryIntegration(Integration):
                 return _wrap_tracer(task, old_build_tracer(name, task, *args, **kwargs))
    
             trace.build_tracer = sentry_build_tracer
    
    +        from celery.app.task import Task  # type: ignore
    +
    +        Task.apply_async = _wrap_apply_async(Task.apply_async)
    +
             _patch_worker_exit()
    
             # This logger logs every status of every task that ran on the worker.
             # Meaning that every task's breadcrumbs are full of stuff like "Task
    

    I think this problem has to do with this new way of importing celery.app.task.Task. Even though TenantTask extends the celery.app.task.Task, for some reason this change broke the TenantTask logic.

    I'm not sure which package this should be fixed in, but I'm bit skeptical about this new import in sentry-sdk, so I'm reporting it here.

    Here is my celery.py:

    from tenant_schemas_celery.app import CeleryApp as TenantAwareCeleryApp
    
    
    app = TenantAwareCeleryApp()
    app.config_from_object('django.conf:settings')
    app.autodiscover_tasks()
    
    bug Integration: Celery Status: Stale needs-repro 
    opened by akifd 29
  • document ignore_errors

    document ignore_errors

    The old raven library had this functionality, implemented for Django by declaring a list of names of errors in the settings file.

    This kind of functionality is necessary to control error reporting spam.

    enhancement doc stabilization Status: Backlog 
    opened by biblicabeebli 29
  • Integration for FastAPI

    Integration for FastAPI

    FastAPI is just Starlette which is just ASGI. We have an ASGI integration that should work fine. However, it would be nice to have deeper integration than we currently provide, particularly around Performance monitoring.

    Please vote with šŸ‘ on this post if you're interested in this. I would also like to hear what currently doesn't work out well with the ASGI middleware applied to your FastAPI app.

    enhancement new-integration Status: Backlog Jira 
    opened by untitaker 25
  • Provide a means for capturing stack trace for messages that are not errors

    Provide a means for capturing stack trace for messages that are not errors

    ... without relying on the logging integration.

    SDK v0.7.10

    Currently, the only way to do this is via the logging integration and issuing a log at the configured level or higher with exc_info=True. I don't think this is a good substitute because:

    • I don't want to classify these events as errors (the end goal being errors should drive alerts)
    • Sometimes there are interesting or unexpected events that I want to debug more and leveraging Sentry's stack traces with locals helps in this regard
    • I don't want to lower our logging integration level to warning or similar, as that may spam our project with a lot of warnings/events that are not interesting or useful

    Ideally, the Sentry SDK could add an additional argument to the and capture_message APIs to make this simple from a user perspective:

    sentry_sdk.capture_message("Unexpected event", level="warning", stack_trace=True)
    

    I'm trying to get this working locally with the SDK, and it's leading to incomplete event data (see picture) and also leading to pretty hairy code.

    sentry_sdk.capture_event({"message": "oops 2", "level": "warning", "threads": [{"stacktrace": sentry_sdk.utils.current_stacktrace(with_locals=True), "crashed": False, "current": True}])
    

    This was more or less copied from the code I see for adding stack traces in Client._prepare_event.

    Screenshot from 2019-04-13 14-39-24

    opened by goodspark 25
  • Celery integration not capturing error with max_tasks_per_child = 1

    Celery integration not capturing error with max_tasks_per_child = 1

    The celery integration is failing to capture the exception when I use a celery factory pattern which patches the celery task with Flask's context.

    This is web/celery_factory.py

    # Source: https://stackoverflow.com/questions/12044776/how-to-use-flask-sqlalchemy-in-a-celery-task
    
    from celery import Celery
    import flask
    
    
    class FlaskCelery(Celery):
    
        def __init__(self, *args, **kwargs):
            super(FlaskCelery, self).__init__(*args, **kwargs)
            self.patch_task()
    
            if 'app' in kwargs:
                self.init_app(kwargs['app'])
    
        def patch_task(self):
            TaskBase = self.Task
            _celery = self
    
            class ContextTask(TaskBase):
                abstract = True
    
                def __call__(self, *args, **kwargs):
                    if flask.has_app_context():
                        return TaskBase.__call__(self, *args, **kwargs)
                    else:
                        with _celery.app.app_context():
                            return TaskBase.__call__(self, *args, **kwargs)
    
            self.Task = ContextTask
    
        def init_app(self, app):
            self.app = app
            self.config_from_object(app.config)
    
    
    celery_app = FlaskCelery()
    

    I am adding a random raise inside a simple task

    import celery_app from celery_factory.py
    @celery_app.task
    def simple_task():
        raise Exception("Testing Celery exception")
    

    The error I get printed is:

    [2019-03-08 21:24:21,117: ERROR/ForkPoolWorker-31] Task simple_task[d6e959b1-7253-4e55-861d-c1968ae14e1c] raised unexpected: RuntimeError('No active exception to reraise')
    Traceback (most recent call last):
      File "/Users/okomarov/.virtualenvs/myenv/lib/python3.7/site-packages/celery/app/trace.py", line 382, in trace_task
        R = retval = fun(*args, **kwargs)
      File "/Users/okomarov/Documents/repos/myproject/web/celery_factory.py", line 28, in __call__
        return TaskBase.__call__(self, *args, **kwargs)
      File "/Users/okomarov/.virtualenvs/myenv/lib/python3.7/site-packages/celery/app/trace.py", line 641, in __protected_call__
        return self.run(*args, **kwargs)
      File "/Users/okomarov/.virtualenvs/myenv/lib/python3.7/site-packages/sentry_sdk/integrations/celery.py", line 66, in _inner
        reraise(*_capture_exception())
      File "/Users/okomarov/.virtualenvs/myenv/lib/python3.7/site-packages/sentry_sdk/_compat.py", line 52, in reraise
        raise value
      File "/Users/okomarov/.virtualenvs/myenv/lib/python3.7/site-packages/sentry_sdk/integrations/celery.py", line 64, in _inner
        return f(*args, **kwargs)
      File "/Users/okomarov/.virtualenvs/myenv/lib/python3.7/site-packages/sentry_sdk/integrations/celery.py", line 66, in _inner
        reraise(*_capture_exception())
      File "/Users/okomarov/.virtualenvs/myenv/lib/python3.7/site-packages/sentry_sdk/_compat.py", line 52, in reraise
        raise value
      File "/Users/okomarov/.virtualenvs/myenv/lib/python3.7/site-packages/sentry_sdk/integrations/celery.py", line 64, in _inner
        return f(*args, **kwargs)
      File "/Users/okomarov/Documents/repos/myproject/web/simple_task.py", line 4, in simple_task
        raise Exception("Testing Celery exception")
    RuntimeError: No active exception to reraise
    

    Relevant pip packages:

    Celery==4.2.1
    Flask==1.0.2
    sentry-sdk==0.7.4
    

    The integration is called as following (flask integration works as expected):

    from flask import Flask
    from celery_factory import celery_app
    from config import config_to_use
    
    
    def create_app():
        app = Flask()
        app.config.from_object(config_to_use)
    
        init_logging(app)
    
        register_extensions(app)
        register_blueprints(app)
        register_jinja_extras(app)
    
        return app
    
    
    def init_logging(app):
        import sentry_sdk
        from sentry_sdk.integrations.flask import FlaskIntegration
        from sentry_sdk.integrations.celery import CeleryIntegration
    
        sentry_sdk.init(
            dsn=app.config.get('FLASK_SENTRY_DSN'),
            integrations=[FlaskIntegration(), CeleryIntegration()]
            )
    
    ...
    
    bug 
    opened by okomarov 23
  • No IPv4 fallback and no error reporting on failed connection

    No IPv4 fallback and no error reporting on failed connection

    If you self-host a sentry instance and have a broken IPv6 setup on the server (i.e., you have an AAAA record set up for the domain, but it points at the wrong IP), but a working IPv4 setup, sentry-python will attempt to deliver the issue via IPv6 (if the network supports it), fail, and not retry with IPv4.

    If this isn't intended behavior, I would recommend implementing an IPv4 fallback. At a minimum, it would be nice if the system would report an error if the connection failed - even with debug enabled, the log does not indicate that the connection failed, and is more or less indistinguishable from a log where the reporting worked.

    In my eyes, an IPv4 fallback would be desirable either way, because some places have broken IPv6 networks (they provide v6 IPs, but do not let them access the internet). This is another scenario where the robustness of reporting would be improved with a v4 fallback.

    Steps to reproduce:

    • Set up Sentry with working A record, but AAAA record pointing at an incorrect IP
    • Run the following code:
    import sentry_sdk
    
    sentry_sdk.init(YOUR_DSN, debug=True)
    
    # Produce an exception:
    1/0
    
    bug help wanted Status: Backlog 
    opened by malexmave 23
  • Django channels + ASGI leaks memory

    Django channels + ASGI leaks memory

    I expended around 3 days trying to figure out what was leaking in my Django app and I was only able to fix it by disabling sentry Django integration (on a very isolated test using memory profiler, tracemalloc and docker). To give more context before profiling information, that's how my memory usage graph looked on a production server (killing the app and/or a worker after a certain threshold): image

    Now the data I gathered:

    By performing 100,000 requests on this endpoint:

    class SimpleView(APIView):
        def get(self, request):
            return Response(status=status.HTTP_204_NO_CONTENT)
    

    A tracemalloc snapshot, grouped by filename, showed sentry django integration using 9MB of memory after a 217 seconds test with 459 requests per second. (using NGINX and Hypercorn with 3 workers):

    /usr/local/lib/python3.7/site-packages/sentry_sdk/integrations/django/__init__.py:0: size=8845 KiB (+8845 KiB), count=102930 (+102930), average=88 B
    /usr/local/lib/python3.7/site-packages/django/urls/resolvers.py:0: size=630 KiB (+630 KiB), count=5840 (+5840), average=110 B
    /usr/local/lib/python3.7/linecache.py:0: size=503 KiB (+503 KiB), count=5311 (+5311), average=97 B
    /usr/local/lib/python3.7/asyncio/selector_events.py:0: size=465 KiB (+465 KiB), count=6498 (+6498), average=73 B
    /usr/local/lib/python3.7/site-packages/sentry_sdk/scope.py:0: size=325 KiB (+325 KiB), count=373 (+373), average=892 B
    

    tracemalloc probe endpoint:

    import tracemalloc
    tracemalloc.start()
    
    start = tracemalloc.take_snapshot()
    
    @api_view(['GET'])
    def PrintMemoryInformation(request):
        current = tracemalloc.take_snapshot()
    
        top_stats = current.compare_to(start, 'filename')
        for stat in top_stats[:5]:
            print(stat)
    
        return Response(status=status.HTTP_204_NO_CONTENT)
    

    I have performed longers tests and the sentry django integration memory usage only grows, never releases, this is just a scaled-down version of the tests I've been performing to identify this leak.

    This is how my sentry settings looks like on settings.py: image

    Memory profile after disabling the Django Integration (same test and endpoint), no sentry sdk at top 5 most consuming files:

    /usr/local/lib/python3.7/site-packages/django/urls/resolvers.py:0: size=1450 KiB (+1450 KiB), count=15123 (+15123), average=98 B
    /usr/local/lib/python3.7/site-packages/hypercorn/protocol/h11.py:0: size=1425 KiB (+1425 KiB), count=8868 (+8868), average=165 B
    /usr/local/lib/python3.7/site-packages/channels/http.py:0: size=1398 KiB (+1398 KiB), count=14848 (+14848), average=96 B
    /usr/local/lib/python3.7/site-packages/h11/_state.py:0: size=1242 KiB (+1242 KiB), count=13998 (+13998), average=91 B
    /usr/local/lib/python3.7/site-packages/h11/_connection.py:0: size=1226 KiB (+1226 KiB), count=15957 (+15957), average=79 B
    

    settings.py for the above profile: image

    Memory profile grouped by line number (more verbose):

    /usr/local/lib/python3.7/site-packages/sentry_sdk/integrations/django/__init__.py:272: size=4512 KiB (+4512 KiB), count=33972 (+33972), average=136 B
    /usr/local/lib/python3.7/site-packages/sentry_sdk/integrations/django/__init__.py:134: size=4247 KiB (+4247 KiB), count=67945 (+67945), average=64 B
    /usr/local/lib/python3.7/linecache.py:137: size=492 KiB (+492 KiB), count=4850 (+4850), average=104 B
    /usr/local/lib/python3.7/asyncio/selector_events.py:716: size=415 KiB (+415 KiB), count=2530 (+2530), average=168 B
    /usr/local/lib/python3.7/site-packages/sentry_sdk/scope.py:198: size=279 KiB (+279 KiB), count=1 (+1), average=279 KiB
    /usr/local/lib/python3.7/site-packages/django/views/generic/base.py:65: size=262 KiB (+262 KiB), count=4783 (+4783), average=56 B
    /usr/local/lib/python3.7/socket.py:213: size=237 KiB (+237 KiB), count=2530 (+2530), average=96 B
    /usr/local/lib/python3.7/site-packages/ddtrace/span.py:149: size=229 KiB (+229 KiB), count=1765 (+1765), average=133 B
    /usr/local/lib/python3.7/site-packages/django/urls/resolvers.py:537: size=229 KiB (+229 KiB), count=390 (+390), average=600 B
    /usr/local/lib/python3.7/site-packages/h11/_state.py:261: size=224 KiB (+224 KiB), count=3170 (+3170), average=72 B
    /usr/local/lib/python3.7/site-packages/django/contrib/messages/storage/session.py:21: size=211 KiB (+211 KiB), count=3863 (+3863), average=56 B
    /usr/local/lib/python3.7/site-packages/rest_framework/request.py:414: size=195 KiB (+195 KiB), count=3565 (+3565), average=56 B
    /usr/local/lib/python3.7/functools.py:60: size=194 KiB (+194 KiB), count=1611 (+1611), average=124 B
    /usr/local/lib/python3.7/site-packages/ddtrace/vendor/msgpack/fallback.py:847: size=192 KiB (+192 KiB), count=542 (+542), average=363 B
    /usr/local/lib/python3.7/site-packages/django/http/request.py:427: size=183 KiB (+183 KiB), count=3335 (+3335), average=56 B
    /usr/local/lib/python3.7/site-packages/ddtrace/encoding.py:114: size=171 KiB (+171 KiB), count=6 (+6), average=28.5 KiB
    /usr/local/lib/python3.7/site-packages/rest_framework/views.py:478: size=166 KiB (+166 KiB), count=3002 (+3002), average=57 B
    /usr/local/lib/python3.7/site-packages/django/utils/datastructures.py:67: size=164 KiB (+164 KiB), count=3006 (+3006), average=56 B
    /usr/local/lib/python3.7/asyncio/selector_events.py:581: size=163 KiB (+163 KiB), count=2530 (+2530), average=66 B
    /usr/local/lib/python3.7/site-packages/h11/_connection.py:233: size=159 KiB (+159 KiB), count=2263 (+2263), average=72 B
    

    my pip freeze output:

    aioredis==1.2.0
    amqp==2.5.0
    appdirs==1.4.3
    asgiref==3.1.4
    asn1crypto==0.24.0
    astroid==2.2.5
    async-timeout==3.0.1
    atomicwrites==1.3.0
    attrs==19.1.0
    autobahn==19.7.1
    Automat==0.7.0
    autopep8==1.4.4
    Babel==2.7.0
    billiard==3.6.0.0
    boto3==1.9.185
    botocore==1.12.185
    celery==4.3.0
    certifi==2019.6.16
    cffi==1.12.3
    channels==2.2.0
    channels-redis==2.4.0
    chardet==3.0.4
    Click==7.0
    colorama==0.4.1
    constantly==15.1.0
    coverage==4.5.3
    cryptography==2.7
    daphne==2.3.0
    ddtrace==0.26.0
    dj-database-url==0.5.0
    Django==2.2.3
    django-anymail==6.1.0
    django-cors-headers==3.0.2
    django-filter==2.1.0
    django-ipware==2.1.0
    django-money==0.15
    django-nose==1.4.6
    django-redis==4.10.0
    django-storages==1.7.1
    django-templated-mail==1.1.1
    djangorestframework==3.9.4
    djoser==1.7.0
    docopt==0.6.2
    docutils==0.14
    factory-boy==2.12.0
    Faker==1.0.7
    flower==0.9.3
    geoip2==2.9.0
    gprof2dot==2017.9.19
    graphviz==0.11
    green==2.16.1
    gunicorn==19.9.0
    h11==0.9.0
    h2==3.1.0
    hiredis==1.0.0
    hpack==3.0.0
    httptools==0.0.13
    Hypercorn==0.7.0
    hyperframe==5.2.0
    hyperlink==19.0.0
    idna==2.8
    importlib-metadata==0.18
    incremental==17.5.0
    isort==4.3.21
    jedi==0.14.0
    Jinja2==2.10.1
    jmespath==0.9.4
    kombu==4.6.3
    lazy-object-proxy==1.4.1
    lxml==4.3.4
    MarkupSafe==1.1.1
    maxminddb==1.4.1
    mccabe==0.6.1
    more-itertools==7.1.0
    msgpack==0.6.1
    nose==1.3.7
    objgraph==3.4.1
    packaging==19.0
    parso==0.5.0
    pendulum==2.0.5
    Pillow==6.1.0
    pipdate==0.3.2
    pluggy==0.12.0
    prompt-toolkit==2.0.9
    psutil==5.6.3
    psycopg2-binary==2.8.3
    ptpython==2.0.4
    py==1.8.0
    py-moneyed==0.8.0
    pycodestyle==2.5.0
    pycparser==2.19
    Pygments==2.4.2
    PyHamcrest==1.9.0
    PyJWT==1.7.1
    pylint==2.3.1
    pylint-django==2.0.10
    pylint-plugin-utils==0.5
    pyparsing==2.4.0
    python-dateutil==2.8.0
    pytoml==0.1.20
    pytz==2019.1
    pytzdata==2019.2
    redis==3.2.1
    requests==2.22.0
    s3transfer==0.2.1
    sentry-sdk==0.10.1
    six==1.12.0
    sqlparse==0.3.0
    text-unidecode==1.2
    toml==0.10.0
    tornado==5.1.1
    Twisted==19.2.1
    txaio==18.8.1
    typed-ast==1.4.0
    typing-extensions==3.7.4
    Unidecode==1.1.1
    urllib3==1.25.3
    uvloop==0.12.2
    vine==1.3.0
    wcwidth==0.1.7
    websockets==7.0
    whitenoise==4.1.2
    wrapt==1.11.2
    wsproto==0.14.1
    zipp==0.5.2
    zope.interface==4.6.0
    

    I used the official python docker image with the label 3.7, meaning latest 3.7 version.

    Hope you guys can figure the problem with this data, I'm not sure if I'll have the time to contribute myself!

    Bonus, memory profiling after 1,000,000 requests (Django Integration using 44MB):

    /usr/local/lib/python3.7/site-packages/sentry_sdk/integrations/django/__init__.py:272: size=43.9 MiB (+43.9 MiB), count=338647 (+338647), average=136 B
    /usr/local/lib/python3.7/site-packages/sentry_sdk/integrations/django/__init__.py:134: size=41.3 MiB (+41.3 MiB), count=677294 (+677294), average=64 B
    /usr/local/lib/python3.7/site-packages/sentry_sdk/scope.py:198: size=2942 KiB (+2942 KiB), count=1 (+1), average=2942 KiB
    /usr/local/lib/python3.7/site-packages/django/views/generic/base.py:65: size=2584 KiB (+2584 KiB), count=47252 (+47252), average=56 B
    /usr/local/lib/python3.7/site-packages/django/contrib/messages/storage/session.py:21: size=2079 KiB (+2079 KiB), count=38013 (+38013), average=56 B
    /usr/local/lib/python3.7/site-packages/rest_framework/request.py:414: size=2006 KiB (+2006 KiB), count=36684 (+36684), average=56 B
    /usr/local/lib/python3.7/site-packages/django/http/request.py:427: size=1857 KiB (+1857 KiB), count=33946 (+33946), average=56 B
    /usr/local/lib/python3.7/site-packages/django/utils/datastructures.py:67: size=1670 KiB (+1670 KiB), count=30546 (+30546), average=56 B
    /usr/local/lib/python3.7/site-packages/rest_framework/views.py:478: size=1547 KiB (+1547 KiB), count=28237 (+28237), average=56 B
    /usr/local/lib/python3.7/site-packages/django/contrib/auth/middleware.py:24: size=1518 KiB (+1518 KiB), count=27752 (+27752), average=56 B
    /usr/local/lib/python3.7/importlib/__init__.py:118: size=1398 KiB (+1398 KiB), count=25571 (+25571), average=56 B
    /usr/local/lib/python3.7/site-packages/django/contrib/messages/storage/__init__.py:12: size=930 KiB (+930 KiB), count=17000 (+17000), average=56 B
    /usr/local/lib/python3.7/site-packages/sentry_sdk/tracing.py:123: size=885 KiB (+885 KiB), count=5985 (+5985), average=151 B
    /usr/local/lib/python3.7/asyncio/selector_events.py:716: size=664 KiB (+664 KiB), count=4049 (+4049), average=168 B
    /usr/local/lib/python3.7/site-packages/django/urls/resolvers.py:541: size=662 KiB (+662 KiB), count=12107 (+12107), average=56 B
    /usr/local/lib/python3.7/site-packages/django/http/request.py:584: size=601 KiB (+601 KiB), count=10986 (+10986), average=56 B
    /usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py:34: size=592 KiB (+592 KiB), count=10618 (+10618), average=57 B
    /usr/local/lib/python3.7/linecache.py:137: size=493 KiB (+493 KiB), count=4875 (+4875), average=104 B
    /usr/local/lib/python3.7/site-packages/h11/_state.py:261: size=434 KiB (+434 KiB), count=6142 (+6142), average=72 B
    /usr/local/lib/python3.7/site-packages/ddtrace/span.py:149: size=406 KiB (+406 KiB), count=3124 (+3124), average=133 B
    
    bug 
    opened by astutejoe 22
  • celery integration RecursionError

    celery integration RecursionError

    Hi there, I upgraded sentry_sdk to 0.7.0 and started getting RecursionError if there's an issue with celery task. Sentry record doesn't contain any stack trace for that but found that error in my apm system (can attach screenshot only, text data is a real mess there). I'm running celery 4.2.1 on Ubuntu 18.

    2019-02-14 15 04 54 bug needs-information 
    opened by chemiron 22
  • Using multiple DSNs, choosing based on the logger

    Using multiple DSNs, choosing based on the logger

    I'm looking to upgrade from raven-python[flask] to sentry-sdk[flask]. We previous had two DSNs for our backend: one for errors and one to log performance issues (e.g. slow requests / high DB query count).

    We were previously able to configure this via:

    from raven.contrib.flask import Sentry
    from raven.handlers.logging import SentryHandler
    
    performance_logger = logging.getLogger("benchling.performance")
    performance_logger.setLevel(logging.WARNING)
    sentry = Sentry(logging=True, level=logging.WARNING)
    
    def init_sentry(app):
        sentry.init_app(app, dsn=app.config["SENTRY_DSN_SERVER"])
        performance_handler = SentryHandler(dsn=app.config["SENTRY_DSN_BACKEND_PERFORMANCE"])
        performance_logger.addHandler(performance_handler)
    

    With the new architecture, this seems hard to do since the DSN is configured once via sentry_sdk.init where the LoggingIntegration simply listens to the root logger. I was able to hack around this by monkey-patching the logging_integration's handler as follows:

    import logging
    
    import sentry_sdk
    from sentry_sdk.client import Client
    from sentry_sdk.hub import Hub
    from sentry_sdk.integrations.celery import CeleryIntegration
    from sentry_sdk.integrations.flask import FlaskIntegration
    from sentry_sdk.integrations.logging import LoggingIntegration
    
    
    def register_clients_for_loggers(logger_name_to_client):
        """Monkeypatch LoggingIntegration's EventHandler to override the Client based on the record's logger"""
        hub = Hub.current
        logging_integration = hub.get_integration(LoggingIntegration)
        if not logging_integration:
            return
        handler = logging_integration._handler
        old_emit = handler.emit
    
        def new_emit(record):
            new_client = logger_name_to_client.get(record.name)
            previous_client = hub.client
            should_bind = new_client is not None
            try:
                if should_bind:
                    hub.bind_client(new_client)
                old_emit(record)
            finally:
                if should_bind:
                    hub.bind_client(previous_client)
    
        handler.emit = new_emit
    
    def init_sentry(app):
        sentry_sdk.init(
            dsn=app.config["SENTRY_DSN_SERVER"],
            release=app.config["SENTRY_RELEASE"],
            environment=app.config["SENTRY_ENVIRONMENT"],
            integrations=[
                LoggingIntegration(
                    level=logging.WARNING,  # Capture info and above as breadcrumbs
                    event_level=logging.WARNING,  # Send warnings and errors as events
                ),
                CeleryIntegration(),
                FlaskIntegration(),
            ],
        )
    
        performance_logger = logging.getLogger("benchling.performance")
        performance_logger.setLevel(logging.WARNING)
    
        perf_client = Client(
            dsn=app.config["SENTRY_DSN_BACKEND_PERFORMANCE"],
            release=app.config["SENTRY_RELEASE"],
            environment=app.config["SENTRY_ENVIRONMENT"],
        )
        register_clients_for_loggers({performance_logger.name: perf_client})
    

    Two questions:

    1. Does this approach seem reasonable, or is there a better way to handle this?
    2. If there isn't a better way, would it be possible to have sentry_sdk.init let you specify this mapping?
    question 
    opened by saifelse 22
  • Support for Sanic 22.12.0

    Support for Sanic 22.12.0

    Problem Statement

    We'd like to upgrade from prior LTS release of sanic (21.12.2) to the new LTS release and just want to make sure everything will work reliably.

    Could you please verify that sentry-python works with the latest LTS release of sanic?

    Solution Brainstorm

    Just want clarification

    enhancement Status: Untriaged 
    opened by robd003 0
  • Profiles will not work with a `traces_sampler` instead of `traces_sample_rate`

    Profiles will not work with a `traces_sampler` instead of `traces_sample_rate`

    How do you use Sentry?

    Sentry Saas (sentry.io)

    Version

    1.12.1

    Steps to Reproduce

    1. Pass a TracesSampler instead of setting traces_sample_rate
    2. Set _experiments['profiles_sample_rate'] to 1.0

    Expected Result

    Every request with a trace also has a corresponding profile

    Actual Result

    No profiles are being recorded

    P.S. From glancing at the code it doesn't look like there is a hard dependency on the more "dumb" traces_sample_rate over a TracesSampler. It's just that init checks for traces_sample_rate instead of doing the more thorough check of has_tracing_enabled which will check either option.

    As a workaround I seem to be able to just pass a dummy fixed sampling rate, since the TracesSampler always takes priority.

    P.P.S. Looks like the workaround might not actually work, since I'm still seeing no profiles for traced transactions. Unless they take a while to process. But I will try some alternative sampling methods for the profiler before giving up.

    Status: Untriaged 
    opened by Daverball 1
  • SQLAlchemy integration fails to parse version `2.0.0rc1`

    SQLAlchemy integration fails to parse version `2.0.0rc1`

    How do you use Sentry?

    Sentry Saas (sentry.io)

    Version

    1.12.1

    Steps to Reproduce

    Call sentry_sdk.init() with SQLAlchemy integration and install SQLAlchemy==2.0.0rc1.

    Expected Result

    no error

    Actual Result

          @staticmethod
          def setup_once():
              # type: () -> None
          
              try:
                  version = tuple(map(int, SQLALCHEMY_VERSION.split("b")[0].split(".")))
              except (TypeError, ValueError):
      >           raise DidNotEnable(
                      "Unparsable SQLAlchemy version: {}".format(SQLALCHEMY_VERSION)
                  )
      E           sentry_sdk.integrations.DidNotEnable: Unparsable SQLAlchemy version: 2.0.0rc1
    
    Status: Untriaged 
    opened by peterschutt 0
  • feat(integrations): Add method and path pattern transaction style for the Django integration

    feat(integrations): Add method and path pattern transaction style for the Django integration

    The method and path pattern for transaction styles includes the HTTP method as well as request path. This new transaction style for Django allows events to be grouped by this segmentation.

    opened by rynmlng 0
Releases(1.12.1)
Owner
Sentry
Real-time crash reporting for your web apps, mobile apps, and games.
Sentry
Django Simple Spam Blocker is blocking spam by regular expression.

Django Simple Spam Blocker is blocking spam by regular expression.

Masahiko Okada 23 Nov 29, 2022
A middleware to log the requests and responses using loguru.

Django Loguru The extension was based on another one and added some extra flavours. One of the biggest problems with the apps is the logging and that

Tiago Silva 9 Oct 11, 2022
DCM is a set of tools that helps you to keep your data in your Django Models consistent.

Django Consistency Model DCM is a set of tools that helps you to keep your data in your Django Models consistent. Motivation You have a lot of legacy

Occipital 59 Dec 21, 2022
Website desenvolvido em Django para gerenciamento e upload de arquivos (.pdf).

Website para Gerenciamento de Arquivos Features Esta Ć© uma aplicaĆ§Ć£o full stack web construĆ­da para desenvolver habilidades com o framework Django. O

Alinne Grazielle 8 Sep 22, 2022
Extensions for using Rich with Django.

django-rich Extensions for using Rich with Django. Requirements Python 3.6 to 3.10 supported. Django 2.2 to 4.0 supported. Are your tests slow? Check

Adam Johnson 88 Dec 26, 2022
A handy tool for generating Django-based backend projects without coding. On the other hand, it is a code generator of the Django framework.

Django Sage Painless The django-sage-painless is a valuable package based on Django Web Framework & Django Rest Framework for high-level and rapid web

sageteam 51 Sep 15, 2022
Reusable, generic mixins for Django

django-braces Mixins for Django's class-based views. Documentation Read The Docs Installation Install from PyPI with pip: pip install django-braces Bu

Brack3t 1.9k Jan 05, 2023
AUES Student Management System Developed for laboratory works ā„–9 Purpose using Python (Django).

AUES Student Management System (L M S ) AUES Student Management System Developed for laboratory works ā„–9 Purpose using Python (Django). I've created t

ANAS NABIL 2 Dec 06, 2021
Dashboad Full Stack utilizando o Django.

Dashboard FullStack completa Projeto finalizado | InformaƧƵes Cadastro de cliente Menu interatico mostrando quantidade de pessoas bloqueadas, liberada

Lucas Silva 1 Dec 15, 2021
Pinax is an open-source platform built on the Django Web Framework.

Symposion Pinax Pinax is an open-source platform built on the Django Web Framework. It is an ecosystem of reusable Django apps, themes, and starter pr

Pinax Project 295 Mar 20, 2022
A music recommendation REST API which makes a machine learning algorithm work with the Django REST Framework

music-recommender-rest-api A music recommendation REST API which makes a machine learning algorithm work with the Django REST Framework How it works T

The Reaper 1 Sep 28, 2021
A simple plugin to attach a debugger in Django on runserver command.

django-debugger A simple plugin to attach a debugger in Django during runserver Installation pip install django-debugger Usage Prepend django_debugger

Sajal Shrestha 11 Nov 15, 2021
Quick example of a todo list application using Django and HTMX

django-htmx-todo-list Quick example of a todo list application using Django and HTMX Background Modified & expanded from https://github.com/jaredlockh

Jack Linke 54 Dec 10, 2022
A Django web application that allows you to be in the loop about everything happening in your neighborhood.

A Django web application that allows you to be in the loop about everything happening in your neighborhood. From contact information of different handyman to meeting announcements or even alerts.

Kennedy Ngugi Mwaura 3 Dec 11, 2022
Yummy Django API, it's the exclusive API used for the e-yummy-ke vue web app

Yummy Django API, it's the exclusive API used for the e-yummy-ke vue web app

Am.Chris_KE 1 Feb 14, 2022
:couple: Multi-user accounts for Django projects

django-organizations Summary Groups and multi-user account management Author Ben Lopatin (http://benlopatin.com / https://wellfire.co) Status Separate

Ben Lopatin 1.1k Jan 01, 2023
Django model mixins and utilities.

django-model-utils Django model mixins and utilities. django-model-utils supports Django 2.2+. This app is available on PyPI. Getting Help Documentati

Jazzband 2.4k Jan 04, 2023
Twitter Bootstrap for Django Form

Django bootstrap form Twitter Bootstrap for Django Form. A simple Django template tag to work with Bootstrap Installation Install django-bootstrap-for

tzangms 557 Oct 19, 2022
A Django app to initialize Sentry client for your Django applications

Dj_sentry This Django application intialize Sentry SDK to your Django application. How to install You can install this packaging by using: pip install

Gandi 1 Dec 09, 2021
Pipeline is an asset packaging library for Django.

Pipeline Pipeline is an asset packaging library for Django, providing both CSS and JavaScript concatenation and compression, built-in JavaScript templ

Jazzband 1.4k Jan 03, 2023