文件描述符不会更新以登录 Django
File descriptor doesn't update for logging in Django
我们使用 Python(2.7)/Django(1.8.1) 和 Gunicorn(19.4.5) 作为我们的 Web 应用程序,并使用 supervisor(3.0) 来监控它。我最近在日志记录中遇到了 2 个问题:
- Django 正在登录前一天的日志(我们启用了日志轮换)
- Django 根本没有记录任何内容。
第一种情况是可以理解的,日志轮换更改了文件但 Django 没有更新。
第二种情况在我重新启动主管进程时得到解决。这让我再次相信文件描述符没有在 django 进程中更新。
我是通过这个 来的,其中指出:
Each child is an independent process, and file handles in the parent
may be closed in the child after a fork (assuming POSIX). In any case,
logging to the same file from multiple processes is not supported.
所以我有几个问题:
我的 gunicorn 有 4 个子进程,如果其中一个失败
写入日志文件,其他子进程将无法写入
用它?以及如何调试这些场景?
我个人发现 python 日志模块中的调试错误是
难的。有一点可以指出如何调试这样的错误吗?
有什么办法可以让猴子补丁日志记录不静默失败?*(Kindly read update section)*
我已经看到 Django LogRotation 导致问题类型 1 如上所述,而不是通过 cron 计划的某些脚本。那么什么是更好的呢?
注意:日志配置没有问题。我已经花了相当多的时间试图弄清楚这一点。此外,如果配置是问题所在,Django 将不会在进程重启后写入日志文件。
更新:
对于我的第二个问题,我看到日志记录模块提供了一个在失败时引发异常的选项,尽管这在生产环境中是不鼓励的。 Documentation here。所以现在我的问题变成了如何在 Django 中设置它?
我想结束这个问题。 2 个月后有点尴尬,看起来很愚蠢。但我想愚蠢是学习的一部分,希望这可以作为偶然发现这一点的人的参考。
场景 1:使用 TimedRotatingFileHandler
的 Django 似乎有时不会更新文件描述符,因此除非我们重新启动主管,否则会写入旧日志文件。我们尚未找到此行为的原因,如果找到则更新原因。现在我们正在使用 WatchedFileHandler
,然后使用 logrotate
实用程序来轮换日志。
场景 2:这是个愚蠢的问题。当我使用一些字符串格式进行记录时,我忘记提供足够的变量,这就是记录器出错的原因。但这并没有得到传播。但是当我在本地进行测试时,我发现日志记录模块实际上是在默默地抛出该错误,并且模块中它之后的任何日志都没有被打印出来。从这种情况中吸取的教训是:
- 如果日志记录有问题,看看字符串格式是否有误
- 使用 python 的
log.debug('example: {msg}'.format(msg=msg))
而不是 log.debug('example: %s', msg)
。
我们使用 Python(2.7)/Django(1.8.1) 和 Gunicorn(19.4.5) 作为我们的 Web 应用程序,并使用 supervisor(3.0) 来监控它。我最近在日志记录中遇到了 2 个问题:
- Django 正在登录前一天的日志(我们启用了日志轮换)
- Django 根本没有记录任何内容。
第一种情况是可以理解的,日志轮换更改了文件但 Django 没有更新。
第二种情况在我重新启动主管进程时得到解决。这让我再次相信文件描述符没有在 django 进程中更新。
我是通过这个
Each child is an independent process, and file handles in the parent may be closed in the child after a fork (assuming POSIX). In any case, logging to the same file from multiple processes is not supported.
所以我有几个问题:
我的 gunicorn 有 4 个子进程,如果其中一个失败 写入日志文件,其他子进程将无法写入 用它?以及如何调试这些场景?
我个人发现 python 日志模块中的调试错误是 难的。有一点可以指出如何调试这样的错误吗? 有什么办法可以让猴子补丁日志记录不静默失败?
*(Kindly read update section)*
我已经看到 Django LogRotation 导致问题类型 1 如上所述,而不是通过 cron 计划的某些脚本。那么什么是更好的呢?
注意:日志配置没有问题。我已经花了相当多的时间试图弄清楚这一点。此外,如果配置是问题所在,Django 将不会在进程重启后写入日志文件。
更新:
对于我的第二个问题,我看到日志记录模块提供了一个在失败时引发异常的选项,尽管这在生产环境中是不鼓励的。 Documentation here。所以现在我的问题变成了如何在 Django 中设置它?
我想结束这个问题。 2 个月后有点尴尬,看起来很愚蠢。但我想愚蠢是学习的一部分,希望这可以作为偶然发现这一点的人的参考。
场景 1:使用 TimedRotatingFileHandler
的 Django 似乎有时不会更新文件描述符,因此除非我们重新启动主管,否则会写入旧日志文件。我们尚未找到此行为的原因,如果找到则更新原因。现在我们正在使用 WatchedFileHandler
,然后使用 logrotate
实用程序来轮换日志。
场景 2:这是个愚蠢的问题。当我使用一些字符串格式进行记录时,我忘记提供足够的变量,这就是记录器出错的原因。但这并没有得到传播。但是当我在本地进行测试时,我发现日志记录模块实际上是在默默地抛出该错误,并且模块中它之后的任何日志都没有被打印出来。从这种情况中吸取的教训是:
- 如果日志记录有问题,看看字符串格式是否有误
- 使用 python 的
log.debug('example: {msg}'.format(msg=msg))
而不是log.debug('example: %s', msg)
。