Flask记录每个请求以及每个请求所对应的响应日志

2019-05-27  本文已影响0人  mengkaidi

首先,是要记录每个请求的日志,在每个接口函数中都记录日志的话,代码量看着比较大而且不美观,于是想到能不能用一个函数进行统一的处理,这个时候flask的钩子函数们又要派上用场啦。

  1. 在 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))
  1. 在 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
  1. 用函数事先约定好日志记录的格式
    为了减小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 } )
上一篇下一篇

猜你喜欢

热点阅读