[flask] 日志配置
1.与supervisor/sentry的日志整合策略
-
分为异常对象和异常信息的捕获:
- 异常event捕获:capture_exception(e),capture_event({"msg":msg})
- 异常信息:add_breadcrumb(msg), app.logger.info(msg)
-
基础:完全关闭flask的记录,不配fileHandler
-
1.只留sentry发送
- prod模式,app.logger.level设置为CRITICAL
- 用capture_exception(e) + add_breadcrumb
-
2.supervisor和sentry同时保存
- app.logger.level设置为INFO
- sentry:capture_exception(e) + app.logger.info(说明信息)
- supervisor:依靠app.logger.info(说明信息)记录,仅stderr.log文件记录,未捕获异常或app.logger.info()内容
- 如果要关闭supervisor
- 仅需将level设置为WARNING,supervisor仅记录错误信息,sentry记录try(e)和错误信息
- 或将level设置为CRITICAL,完全关闭supervisor的记录,sentry记录try(e)和错误信息
2.flask本身日志配置的两种方式:
1.通过logging模块的dictConfig加载日志配置字典的方式
from logging.config import dictConfig
path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
log_file = os.path.join(path, "log/error.log")
log_dict = {
'version': 1,
'root': {
# handler中的level会覆盖掉这里的level
'level': 'DEBUG',
'handlers': ['error_file']
},
'handlers': {
'wsgi': {
'class': 'logging.StreamHandler',
'stream': 'ext://flask.logging.wsgi_errors_stream',
'formatter': 'default'
},
"error_file": {
"class": "logging.handlers.RotatingFileHandler",
"maxBytes": 1024 * 1024, # 打日志的大小,单位字节,这种写法是1M
"backupCount": 1, # 备份多少份,经过测试,最少也要写1,不然控制不住大小
"encoding": "utf-8",
"level": "ERROR",
"formatter": "default", # 对应下面的键
"filename": log_file # 打日志的路径
},
},
'formatters': {
'default': {
'format': '[%(asctime)s] %(levelname)s in [%(filename)s:%(lineno)s]: %(message)s',
},
'simple': {
'format': '%(asctime)s - %(levelname)s - %(message)s'
}
},
}
dictConfig(log_dict)
app = Flask(__name__)
2.通过logging模块的fileConfig加载日志配置文件的方式
config.ini
[loggers]
keys=root,zhilian
[handlers]
keys=fileHandler,consoleHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=DEBUG
handlers=fileHandler
[logger_zhilian]
level=DEBUG
handlers=fileHandler
qualname=zhilian
propagate=0
[handler_consoleHandler]
class=StreamHandler
args=(sys.stdout,)
level=DEBUG
formatter=simpleFormatter
[handler_fileHandler]
class=FileHandler
args=(r'D:\python\code\spider_review\zhilian\log\spider_zhilian.log', 'a')
level=DEBUG
formatter=simpleFormatter
[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=
log.py
import logging
import os
import logging.config
import sys
class Log:
__obj = False
def __new__(cls, *args, **kwargs):
if not cls.__obj:
cls.__obj = super().__new__(cls,*args,**kwargs)
return cls.__obj
def __init__(self):
CONF_LOG = os.path.join(os.path.dirname(os.path.abspath(__file__)),"config.ini")
logging.config.fileConfig(CONF_LOG) # 采用配置文件
self.logger = logging.getLogger('zhilian')
if __name__ == '__main__':
logger = Log().logger
logger.info("aasf")