Flask yaml配置logger及l(fā)ogger使用
tips:
Python logging模塊
- debug : 打印全部的日志,詳細(xì)的信息,通常只出現(xiàn)在診斷問(wèn)題上
- info : 打印info,warning,error,critical級(jí)別的日志,確認(rèn)一切按預(yù)期運(yùn)行
- warning : 打印warning,error,critical級(jí)別的日志,一個(gè)跡象表明,一些意想不到的事情發(fā)生了,或表明一些問(wèn)題在不久的將來(lái)(例如。磁盤空間低”),這個(gè)軟件還能按預(yù)期工作
- error : 打印error,critical級(jí)別的日志,更嚴(yán)重的問(wèn)題,軟件沒(méi)能執(zhí)行一些功能
- critical : 打印critical級(jí)別,一個(gè)嚴(yán)重的錯(cuò)誤,這表明程序本身可能無(wú)法繼續(xù)運(yùn)行
- 日志級(jí)別:CRITICAL >ERROR> WARNING > INFO> DEBUG> NOTSET
- logging日志設(shè)置以及使用
import logging
# 日志記錄最低輸出級(jí)別設(shè)置
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
# Logging記錄到文件
fh = logging.FileHandler("test.log", mode='w')
logger.addHandler(fh) # 將logger添加到handler里面
# Logging記錄格式以及設(shè)置
formatter = logging.Formatter("%(asctime)s - %(message)s") # 記錄時(shí)間和消息
fh.setFormatter(formatter) # 此處設(shè)置handler的輸出格式
# Logging使用
logger.info("this is info")
logger.debug("this is debug")
logger.warning("this is warning")
logging.error("this is error")
logger.critical("this is critical")
- 輸出test.log
2019-03-18 21:39:37,260 - this is info
2019-03-18 21:39:37,260 - this is debug
2019-03-18 21:39:37,260 - this is warning
2019-03-18 21:39:37,260 - this is error
2019-03-18 21:39:37,260 - this is critical
- 查看更多詳細(xì)信息
Flask自帶logger
Flask在0.3版本后就有了日志工具logger。
- Flask日志配置
- 日志工具簡(jiǎn)單使用:
from flask import Flask
app = Flask(__name__)
app.logger.debug('A value for debugging')
app.logger.warning('A warning occurred (%d apples)', 42)
app.logger.error('An error occurred')
if __name__ == "__main__":
app.run()
- 兩種不同的方式配置logger
import logging
from flask import Flask
app = Flask(__name__)
handler = logging.FileHandler(filename="test.log", encoding='utf-8')
handler.setLevel("DEBUG")
format_ ="%(asctime)s[%(name)s][%(levelname)s] :%(levelno)s: %(message)s"
formatter = logging.Formatter(format_)
handler.setFormatter(formatter)
app.logger.addHandler(handler)
if __name__ == "__main__":
app.run()
import logging
import logging.config
from flask import Flask
logger_conf ={
'version': 1,
'formatters': {'default': {
'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
}},
'handlers': {'wsgi': {
'class': 'logging.StreamHandler',
'stream': 'ext://flask.logging.wsgi_errors_stream',
'formatter': 'default'
}},
'root': {
'level': 'INFO',
'handlers': ['wsgi']
}
}
app = Flask(__name__)
logging.config.dictConfig(logger_conf)
if __name__ == "__main__":
app.run()
- 工廠模式下不同地方使用logger,請(qǐng)使用current_app.logger
import logging
import logging.config
from flask import current_app, Flask
logger_conf ={
'version': 1,
'formatters': {'default': {
'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
}},
'handlers': {'wsgi': {
'class': 'logging.StreamHandler',
'stream': 'ext://flask.logging.wsgi_errors_stream',
'formatter': 'default'
}},
'root': {
'level': 'INFO',
'handlers': ['wsgi']
}
}
def create_app():
app = Flask(__name__)
# 方法一日志設(shè)置
handler = logging.FileHandler(filename="test.log", encoding='utf-8')
handler.setLevel("DEBUG")
format_ ="%(asctime)s[%(name)s][%(levelname)s] :%(levelno)s: %(message)s"
formatter = logging.Formatter(format_)
handler.setFormatter(formatter)
app.logger.addHandler(handler)
# 方法二日志設(shè)置
# logging.config.dictConfig(logger_conf)
return app
app = create_app()
@app.route("/", methods=["GET"])
def test():
current_app.logger.info("this is info")
current_app.logger.debug("this is debug")
current_app.logger.warning("this is warning")
current_app.logger.error("this is error")
current_app.logger.critical("this is critical")
return "ok"
if __name__ == "__main__":
app.run()
請(qǐng)求http://127.0.0.1:5000 輸出到test.log內(nèi)容2019-03-18 22:02:58,718[flask.app][WARNING] :30: this is warning
2019-03-18 22:02:58,718[flask.app][ERROR] :40: this is error
2019-03-18 22:02:58,719[flask.app][CRITICAL] :50: this is critical
2019-03-18 22:04:03,991[flask.app][WARNING] :30: this is warning
2019-03-18 22:04:03,992[flask.app][ERROR] :40: this is error
2019-03-18 22:04:03,992[flask.app][CRITICAL] :50: this is critical
- 對(duì)于以上的Flask logger的基本配置都能滿足基本的日常需求。但是如果同時(shí)配置多個(gè)不同的handler,并且將不同內(nèi)容的日志輸出到不同的文件會(huì)很麻煩。所以需要一個(gè)統(tǒng)一的日志配置文件來(lái)處理。
yaml配置logger
- 在前文中,第二種配置logger的方法中使用了字典,在上一篇文章《Flask如何加載yaml文件配置》中介紹了python讀取yaml文件以及yaml文件在python中的轉(zhuǎn)換。所以只要按照一定的規(guī)則編寫yaml文件,加載到日志配置中,即可完成配置。
- 文件目錄
-----app
│ │
│
-----config
| |
| config.yaml
| logging.yaml
- 編寫logging.yaml
version: 1
disable_existing_loggers: False
# 定義日志輸出格式,可以有多種格式輸出
formatters:
simple:
format: "%(message)s"
error:
format: "%(asctime)s [%(name)s] [%(levelname)s] :%(levelno)s: %(message)s"
# 定義不同的handler,輸出不同等級(jí)的日志消息
handlers:
console:
class: logging.StreamHandler # 輸出到控制臺(tái)
level: DEBUG
formatter: simple
stream: ext://flask.logging.wsgi_errors_stream # 監(jiān)聽(tīng)flask日志
info_file_handler:
class: logging.handlers.RotatingFileHandler # 輸出到文件
level: INFO
formatter: simple
filename: ./logs/info.log
maxBytes: 10485760 # 10MB
backupCount: 20 #most 20 extensions
encoding: utf8
error_file_handler:
class: logging.handlers.RotatingFileHandler # 輸出到文件
level: ERROR
formatter: error
filename: ./logs/errors.log
maxBytes: 10485760 # 10MB
backupCount: 20
encoding: utf8
# 啟用handler
root:
level: INFO
handlers: [console,info_file_handler,error_file_handler]
- 編寫Flask config.yaml
COMMON: &common
# app設(shè)置
DEBUG: False
TESTING: False
THREADED: False
SECRET_KEY: insecure
# 日志配置文件路徑
LOGGING_CONFIG_PATH: ./config/logging.yaml
# 日志文件存放位置
LOGGING_PATH: ./logs
DEVELOPMENT: &development
<<: *common
DEBUG: True
ENV: dev
TESTING: &testing
<<: *common
ENV: test
TESTING: True
PRODUCTION: &production
<<: *common
ENV: prod
SECRET_KEY: shouldbereallysecureatsomepoint
- 加載Flask配置及日志配置
- 工廠文件()
import logging
import logging.config
import yaml
import os
from flask import Flask
def create_app(config_name=None, config_path=None):
app = Flask(__name__)
# 讀取配置文件
if not config_path:
pwd = os.getcwd()
config_path = os.path.join(pwd, 'config/config.yaml')
if not config_name:
config_name = 'PRODUCTION'
conf = read_yaml(config_name, config_path)
app.config.update(conf)
if not os.path.exists(app.config['LOGGING_PATH']):
# 日志文件目錄
os.mkdir(app.config['LOGGING_PATH'])
# 日志設(shè)置
with open(app.config['LOGGING_CONFIG_PATH'], 'r', encoding='utf-8') as f:
dict_conf = yaml.safe_load(f.read())
logging.config.dictConfig(dict_conf) # 載入日志配置
return app
def read_yaml(config_name, config_path):
"""
config_name:需要讀取的配置內(nèi)容
config_path:配置文件路徑
"""
if config_name and config_path:
with open(config_path, 'r', encoding='utf-8') as f:
conf = yaml.safe_load(f.read())
if config_name in conf.keys():
return conf[config_name.upper()]
else:
raise KeyError('未找到對(duì)應(yīng)的配置信息')
else:
raise ValueError('請(qǐng)輸入正確的配置名稱或配置文件路徑')
from app import factory
app = factory.create_app(config_name='DEVELOPMENT')
if __name__ == "__main__":
app.run()
logger在藍(lán)圖(Blueprint)中的使用
- 第一種方法(),使用flask內(nèi)置的handler輸出日志,返回名為
flask.app 的日志。from flask import current_app,Blueprint
bp = Blueprint("test", __name__, url_prefix='/test')
@bp.route('',methods=["GET"])
def test():
current_app.logger.info("this is info")
current_app.logger.debug("this is debug")
current_app.logger.warning("this is warning")
current_app.logger.error("this is error")
current_app.logger.critical("this is critical")
return "ok"
# 輸出日志
# 2019-03-18 22:02:58,718[flask.app][WARNING] :30: this is warning
# 2019-03-18 22:02:58,718[flask.app][ERROR] :40: this is error
# 2019-03-18 22:02:58,719[flask.app][CRITICAL] :50: this is critical
# 2019-03-18 22:04:03,991[flask.app][WARNING] :30: this is warning
# 2019-03-18 22:04:03,992[flask.app][ERROR] :40: this is error
# 2019-03-18 22:04:03,992[flask.app][CRITICAL] :50: this is critical
- 第二種方法(),輸出日志是在某個(gè)文件產(chǎn)生的。
import logging
from flask import Blueprint
bp = Blueprint("test", __name__, url_prefix='/test')
logger = logging.getLogger(__name__) #返回一個(gè)新的以文件名為名的logger
@bp.route('',methods=["GET"])
def test():
logger.info("this is info")
logger.debug("this is debug")
logger.warning("this is warning")
logger.error("this is error")
logger.critical("this is critical")
return "ok"
# 輸出日志
# 2019-03-20 22:05:44,705 [app.test] [ERROR] :40: this is error
# 2019-03-20 22:05:44,705 [app.test] [CRITICAL] :50: this is critical
總結(jié)
- 本文主要介紹了Python logging模塊的簡(jiǎn)單使用,讀者可根據(jù)自身需要進(jìn)行深入學(xué)習(xí)。
- 本文介紹Flask的官方日志配置配置方法以及工廠模式下藍(lán)圖如何使用Flask自帶logger。
- 實(shí)現(xiàn)yaml文件配置Flask日志配置,以及兩種不同的輸出日志選項(xiàng)(Flask自帶logger及文件名logger)。
- 下一篇將介紹如何設(shè)計(jì)實(shí)現(xiàn)FlaskRestful標(biāo)準(zhǔn)化接口。
|