Python-Celery Log



我使用烧瓶,python 3.x and Celery4 (总计8个工人)

我想用'rotatingfilehandler'进行日志文件,如果文件大小结束了。

在第一个日志文件中正常工作。(其中包括所有工人日志,Poolworker-1〜Poolworker-8)

-rw-rw-r-- 1 sj sj   1048530  9월 18 10:01 celery_20170918.log (All worker's log)

但是,当文件大小结束后,工人在分开的文件上写日志。

-rw-rw-r-- 1 sj sj    223125  9월 18 10:47 celery_20170918.log  (All worker's log except below 2, 5, 6))
-rw-rw-r-- 1 sj sj     43785  9월 18 10:47 celery_20170918.log.1 (only PoolWorker-2 log)
-rw-rw-r-- 1 sj sj     46095  9월 18 10:47 celery_20170918.log.2 (only PoolWorker-5 log)
-rw-rw-r-- 1 sj sj     45990  9월 18 10:47 celery_20170918.log.3 (only PoolWorker-6 log)
-rw-rw-r-- 1 sj sj   1048530  9월 18 10:01 celery_20170918.log.4 (Log file made at first is changed to this.)

我不知道该规则是什么,它们有任何重复的日志。!!!

我的芹菜记录仪如下。

tasks.py

logger = get_task_logger('tasks')
logger.setLevel("INFO")
filename = './log/celery/celery_task.log'
formatter = Formatter('%(levelname)s-%(asctime)s %(processName)s %(funcName)s():%(lineno)d %(message)s')
# FileSize rotating
fileMaxByte = 1024 * 1024 * 1  # 30MB
fileHandler = logging.handlers.RotatingFileHandler(filename, maxBytes=fileMaxByte, backupCount=100)
fileHandler.setFormatter(formatter)
logger.addHandler(fileHandler)
@celery.task(...options...)
def test_call(self):
    logger.info("LOG TEST")

test.py

if __name__ == '__main__':
    test_call.apply_async()

怎么了?

RotatingFileHandler在日志文件滚动时多流程之间不保持原子。

在多进程环境中,进程A参见在日志文件c.log上到达的maxBytes,对c.log.1进行文件命名,然后将一些日志行写入新创建的c.log

但与此同时,另一个过程B仍然可以持有c.log的句柄,因为用于检查文件大小的方式基于文件句柄的末端偏移,它也可以看到到达maxBytes,想做文件卷由于用来翻滚的方式是在磁盘上重命名文件,因此此过程尝试将c.log重命名为c.log.1,但是随着c.log.1的存在,将其重命名为c.log.2

由于还有其他过程, c.log.3在上面又可以创建。

使用外部记录机制可以很好地解决此问题,或者您可以包装自己的原子文件旋转记录处理程序。

相关内容

  • 没有找到相关文章

最新更新