由于我们很多统计和备份的任务,所以单独使用celery来做这些耗时或者需要定时处理的工作,但是在使用的过程中出现一些问题,就是发现日志中打印的celery相关的日志时会多次打印同样的信息,次数和我的flask和celery进程数量能够对应上,所以解决这个问题的同时也顺便记录下,方便后续使用。
问题现象如下
在应用工厂中我目前的日志配置如下
#日志配置
def configure_logger(app):
if not os.path.exists(app.config["LOG_PATH"]):
os.makedirs(app.config["LOG_PATH"], mode=0o777)
log_level = logging.INFO
log_file_path = app.config["LOG_PATH"] + os.sep + "blog.log"
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(filename)s - %(funcName)s - %(lineno)s - %(message)s')
handler = TimedRotatingFileHandler(log_file_path, when="midnight", interval=1, backupCount=15,encoding="UTF-8")
handler.setLevel(log_level)
handler.setFormatter(formatter)
app.logger.addHandler(handler)
需要对上述代码进行改造,主要创建添加一个日志过滤器来让进程感知过滤器,改造代码如下
#日志过滤器
class ProcessFilter(logging.Filter):
def filter(self, record):
record.process_id = os.getpid()
return True
#日志配置
def configure_logger(app):
if not os.path.exists(app.config["LOG_PATH"]):
os.makedirs(app.config["LOG_PATH"], mode=0o777)
log_level = logging.INFO
log_file_path = app.config["LOG_PATH"] + os.sep + "blog.log"
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(filename)s - %(funcName)s - %(lineno)s - %(message)s')
handler = TimedRotatingFileHandler(log_file_path, when="midnight", interval=1, backupCount=15,encoding="UTF-8")
handler.setLevel(log_level)
handler.setFormatter(formatter)
#添加进程过滤器,防止进程重复
process_filter = ProcessFilter()
handler.addFilter(process_filter)
app.logger.handlers.clear()
app.logger.addHandler(handler)
app.logger.setLevel(log_level)
根据上述修改以后日志就不会再次输出多次同样的日志了。
还有另外一种处理方式,就是flask和celery使用不同的日志文件,下面方法查到的,但是还没实践过,先记录,后面可能用的上
ef configure_logger(app):
if not os.path.exists(app.config["LOG_PATH"]):
os.makedirs(app.config["LOG_PATH"], mode=0o777)
# 获取进程标识
process_type = os.environ.get('PROCESS_TYPE', 'flask')
process_id = os.getpid()
# 为不同进程类型创建不同的日志文件
if process_type == 'celery':
log_file_name = f"celery_{process_id}.log"
else:
log_file_name = f"flask_{process_id}.log"
log_file_path = os.path.join(app.config["LOG_PATH"], log_file_name)
log_level = logging.INFO
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(filename)s - %(funcName)s - %(lineno)s - %(message)s')
handler = TimedRotatingFileHandler(
log_file_path,
when="midnight",
interval=1,
backupCount=15,
encoding="UTF-8"
)
handler.setLevel(log_level)
handler.setFormatter(formatter)
# 清除可能存在的其他处理器
app.logger.handlers.clear()
app.logger.addHandler(handler)
app.logger.setLevel(log_level)
这种方式就是用设置进程类型,然后根据不同的进程类型将日志写入不同的日志文件中。
内容版权声明:除非注明,否则皆为本站原创文章。
转载注明出处:https://sulao.cn/post/1126
评论列表