Flask日志仅输出至控制台无法写入文件,求问题排查方案
先把你的场景再理一遍:
我用以下代码配置Flask的RotatingFileHandler日志:
from logging.handlers import RotatingFileHandler from logging import ERROR, Formatter from flask.logging import default_handler database.init_db() handler = RotatingFileHandler("logs/log.txt", maxBytes=10000, backupCount=10) handler.setLevel(ERROR) handler.setFormatter(Formatter('%(asctime)s %(levelname)s: %(message)s')) app.logger.removeHandler(default_handler) app.logger.addHandler(handler) app.run()
在其他模块里这样记录日志:
from main import app try: # 业务代码 except Exception as e: app.logger.error(e)
现在日志能正常输出到控制台,但就是写不进项目目录下logs文件夹里的log.txt(已经把文件权限设成777了),到底哪里操作有误?
几个大概率的排查方向,我帮你捋一捋:
先确认
logs文件夹是否存在
RotatingFileHandler不会自动创建不存在的文件夹!这是个很容易忽略的坑,我之前也栽过。如果项目根目录下没有logs目录,程序不会抛出异常,但就是写不了日志。解决办法很简单:import os # 在初始化handler前创建文件夹 if not os.path.exists('logs'): os.makedirs('logs')相对路径的坑:工作目录≠项目目录
你用的logs/log.txt是相对路径,这个路径是相对于你运行程序时的工作目录,而不是你的项目根目录。比如如果你在项目文件夹外面执行python your_project/main.py,程序会在当前工作目录下找logs,而不是项目里的logs。
解决办法是用绝对路径,确保路径永远正确:import os # 获取当前脚本所在目录的绝对路径(也就是项目根目录) BASE_DIR = os.path.dirname(os.path.abspath(__file__)) # 拼接日志文件的绝对路径 log_file_path = os.path.join(BASE_DIR, 'logs', 'log.txt') handler = RotatingFileHandler(log_file_path, maxBytes=10000, backupCount=10)确认Flask logger的级别是否足够
你给handler设置了ERROR级别,但app.logger本身的默认级别是WARNING,理论上ERROR级别的日志是能通过的,但保险起见可以手动设置app.logger的级别,避免被过滤:app.logger.setLevel(ERROR)再检查文件夹的权限
虽然你说log.txt的权限是777,但logs文件夹的权限呢?如果文件夹没有写入权限,就算文件权限够也白搭。可以用ls -ld logs(Linux/macOS)查看文件夹权限,确保运行程序的用户有读写权限。关于移除default_handler的小提醒
你移除了默认的控制台handler,但你说日志还能输出到控制台,说明可能你后续又添加了其他控制台handler?不过这个不影响文件写入,只是顺带提一句,如果之后控制台日志消失了,可以排查这块。
内容的提问来源于stack exchange,提问作者AlexSheffer

