关于这个主题有很多资源,但不幸的是没有一个有效。
1.以下是我的django日志设置:
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"default": {
"format": "[%(asctime)s: %(levelname)s/%(processName)s] [%(name)s] %(message)s"
}
},
"filters": {"require_debug_false": {"()": "django.utils.log.RequireDebugFalse"}},
"handlers": {
"console": {
"level": "INFO",
"class": "logging.StreamHandler",
"formatter": "default",
},
"mail_admins": {
"level": "ERROR",
"filters": ["require_debug_false"],
"class": "django.utils.log.AdminEmailHandler",
},
"my_custom_handler": {
"level": "INFO",
"class": "my_custom_handler_class",
},
},
"loggers": {
"django.request": {
"handlers": ["mail_admins"],
"level": "ERROR",
"propagate": True,
},
"": {
"handlers": ["console", "my_custom_handler"],
"level": "INFO",
"propagate": True,
"formatter": "default",
},
"celery": {
"handlers": ["console", "my_custom_handler"],
"level": "INFO",
"propagate": True,
},
},
字符串
}
- Celery是在导入www.example.com/初始化设置之前初始化的(这可能是罪魁祸首),我在celery任务中用于登录的记录器是base.py
第一个月
1.我尝试设置CELERYD_HIJACK_ROOT_LOGGER = False
,使用after_setup_task_logger信号(我尝试打印以查看该信号是否被调度,但它没有),它们都没有任何效果
1.我尝试使用setup_logging
,它可以工作:
@setup_logging.connect
def config_loggers(*args, **kwags):
my_handler = MyCustomHandler()
root_logger = logging.getLogger()
root_logger.addHandler(my_handler)
root_logger.level = logging.INFO
@worker_process_init.connect
def init_worker(**kwargs):
logger = get_task_logger(__name__) # or Logger.get_logger(__name__), no difference
logger.info("My log message")
型
我说它有点工作,只是因为当我在init_worker
中检查记录器对象的根时,我看到处理程序在那里,但它不在记录器的处理程序中,而且它似乎没有传播(即我没有看到日志消息)。只有当我直接将处理程序附加到记录器对象时,我才能看到消息,但很明显,这样做的问题是,每当我在新文件中声明一个记录器时,我都必须附加处理程序,这是没有意义的。
1条答案
按热度按时间c3frrgcw1#
如果你使用
prefork
的默认Celeryworker_pool
选项,那么如果你的自定义处理程序做了一些不“fork安全”的事情(比如启动一个线程),那么fork的worker子进程将不会像预期的那样运行。例如,
fluent-logger
提供了fluent.asynchandler.FluentHandler
,它创建了一个异步发送器来启动一个线程--如果这个线程已经在父进程celery中启动,那么分叉的子进程认为他们不需要启动一个线程,但实际上这个线程在分叉时被杀死了。这意味着任何来自子进程的日志记录都不会被发送,最终fluent-logger队列会满,要么被阻塞,要么被丢弃。
有关详细信息,请参阅本期。