前言
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參數來指定;