getsentry / getsentry/sentry-python

Performance tracing does not work with Sanic integration if AppFactory is used

未关闭
#2,902 2 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
Improvement Integration: Sanic Python Quality Improvement Spans
主要语言
Python
星标
2.2k
派生
669
平均合并
1 天 1 小时
30 天内合并 PR
213

描述

### How do you use Sentry?

Self-hosted/on-premise

### Version

1.43.0

### Steps to Reproduce

When using Sanic with a dynamic application as mentioned on https://sanic.dev/en/guide/running/app-loader.html the performance tracing doesn't work. The patched _startup method is never called in this case, so the corresponding signals aren't set up.

For instance:

```
import argparse
import asyncio

import sentry_sdk
from sanic import Sanic
from sanic.log import logger
from sanic.worker.loader import AppLoader
from sentry_sdk.integrations.asyncio import AsyncioIntegration
from sentry_sdk.integrations.sanic import SanicIntegration

def create_app() -> Sanic:
"""Create a Sanic application."""
app = Sanic("app")

@app.listener("before_server_start")
async def setup_sentry(_):
sentry_sdk.init(
dsn=config.sentry.dsn,
environment=config.sentry.environment,
integrations=[AsyncioIntegration(), SanicIntegration(unsampled_statuses={404, 403, 401})],
enable_tracing=config.sentry.sample_rate > 0,
traces_sample_rate=config.sentry.sample_rate,
before_send=filter_error,
)

app = register_all_handlers(app, config)

return app

if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-H", "--host", default="0.0.0.0", help="Host to listen on")
parser.add_argument("-p", "--port", default=8000, type=int, help="Port to listen on")
args = vars(parser.parse_args())
loader = AppLoader(factory=create_app)
app = loader.load()
app.prepare(**args)
Sanic.serve(primary=app, app_loader=loader)
```
this will still log exceptions but the _startup method in the sanic integration is never called, nor are any of the hub_enter, hub_exit or set_transaction methods. (I left out the register_all_handlers method which just registers our endpoints)
A workaround is to set the signals in sanic manually, e.g.

```
import argparse
import asyncio

import sentry_sdk
from sanic import Sanic
from sanic.log import logger
from sanic.worker.loader import AppLoader
from sentry_sdk.integrations.asyncio import AsyncioIntegration
from sentry_sdk.integrations.sanic import SanicIntegration, _hub_enter, _hub_exit, _set_transaction

def create_app() -> Sanic:
"""Create a Sanic application."""
app = Sanic("app")

@app.listener("before_server_start")
async def setup_sentry(_):
sentry_sdk.init(
dsn=config.sentry.dsn,
environment=config.sentry.environment,
integrations=[AsyncioIntegration(), SanicIntegration(unsampled_statuses={404, 403, 401})],
enable_tracing=config.sentry.sample_rate > 0,
traces_sample_rate=config.sentry.sample_rate,
before_send=filter_error,
)

# we manually need to set the signals because sentry sanic integration doesn't work with using
# an app factory
app.signal("http.lifecycle.request")(_hub_enter)
app.signal("http.lifecycle.response")(_hub_exit)
app.signal("http.routing.after")(_set_transaction)

app = register_all_handlers(app, config)

return app

if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-H", "--host", default="0.0.0.0", help="Host to listen on")
parser.add_argument("-p", "--port", default=8000, type=int, help="Port to listen on")
args = vars(parser.parse_args())
loader = AppLoader(factory=create_app)
app = loader.load()
app.prepare(**args)
Sanic.serve(primary=app, app_loader=loader)
```
which logs performance tracing as expected.

### Expected Result

Peformance traces to show up in sentry

### Actual Result

No performance traces are logged

贡献指南

打开贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。