FastAPI/Uvicorn集成Logtail外部日志工具无法正常工作?
问题分析与修复方案
核心问题点
- Logger类未绑定日志实例:
Logger类的__init__方法中创建的logger是局部变量,未赋值给self.log,导致后续调用info/error等方法时会触发AttributeError;同时__init__内的调试日志虽能执行,但可能被Uvicorn的日志配置覆盖。 - Uvicorn日志配置干扰:Uvicorn启动时会默认配置root logger,自定义日志默认开启传播机制,会被root logger的设置拦截,无法正常发送到Logtail。
- 启动日志执行时机错误:
uvicorn.run是阻塞调用,其后的logger.info语句永远不会被执行。
修复后的Logger类代码
# Logger.py from logtail import LogtailHandler import logging class Logger: def __init__(self): handler = LogtailHandler(source_token="XXXXXXX") # 使用固定名称的logger,避免模块名变化导致重复实例化 self.log = logging.getLogger("abe_logger") # 清空已存在的handler,防止重复添加(多次实例化Logger时生效) self.log.handlers = [] self.log.setLevel(logging.DEBUG) # 禁止向root logger传播日志,避免被Uvicorn配置干扰 self.log.propagate = False self.log.addHandler(handler) self.log.debug('I am using Logtail!') def info(self, message): self.log.info(message) def error(self, message): self.log.error(message) def debug(self, message): self.log.debug(message) def warning(self, message): self.log.warning(message) def critical(self, message): self.log.critical(message) def exception(self, message): self.log.exception(message)
修复后的启动文件代码
# __init__.py from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from abe.routes import main, bc_handler from abe.utils.logger import Logger logger = Logger() app = FastAPI(title="ABE-Backend", openapi_url="/openapi.json") app.include_router(main.router) app.include_router(bc_handler.router) # create tables # models.Base.metadata.create_all(bind=engine) origins = [ ] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) if __name__ == "__main__": # 先输出启动日志,再启动服务(uvicorn.run是阻塞调用) logger.info(f"Starting server on port 8000, with cors origins: {origins}") import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000, log_level="debug")
额外排查步骤
如果修复后仍无日志输出,可以:
- 核对
source_token是否正确有效(单独测试文件正常的话,该问题概率较低) - 添加控制台输出handler,验证日志是否正常生成:
在Logger类的__init__中添加以下代码:
若控制台能看到日志,说明问题出在LogtailHandler配置;若仍看不到,检查logger的级别设置是否正确。stream_handler = logging.StreamHandler() stream_handler.setLevel(logging.DEBUG) self.log.addHandler(stream_handler)
内容的提问来源于stack exchange,提问作者Oze
相关产品推荐
相关产品推荐

