前言
python有默认的日志配置,可是对于业务开发来讲通常须要配置本身的日志输出方式,同时各类框架也继承了日志相关的内容。下面记录一下celery和flask框架中自带的logger使用方法。html
flask使用logger
flask中的app对象自带了logger方法,其本质上是在python内置的logging模块上进行封装使用,其调用的方式为:python
from flask import current_app current_app.logger.error('this is a error') current_app.logger.info('this is a info') current_app.logger.warning('this is a wraning') current_app.logger.debug('this is a debug')
配置方法
日志的配置方法有多种,和python配置日志的方式是同样的。flask
可参考:python日志配置loggerapp
- 经过字典配置
#logging.py logger_dict = { 'version': 1, # 该配置写法固定 'formatters': { # 设置输出格式 'default': {'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',} }, # 设置处理器 'handlers': { 'wsgi': { 'class': 'logging.StreamHandler', 'stream': 'ext://sys.stdout', 'formatter': 'default', 'level': 'DEBUG' }}, # 设置root日志对象配置 'root': { 'level': 'INFO', 'handlers': ['wsgi'] }, # 设置其余日志对象配置 'loggers': { 'test': {'level': 'DEBUG', 'handlers':['wsgi'], 'propagate':0} } }
- 源码分析
flask的logger其实也是经过python的logging模块建立logger对象获得的,源码为:框架
# logging.py from logging import getLogger, getLoggerClass def create_logger(app): ... # 建立一个调试模式下的日志处理器,级别为debug debug_handler = DebugHandler() debug_handler.setLevel(DEBUG) debug_handler.setFormatter(Formatter(DEBUG_LOG_FORMAT)) # 建立一个运行过程的日志处理器,级别为error prod_handler = ProductionHandler(_proxy_stream) prod_handler.setLevel(ERROR) prod_handler.setFormatter(Formatter(PROD_LOG_FORMAT)) # 获取应用的名字,即app = Flask(app.name)传入的参数名,而后建立一个logger对象 logger = getLogger(app.logger_name) # 先清空之前全部的处理器 del logger.handlers[:] logger.__class__ = DebugLogger # 加入新的处理器 logger.addHandler(debug_handler) logger.addHandler(prod_handler) # 默认状况下不继承 logger.propagate = False return logger
当程序调用current_app.logger时,会获得create_logger函数返回的logger对象,若是咱们开启的是调试模式,会使用debug_handler处理器;若是是非调试模式使用的是ProductionHandler处理器,日志的输出格式为:ide
# 调试模式格式 DEBUG_LOG_FORMAT = ( '-' * 80 + '\n' + '%(levelname)s in %(module)s [%(pathname)s:%(lineno)d]:\n' + '%(message)s\n' + '-' * 80 ) # 非调试模式格式 PROD_LOG_FORMAT = '[%(asctime)s] %(levelname)s in %(module)s: %(message)s'
此外咱们开发程序时能够看到除了咱们调用current_app.logger产生的日志信息外,还有flask默认的日志信息,这个默认的日志输出咱们是能够经过配置日志文件来修改的,可是current_app.logger产生的日志信息的格式是固定的,若是不知足咱们的要求的话就须要手动建立logger对象来使用。函数
细节
咱们加载日志文件的时候应该尽量的早,避免在调用过一次app.logger以后才加载日志配置,因此最好在app被建立以前就加载日志配置文件。源码分析
# app.py logging.config.fileConfig(Config.FILEPATH) app = Flask(__name__)
在celery中使用logger
celery也封装了logger使用方法:ui
from celery.utils.log import get_task_logger # 建立一个logger对象 logger = get_task_logger('name')
celery的logger调用的仍然是logging模块的logger.this
# get_task_logger函数调用了get_logger函数 # 传入一个字符串获取一个logger对象 def get_logger(logger): """Get logger by name.""" # 判断该参数是否是字符串,是就获取一个logger对象 if isinstance(logger, string_t): logger = logging.getLogger(logger) # 没有处理器就添加NullHandler处理器 if not logger.handlers: logger.addHandler(logging.NullHandler()) return logger
- 其相关的配置能够在celery的配置文件中设置;
# 在4.0版本后改为了小写,可是原来的尚未弃用 CELERYD_HIJACK_ROOT_LOGGER :默认true,先前全部的logger的配置都会失效,能够经过设置false禁用定制本身的日志处理程序; CELERYD_LOG_COLOR :是否开启不一样级别的颜色标记,默认开启; CELERYD_LOG_FORMAT :设置celery全局的日志格式;默认格式:"[%(asctime)s: %(levelname)s/%(processName)s] %(message)s" CELERYD_TASK_LOG_FORMAT:设置任务日志格式,默认:"[%(asctime)s: %(levelname)s/%(processName)s [%(task_name)s(%(task_id)s)] %(message)s" CELERY_REDIRECT_STDOUTS:设置标准输入输出重定向到当前的处理器,默认为 true CELERY_REDIRECT_STDOUTS_LEVEL:设定标准输入输出重定向到当前的处理器日志的输出级别;即指定使用print()输出的是什么级别的日志记录;默认wraning;
注意:
-
因为celery的运行是独立的,在flask中定义的logger对象的配置在celery的程序中是失效的,必须使用get_task_logger建立logger;
-
指定celery日志的输出等级,经过启动时用--loglevel参数来指定;