日志翻转时的主管异常导致应用服务器冻结?

时间:2014-03-01 19:08:35

标签: python logging flask gunicorn supervisord

我在EC2服务器上运行带有gunicorn的烧瓶应用程序。我使用supervisord来监控和重启应用服务器。昨天,服务器没有响应http请求。我们使用supervisorctl查看了状态,它显示为正在运行。我们查看了主管日志,发现了以下错误:

CRIT uncaptured python exception, closing channel <POutputDispatcher at 34738328
for <Subprocess at 34314576 with name flask in state RUNNING> (stdout)>
(<type 'exceptions.OSError'>:[Errno 2] No such file or directory

[/usr/local/lib/python2.7/dist-packages/supervisor/supervisord.py|runforever|233] 
[/usr/local/lib/python2.7/dist-packages/supervisor/dispatchers.py|handle_read_event|231] 
[/usr/local/lib/python2.7/dist-packages/supervisor/dispatchers.py|record_output|165] 
[/usr/local/lib/python2.7/dist-packages/supervisor/dispatchers.py|_log|141]
[/usr/local/lib/python2.7/dist-packages/supervisor/loggers.py|info|273] 
[/usr/local/lib/python2.7/dist-packages/supervisor/loggers.py|log|291] 
[/usr/local/lib/python2.7/dist-packages/supervisor/loggers.py|emit|186]
[/usr/local/lib/python2.7/dist-packages/supervisor/loggers.py|doRollover|220])

重新启动supervisord为我们解决了问题。以下是我们的主管配置的相关部分:

[supervisord]
childlogdir = /var/log/supervisord/
logfile = /var/log/supervisord/supervisord.log
logfile_maxbytes = 50MB
logfile_backups = 10
loglevel = info
pidfile = /var/log/supervisord/supervisord.pid
umask = 022
nodaemon = false
nocleanup = false

[program:flask]
directory=%(here)s
environment=PATH="/home/ubuntu/.virtualenvs/flask/bin"
command=newrelic-admin run-program gunicorn app:app -c gunicorn_conf.py
autostart=true
autorestart=true
redirect_stderr=true

奇怪的是,我们有两个服务器在ELB后面运行,并且两个服务器相同的问题相隔10分钟。我猜两个日志大约在同一时间达到了极限(这是可能的,因为它们都看到了相同的流量)并且翻转失败。关于为什么会发生这种情况的任何想法?

2 个答案:

答案 0 :(得分:2)

AFAIK supervisor使用自己的日志记录实现,而不是Python stdlib中的日志实现 - 尽管类和方法名称非常相似。

在翻转期间删除文件时存在潜在的竞争条件 - 您需要检查特定supervisor版本的源代码,并将其与最新的supervisor版本进行比较(如果不同)。以下是我系统上supervisor代码的摘录(在doRollover()方法中):

try:
    os.remove(dfn)
except OSError, why:
    # catch race condition (already deleted)
    if why[0] != errno.ENOENT:
        raise

如果您的翻转代码不能执行此操作,则可能需要升级supervisor版本。

更新:如果重命名时发生错误,则可能是尚未捕获的竞争条件。考虑询问the supervisor mailing list

答案 1 :(得分:0)

在主管部分(例如:[program:flask])中,您需要设置:

stdout_logfile_maxbytes=0
stderr_logfile_maxbytes=0