目录

  • 前言
  • Logging
    • 日记级别
    • 配置
  • 改造
    • 初始化配置
    • 添加配置
    • 打印日志
    • 请求日志拦截

前言

在之前的文章中我们讲过Flask项目的创建和Flask项目的部署。但在实际项目的运行中,少补了会发生一些我们无法预知的错误。而这个时候日志的输出就发挥着重要的左右。本文将基于Flask服务对日志格式就行修改,并按日期作为文件名进行本地化存储。

Logging

讲到日志,我们总不能每一次都print()这么low的对吧?所以这里先介绍一下logging模块。它提供一套完成的日志API,可以完美与我们的Flask服务契合。

日记级别

这里日志级别其实已经是全球国际惯例了,基本所有的服务(不管什么语言)都是这么定义的:

  • CRITICAL
  • ERROR
  • WARNING
  • INFO
  • DEBUG

配置

logging主要是由一个API来创建自定义日志格式的,那就是basicConfig。这里点进去看看函数,发现可以填这些参数

filename  Specifies that a FileHandler be created, using the specifiedfilename, rather than a StreamHandler.
filemode  Specifies the mode to open the file, if filename is specified(if filemode is unspecified, it defaults to 'a').
format    Use the specified format string for the handler.
datefmt   Use the specified date/time format.
style     If a format string is specified, use this to specify thetype of format string (possible values '%', '{', '$', for%-formatting, :meth:`str.format` and :class:`string.Template`- defaults to '%').
level     Set the root logger level to the specified level.
stream    Use the specified stream to initialize the StreamHandler. Notethat this argument is incompatible with 'filename' - if bothare present, 'stream' is ignored.
handlers  If specified, this should be an iterable of already createdhandlers, which will be added to the root handler. Any handlerin the list which does not have a formatter assigned will beassigned the formatter created in this function.

如果只是简单使用的话,对应的参数实际意义其实也非常明显了。但这里额外讲讲format这个参数的定义。这里表格是搬运而来的,大佬还是整理的完整(原文地址,支持原创)

