我正在检查logging.Logger.manager.loggerDict:
import logging
logging.Logger.manager.loggerDict
和dict如下:
{
'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
我的问题是:
logger = logging.getLogger(__name__)
进行日志记录的两个文件,我看到一个是PlaceHolderObject,另外两个是celery.utils.log.ProcessAwareLogger对象 - 虽然后两个在视图中调用而不是在芹菜中调用流程。那是怎么变成这种方式的由于
答案 0 :(得分:7)
Celery本身使用logging.setLoggerClass
方法替换(全局)记录器类,并使用ProcessAwareLogger
类执行以下操作:避免尝试在信号处理程序中记录,并添加进程名称到日志。只要Celery的日志系统设置完毕,就会发生这种情况。由于setLoggerClass
的全球性,你甚至可以在自己的记录器上看到这个课程。
至于为什么,Celery就是这样设计的,我认为你必须要问Celery的开发者,但实际上它允许Celery确保即使你使用信号处理程序的安全性和工艺名称也能得到照顾你自己的应用程序中的记录器。
python logging
文档说明:
如果使用信号模块实现异步信号处理程序,则可能无法在此类处理程序中使用日志记录。这是因为线程模块中的锁实现并不总是可重入的,因此无法从这些信号处理程序中调用。
Celery使用signal
因此这可能是想要全局强制执行其记录器类的原因。