StreamHandler-不记录到Docker容器中的sys.stdout-Python

时间:2018-12-06 20:03:54

标签: python apache docker logging

我的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

感谢您提供的任何帮助或指示。

1 个答案:

答案 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 = []