首先,是要记录每个请求的日志,在每个接口函数中都记录日志的话,代码量看着比较大而且不美观,于是想到能不能用一个函数进行统一的处理,这个时候flask的钩子函数们又要派上用场啦。
- 在 before_app_request 中记录每个请求的记录
开发的过程中采用了前后端分离,前后端通过json格式进行数据交互,涉及到文件上传的个别接口使用了表单的提交方式,代码如下:
@api.before_app_request
def before_app_request():
api_name = request.url
try:
#收到的前端数据
request_data = json.loads(request.get_data())
except Exception as e:
request_data = request.form.to_dict()
redis_log_format('R', api_name, None, str(request_data))
- 在 after_app_request 中记录每个请求对应的响应记录
@api.after_app_request
def after_app_request(response):
api_name = request.url
#返回给前端的数据,全部为json类型
response_data = response.json
if str(response.status_code).startswith('4') or str(response.status_code).startswith('5') :
redis_log_format('E', api_name, response.status_code, str(response_data))
else:
redis_log_format('I', api_name, response.status_code, str(response_data))
#别忘记将response返回,否则数据到不了前端
return response
- 用函数事先约定好日志记录的格式
为了减小IO操作对程序效率的影响,也为了避免多进程进行IO操作时带来的冲突,可以先把日志存到redis中,之后再用异步线程或者单独的进程将redis中的日志按照日期读到磁盘文件中,代码如下:
def redis_log_format(level, url, status_code, message): #status_code为状态码,请求日志中为None
# 定义日志的层级
level_dict = { "I":"INFO", "W":"WARNING", "E":"ERROR", 'R':"REQUEST"}
now = datetime.now()
asctime = now.strftime('%Y-%m-%d %H:%M:%S')
levelname = level_dict.get(level, 'INFO')
process = os.getpid()
thread = threading.currentThread().ident
#定义日志的格式 采用f‘’的方式格式化字符串
strMessage = f'{asctime} {levelname} {process} {thread} {url} {status_code} {message}'
#将日志存放到redis中的有序集合中,用时间戳作为每条日志的得分,同一天的日志放到一个集合中,便于之后按日期保存日志文件
tablename = str(date.today())
score= int(now.strftime('%Y%m%d%H%M%S'))
r.zadd( tablename, { strMessage:score } )
网友评论