如何在ASGI Sanic中集成Prometheus Client?挂载方案遇异常求简便法
在Sanic中集成Prometheus监控指标的简便方案
你遇到的异常是因为Sanic作为子ASGI应用被Starlette挂载时,其内部事件循环的初始化逻辑与Starlette的启动流程不兼容,导致无法正确获取运行时的事件循环。下面是两种无需依赖Starlette的简便解决方案:
方案一:直接用Sanic挂载Prometheus ASGI应用
Sanic原生支持挂载ASGI应用,直接通过mount方法即可将Prometheus的监控服务挂到指定路径,代码示例:
from prometheus_client import make_asgi_app from sanic import Sanic from sanic.response import text app = Sanic("MyHelloWorldApp") @app.get("/") async def hello_world(request): return text("Hello, world.") # 创建Prometheus监控应用并挂载到/metrics路径 metrics_app = make_asgi_app() app.mount("/metrics", metrics_app) if __name__ == "__main__": app.run(host="127.0.0.1", port=8000, log_level="info")
启动后,访问http://127.0.0.1:8000/metrics即可获取Prometheus格式的监控指标,主应用的/路径也能正常响应,不会触发事件循环相关异常。
方案二:包装Sanic的ASGI入口
如果需要直接使用uvicorn运行ASGI应用,可以直接包装Sanic的ASGI实例,代码示例:
from prometheus_client import make_asgi_app from sanic import Sanic from sanic.response import text app = Sanic("MyHelloWorldApp") @app.get("/") async def hello_world(request): return text("Hello, world.") # 将Prometheus监控应用与Sanic的ASGI应用整合 app.asgi_app = make_asgi_app(app=app.asgi_app, path="/metrics") if __name__ == "__main__": import uvicorn uvicorn.run(app.asgi_app, host="127.0.0.1", port=8000, log_level="info")
这种写法适合以纯ASGI模式部署的场景,同样能实现监控指标的暴露和主应用的正常运行。
内容的提问来源于stack exchange,提问作者tulsluper
相关产品推荐
相关产品推荐