参数 描述
%(name)s Logger的名字
%(levelno)s 数字形式的日志级别
%(levelname)s 文本形式的日志级别
%(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
%(filename)s 调用日志输出函数的模块的文件名
%(module)s 调用日志输出函数的模块名
%(funcName)s 调用日志输出函数的函数名
%(lineno)d 调用日志输出函数的语句所在的代码行
%(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
%(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
%(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(thread)d 线程ID。可能没有
%(threadName)s 线程名。可能没有
%(process)d 进程ID。可能没有
%(message)s 用户输出的消息

改造

讲了那么多有的没的,现在开始动手在我们的flask应用中改造优雅的日志输出。

初始化配置

首先在自己的配置包中创建一个新的py文件,这里我命名为LogHandler.py。然后里面是代码,具体每一行我都有注释的,大家可以直接复制或个性修改。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File  : LogHandle.py
# @Author: Richard Chiming Xu
# @Date  : 2021/1/18
# @Desc  :import os
import logging
import time
from logging.handlers import RotatingFileHandler# log配置,实现日志自动按日期生成日志文件
def make_dir(make_dir_path):path = make_dir_path.strip()if not os.path.exists(path):os.makedirs(path)def getLogHandler():# 日志地址log_dir_name = "Logs"# 文件名,以日期作为文件名log_file_name = 'logger-' + time.strftime('%Y-%m-%d', time.localtime(time.time())) + '.log'# 创建日志文件log_file_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) + os.sep + log_dir_namemake_dir(log_file_folder)log_file_str = log_file_folder + os.sep + log_file_name# 默认日志等级的设置logging.basicConfig(level=logging.WARNING)# 创建日志记录器,指明日志保存路径,每个日志的大小,保存日志的上限file_log_handler = RotatingFileHandler(log_file_str, maxBytes=1024 * 1024, backupCount=10, encoding='UTF-8')# 设置日志的格式                   发生时间    日志等级     日志信息文件名      函数名          行数        日志信息formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(filename)s - %(funcName)s - %(lineno)s - %(message)s')# 将日志记录器指定日志的格式file_log_handler.setFormatter(formatter)# 日志等级的设置# file_log_handler.setLevel(logging.WARNING)return file_log_handler

添加配置

创建完日志的配置文件之后,我们还需要在flask app创建的时候把我们的配置文件给注册到flask logger里面。这里我就简短只标重点好了。

    # 创建Flask应用app = Flask(__name__)# 添加日志配置app.logger.addHandler(LogHandle.getLogHandler())# 激活上下文ctx = app.app_context()ctx.push()

打印日志

添加完成之后,我们只需要在代码中引入flask app,然后使用就可以了。我一般会在上面配置中激活上下文,然后引入current_app使用。注意:这里flask app必须要上下文衔接统一(一个线程中)。经测试,使用multiprocessing开启多线程是无法使用的。

current_app.logger.info('我打印了一个日志输出')

最终的日志打印格式如下:

2021-01-26 08:47:14,393 - INFO - 类名.py - 方法名 - 行数 - 日志内容

请求日志拦截

再深化一点点,flask其实有提供api的拦截器。大致就是拦截所有的请求,然后先统一执行我们这段代码,再执行对应api逻辑。我们可以通过这个特性配合我们的日志输出,最后进行统一的request日志打印,从而节省大量的重复代码。

# 每一次请求前执行
@app.before_request
def log_each_request():app.logger.info('【请求方法】{}【请求路径】{}【请求地址】{}'.format(request.method, request.path, request.remote_addr))

基于Flask的优雅日志记录相关推荐

  1. 基于.NetCore3.1系列 —— 日志记录之初识Serilog

    前言 对内置日志系统的整体实现进行了介绍之后,可以通过使用内置记录器来实现日志的输出路径.而在实际项目开发中,使用第三方日志框架(如:Log4Net.NLog.Loggr.Serilog.Sentry ...

  2. PostSharp AOP编程:1.基于PostSharp的AOP日志记录和异常捕捉【附带源码】

    AOP(基于切面编程):它是对业务逻辑的分离,使各个业务直接的耦合变低,比如在传统的OOP编程中将日志记录.异常处理.权限管理等方面剥离出来.在今后的维护过程中,对其改变日志记录.异常处理.权限管理方 ...

  3. 基于.NetCore3.1系列 —— 日志记录之自定义日志组件

    前言 回顾:日志记录之日志核心要素揭秘 在上一篇中,我们通过学习了解在.net core 中内置的日志记录中的几大核心要素,在日志工厂记录器(ILoggerFactory)中实现将日志记录提供器(IL ...

  4. 基于.NetCore3.1系列 —— 日志记录之日志配置揭秘

    前言 在项目的开发维护阶段,有时候我们关注的问题不仅仅在于功能的实现,甚至需要关注系统发布上线后遇到的问题能否及时的查找并解决.所以我们需要有一个好的解决方案来及时的定位错误的根源并做出正确及时的修复 ...

  5. 基于.NetCore3.1系列 —— 日志记录之日志核心要素揭秘

    前言 在上一篇中,我们已经了解了内置系统的默认配置和自定义配置的方式,在学习了配置的基础上,我们进一步的对日志在程序中是如何使用的深入了解学习.所以在这一篇中,主要是对日志记录的核心机制进行学习说明. ...

  6. .NET Core微服务之基于Exceptionless实现分布式日志记录

    一.Exceptionless极简介绍 Exceptionless 是一个开源的实时的日志收集框架,它可以应用在基于 ASP.NET,ASP.NET Core,Web API,Web Forms,WP ...

  7. python flask sqlalchemy慢日志记录

    参考1:https://www.cnblogs.com/rgcLOVEyaya/p/RGC_LOVE_YAYA_605days.html 参考2:https://gitee.com/Green-uni ...

  8. TinyLog –轻量级Java日志记录框架教程

    TinyLog is a simple and lightweight logging framework for Java. We can use tinylog with Java, Kotlin ...

  9. OWASP之安全日志记录和监控失败

    windows系统日志 windows系统日志:命令eventvwr.exe查看 日志缺失的危害 不记录可审计的事件,例如登录.失败登录和高价值交易. 警告和错误不会生成.不充分或不清楚的日志消息. ...

最新文章

  1. 208. Implement Trie (Prefix Tree)
  2. 153.复用的相关概念 154.信道共享技术有哪些?
  3. oracle dba_seg,Oracle DBA 应知应会 -- PGA自动管理
  4. NYOJ 597 完数?
  5. pmtk3怎样离线安装
  6. 怎样在电脑上上传图片_电脑上回收站怎样恢复
  7. 十分钟带你理解Kubernetes核心概念
  8. Hvv近期0day总结二
  9. 2016年移动广告聚合平台浅析
  10. matlab simulink 单气室油气弹簧阻尼特性分析
  11. wake on lan 实现远程开机(远程开关机程序)
  12. 计算机学报latex模板\renewcommand\figurename失效
  13. 计算机中图形和图像这两个概念的异同,图形图象处理
  14. 时间,是个什么东东?
  15. (转载)总结一下SQL语句中引号(')、quotedstr()、('')、format()在SQL语句中的用法...
  16. python基础——文件与IO
  17. 微信小程序导入微信聊天记录文件
  18. 游戏保护_CRC32检测
  19. windows下安装spark
  20. MATLAB函数——lowpass

热门文章

  1. python---mysql批量插入数据
  2. Java-实现动态数组(ArrayList<Integer>集合)
  3. python numpy安装教程_Python和numpy下载安装方法
  4. C51单片机LED显示二进制【核心代码详解】
  5. 前端面经——腾讯暑期实习生
  6. BZOJ 4808 二分图最大独立集
  7. Fiddler抓包安装使用教程
  8. 分布式数据库HBase
  9. 老男孩python第14期_python学习之老男孩python全栈第九期_day014知识点总结
  10. Eclipse更新插件时报错解决办法