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



我的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。但是,如果我去掉错误日志的符号链接,两个日志都会消失。就好像StreamHandler正在输出到dev/stderr,尽管我已经在StreamHandler中将其声明为sys.stdout。我也尝试过删除"stream=",但这并没有解决任何问题。我一直在翻阅所有的文档,似乎不知道如何解决这个问题。

我还在环境变量中设置了PYTHONUNBUFFERED=0

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

烧瓶连接一个"默认";流处理程序已连接到应用程序记录器。因此,在你连接你的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 = []

最新更新