celery.utils.log.ProcessAwareLoggerobject 在 logging.Logger.manager.loggerDict 中做啥

Posted

技术标签:

【中文标题】celery.utils.log.ProcessAwareLoggerobject 在 logging.Logger.manager.loggerDict 中做啥【英文标题】:What is celery.utils.log.ProcessAwareLoggerobject doing in logging.Logger.manager.loggerDictcelery.utils.log.ProcessAwareLoggerobject 在 logging.Logger.manager.loggerDict 中做什么 【发布时间】:2016-05-25 07:14:47 【问题描述】:

我正在通过以下方式检查 logging.Logger.manager.loggerDict:

import logging
logging.Logger.manager.loggerDict

而字典如下:


  'nose.case': <celery.utils.log.ProcessAwareLoggerobjectat0x112c8dcd0>,
  'apps.friends': <logging.PlaceHolderobjectat0x1147720d0>,
  'oauthlib.oauth2.rfc6749.grant_types.client_credentials': <celery.utils.log.ProcessAwareLoggerobjectat0x115c48710>,
  'apps.adapter.views': <celery.utils.log.ProcessAwareLoggerobjectat0x116a847d0>,
  'apps.accounts.views': <celery.utils.log.ProcessAwareLoggerobjectat0x116976990>,

  
  There are more but I truncated it

我的问题是:

    为什么 celery 会参与各种其他非 celery 应用的日志记录?是因为日志记录是以异步方式完成的,并且日志记录框架以某种方式检测到 celery 的存在并使用它吗? 对于我自己的两个使用 logger = logging.getLogger(__name__) 记录的文件,我看到一个是 PlaceHolderObject,另外两个是 celery.utils.log.ProcessAwareLogger 对象 - 尽管后两个在视图中而不是在 celery 进程中调用。后来怎么变成这样了

谢谢

【问题讨论】:

【参考方案1】:

Celery 本身使用 logging.setLoggerClass 方法替换(全局)记录器类,并使用 ProcessAwareLogger 类做几件事:避免在信号处理程序中尝试记录,并在日志中添加进程名称.一旦设置了 Celery 的日志记录系统,就会发生这种情况。由于setLoggerClass 的全球性质,您甚至可以在自己的记录器上看到此类。

至于为什么 Celery 是这样设计的,我想你得问问 Celery 的开发人员,但实际上它允许 Celery 确保即使你使用了信号处理程序的安全性和进程名称也得到了照顾在您的应用中使用您自己的记录器。

pythonlogging 文档说明:

如果您使用信号模块实现异步信号处理程序,您可能无法在此类处理程序中使用日志记录。这是因为线程模块中的锁实现并不总是可重入的,因此不能从此类信号处理程序中调用。

Celery 使用signal,因此这可能是希望全局强制执行其记录器类的原因。

【讨论】:

我对ProcessAwareLogger困惑了很长时间,感谢您的解释。

以上是关于celery.utils.log.ProcessAwareLoggerobject 在 logging.Logger.manager.loggerDict 中做啥的主要内容,如果未能解决你的问题,请参考以下文章