我的Python应用程序中有一个RotatingFileHandler和StreamHandler。它正在docker容器中的apache服务器中运行。因此,我已经将apache访问和错误日志链接到/ dev / stdout上,如下所示:
RUN ln -sf /dev/stdout /project/Project_Service/log/access.log && \
ln -sf /dev/stdout /project/Project_Service/log/error.log
我将处理程序设置为:
app = Flask(__name__)
app.logger.setLevel(logging.DEBUG)
formatter = logging.Formatter(
"%(asctime)s - %(name)s - %(levelname)s - %(message)s")
file_handler = RotatingFileHandler(app_error,
maxBytes=1024 * 1024 * 100, backupCount=20)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)
stream_handler = logging.StreamHandler(stream=sys.stdout)
stream_handler.setLevel(logging.DEBUG)
stream_handler.setFormatter(formatter)
app.logger.addHandler(file_handler)
app.logger.addHandler(stream_handler)
app.logger.debug('DEBUG LOG')
app.logger.info('INFO LOG')
app.logger.warning('WARNING LOG')
app.logger.error('ERROR LOG')
app.logger.critical('CRITICAL LOG')
如果我查看app_error文件,则可以正确看到输出:
2018-12-06 19:37:46,863 - app - DEBUG - DEBUG LOG
2018-12-06 19:37:46,865 - app - INFO - INFO LOG
2018-12-06 19:37:46,865 - app - WARNING - WARNING LOG
2018-12-06 19:37:46,866 - app - ERROR - ERROR LOG
2018-12-06 19:37:46,868 - app - CRITICAL - CRITICAL LOG
这在docker日志中可以看到:
[Thu Dec 06 19:37:46.864764 2018] [:error] [pid 8] 2018-12-06 19:37:46,863 - app - DEBUG - DEBUG LOG
[Thu Dec 06 19:37:46.865872 2018] [:error] [pid 8] 2018-12-06 19:37:46,865 - app - INFO - INFO LOG
[Thu Dec 06 19:37:46.866116 2018] [:error] [pid 8] 2018-12-06 19:37:46,865 - app - WARNING - WARNING LOG
[Thu Dec 06 19:37:46.866370 2018] [:error] [pid 8] [2018-12-06 19:37:46,866] ERROR in app: ERROR LOG
[Thu Dec 06 19:37:46.868450 2018] [:error] [pid 8] 2018-12-06 19:37:46,866 - app - ERROR - ERROR LOG
[Thu Dec 06 19:37:46.870184 2018] [:error] [pid 8] [2018-12-06 19:37:46,868] CRITICAL in app: CRITICAL LOG
[Thu Dec 06 19:37:46.870448 2018] [:error] [pid 8] 2018-12-06 19:37:46,868 - app - CRITICAL - CRITICAL LOG
这很有意义,因为我同时拥有错误日志和流处理程序,该错误日志假定为ERROR和CRITICAL日志级别。但是,如果我取出错误日志的符号链接,则两个日志都会消失。即使我在StreamHandler中将其声明为sys.stdout,也好像StreamHandler正在输出到dev / stderr。我也尝试过删除“ stream =”,但这并不能解决任何问题。我一直在浏览所有文档,似乎无法弄清楚该如何解决。
我还在环境变量中设置了PYTHONUNBUFFERED=0
。
感谢您提供的任何帮助或指示。
答案 0 :(得分:0)
Flask已将“默认” StreamHandler附加到应用程序记录器。因此,在附加了2个记录器之后,实际上有3个记录器:
print(app.logger.handlers)
[<logging.StreamHandler object at 0x7ff30592b358>,
<logging.handlers.RotatingFileHandler object at 0x7ff3058e2e80>,
<logging.StreamHandler object at 0x7ff3058f33c8>]
这也解释了为什么两行具有不同的格式-它们来自具有自己的格式化程序的默认StreamHandler:
2018-12-06 19:37:46,863 - app - DEBUG - DEBUG LOG
2018-12-06 19:37:46,865 - app - INFO - INFO LOG
2018-12-06 19:37:46,865 - app - WARNING - WARNING LOG
[2018-12-06 19:37:46,866] ERROR in app: ERROR LOG # <----
2018-12-06 19:37:46,866 - app - ERROR - ERROR LOG
[2018-12-06 19:37:46,868] CRITICAL in app: CRITICAL LOG # <----
2018-12-06 19:37:46,868 - app - CRITICAL - CRITICAL LOG
解决方法是简单地在添加您的处理程序之前删除所有处理程序:
app.logger.handlers = []