首页 > 其他分享 >flask写接口,定制日志输出以及将请求状态以及自定义日志写入文件中

flask写接口,定制日志输出以及将请求状态以及自定义日志写入文件中

时间:2024-07-23 17:55:09浏览次数:11  
标签:logging 自定义 flask app handler 日志 logger

前言:

无论是写接口还是写项目,配置日志是必选的;适合配置可以帮助自己排查代码逻辑问题

简单说一说日志的等级以及用处

1. 日志等级
DEBUG : 10
INFO:20
WARN:30
ERROR。40
CRITICAL:50

数字越大,等级越高!!

2. 日志用处:
        DEBUG(调试):用于开发阶段的调试,开启后,会记录程序运行过程中的所有详细信息,用于排查代码逻辑问题;在生产环境一般不建议长期开启,会产生大量的日志数据
        INFO(信息)::通常用来记录系统运行的关键事件或正常流程信息,或者是自定义输出日志帮助自己排查问题
        WARN(警告):记录可能潜在的问题或者非预期情况,但不影响系统整体运行的情况;可以提前发现可能存在的风险,避免小问题逐渐恶化成严重故障
        ERROR(错误):记录系统出现错误或异常情况,这些情况可能会导致功能无法正常使用或部分服务中断
        CRITICAL(致命): 显示应用程序中发生了严重的错误,比如程序失败

3. 日志格式
format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s'

filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中
pathname:打印当前执行程序的路径,其实就是sys.argv[0]
filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”
format:指定handler使用的日志显示格式。
datefmt:指定日期时间格式。
level:设置rootlogger(后边会讲解具体概念)的日志级别
stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。

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用户输出的消息

一、日志基本配置

1. 使用logging模块,配合控制日志输出到控制台中

from flask import Flask, request  
import logging  
from logging.handlers import RotatingFileHandler  

  
# 创建 Flask 应用实例  
app = Flask(__name__)  

# 创建一个控制台处理器,将日志输出到控制台  
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)

# 配置自定义日志记录器,用于自己需要调试的信息展示
flask_logger = logging.getLogger('flask_app')
flask_logger.setLevel(logging.INFO)  # 设置日志输出等级至少在INFO及以上

# 定义日志格式
formatter = logging.Formatter('%(asctime)s [%(filename)s %(lineno)d] %(levelname)s:%(message)s')
console_handler.setFormatter(formatter)
flask_logger.addHandler(console_handler)

@app.route('/', methods=['GET', ])
def index():
    flask_logger.debug("请求调试") 
    flask_logger.info("请求成功") 
    flask_logger.warning("警告") 
    flask_logger.error("发生错误!") 
    flask_logger.critical("系统发生严重错误") 
    return 'Hello, World!'
    

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8081)

控制台日志输出样例:

WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:8081
 * Running on http://10.47.75.187:8081
Press CTRL+C to quit
2024-07-23 16:45:32,173 [api_test.py 24] INFO:请求成功
2024-07-23 16:45:32,173 [api_test.py 25] WARNING:警告
2024-07-23 16:45:32,174 [api_test.py 26] ERROR:发生错误!
2024-07-23 16:45:32,174 [api_test.py 27] CRITICAL:系统发生严重错误
127.0.0.1 - - [23/Jul/2024 16:45:32] "GET / HTTP/1.1" 200 -

2. 将自定义的日志写入文件中 

from flask import Flask
import logging

# 创建 Flask 应用实例
app = Flask(__name__)

# 配置日志记录器
# logger = logging.getLogger('flask_app')
# logger.setLevel(logging.INFO)

# 配置自定义日志记录器,用于自己需要调试的信息展示
flask_logger = logging.getLogger('flask_app')
flask_logger.setLevel(logging.INFO)  # 设置日志输出等级至少在INFO及以上

# 创建一个文件处理器,将日志记录到flask_api.log文件中
file_handler = logging.FileHandler('flask_api.log')
file_handler.setLevel(logging.INFO)

# 创建一个控制台处理器,将日志输出到控制台
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)  # 设置日志输出等级至少在INFO及以上

# 定义日志格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)

# 将处理器添加到日志记录器
flask_logger.addHandler(file_handler)  # 将自定义的日志写入文件中
flask_logger.addHandler(console_handler)  # 将自定义的日志写输出到控制台中


@app.route('/', methods=['GET', ])
def index():
    flask_logger.debug("请求调试")
    flask_logger.info("请求成功")
    flask_logger.warning("警告")
    flask_logger.error("发生错误!")
    flask_logger.critical("系统发生严重错误")
    return 'Hello, World!'


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8081)
flask_api.log日志文件输出样例:
2024-07-23 16:59:25,979 - flask_app - INFO - 请求成功
2024-07-23 16:59:25,980 - flask_app - WARNING - 警告
2024-07-23 16:59:25,981 - flask_app - ERROR - 发生错误!
2024-07-23 16:59:25,981 - flask_app - CRITICAL - 系统发生严重错误

以上会存在一个问题:自定义输出的日志可以写入文件中,请求状态GET、POST 成功 200状态等没有写入

如果想要请求的状态也要写入文件中,需要配合Werkzeug(Flask 使用的 WSGI 工具包)的日志记录器来实现

3. 将flask自定义的日志,以及请求flask接口过来的状态日志一同写入文件中

import logging
from flask import Flask


# 配置文件日志处理器
file_handler = logging.FileHandler('flask_api_main.log')  # 写入当前文件所在目录的文件,没有自动创建
file_handler.setLevel(logging.DEBUG)

# 配置控制台输出日志处理器
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)

# 配置日志格式化器
formatter = logging.Formatter('%(asctime)s [%(filename)s %(lineno)d] %(levelname)s:%(message)s')
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)

# 配置 Werkzeug(Flask 的底层 WSGI 工具包)的日志记录器
werkzeug_logger = logging.getLogger('werkzeug')
werkzeug_formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(message)s')
werkzeug_logger.addHandler(file_handler)  # 将日志输出写入文件
werkzeug_logger.addHandler(console_handler)  # 将请求接口的状态日志也输出到控制台

app = Flask(__name__)
app.debug = True  # 调试使用,并默认使用日志输出,完全控制自定义日志记录,生产下删掉

# 将日志处理器添加到 Flask 应用的日志记录器
app.logger.setLevel(logging.INFO)
app.logger.addHandler(file_handler)  # 将flask自定义日志输出也写入文件 主要是 app.logger 的使用


@app.route('/', methods=['GET', ])
def index():
    app.logger.debug("请求调试")
    app.logger.info("请求成功")
    app.logger.warning("警告")
    app.logger.error("发生错误!")
    app.logger.critical("系统发生严重错误")
    return "Hello World!"


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8081)
flask_api_main.log日志文件输出样例:
2024-07-23 17:34:15,278 [_internal.py 96] INFO:[31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:8081
 * Running on http://10.49.73.177:8081
2024-07-23 17:34:15,279 [_internal.py 96] INFO:[33mPress CTRL+C to quit[0m
2024-07-23 17:34:15,282 [_internal.py 96] INFO: * Restarting with watchdog (fsevents)
2024-07-23 17:34:15,376 [_internal.py 96] WARNING: * Debugger is active!
2024-07-23 17:34:15,381 [_internal.py 96] INFO: * Debugger PIN: 139-794-987
2024-07-23 17:34:19,888 [api_test.py 39] INFO:请求成功
2024-07-23 17:34:19,889 [api_test.py 40] WARNING:警告
2024-07-23 17:34:19,889 [api_test.py 41] ERROR:发生错误!
2024-07-23 17:34:19,889 [api_test.py 42] CRITICAL:系统发生严重错误
2024-07-23 17:34:19,890 [_internal.py 96] INFO:127.0.0.1 - - [23/Jul/2024 17:34:19] "GET / HTTP/1.1" 200 -

标签:logging,自定义,flask,app,handler,日志,logger
From: https://blog.csdn.net/2301_76868495/article/details/140639928

相关文章

  • 在帝国CMS中设置自定义页面主要涉及以下步骤
    步骤1:创建新页面登录帝国CMS后台。在左侧导航栏中,单击“页面管理”。单击“添加单页信息”。步骤2:设置页面基本信息在“页面名称”字段中输入页面的名称。在“页面别名”字段中输入页面的别名(用于在URL中使用)。在“所属栏目”字段中选择页面的父栏目(如果没有,则选择“顶级栏......
  • Typora设置自定义脚本上传图片
    搭建图床服务这里利用CloudFlare搭建免费的图床服务cf-image-hosting部署Pages$gitclonehttps://github.com/ifyour/cf-image-hosting.git$cdcf-image-hosting$npminstall&&npmrundeploy部署成功后会显示如下信息设置自定义域名点击左侧Workers和Pages,选......
  • 织梦dedecms自定义表单选项必填怎么修改?
    我们先在plus/diy.php文件中的的第40行下加上一下代码//增加必填字段判断if($required!=''){if(preg_match('/,/',$required)){$requireds=explode(',',$required);foreach($requiredsas$field){if($$field==''){......
  • 一段时间后登录时 Flask 出现 SESSION_COOKIE_NAME 错误
    直到最近,一切都很好,但现在我的网站不断给出“SESSION_COOKIE_NAME”和“NoneType”对象没有属性“修改”错误。但令人感兴趣的是,如果我更改代码,错误如何消失一段时间并不重要。请帮助知识渊博的人这里是代码最重要的部分:importosimportplotly.expressaspximportcs50......
  • Gunicorn Flask 服务器终止最后一个请求,并显示“连接关闭但没有响应”
    Heroku上的GunicornFlask服务器在重新启动Worker之前终止了最后一个请求,导致出现503错误:“连接关闭而没有响应。”我已经分析了数百个这样的请求,每当服务器遇到“连接关闭而没有响应”时,“错误,它总是发生在特定工作程序重新启动之前的最后一次调用上。我在Guni......
  • 自定义全选框,当勾选√添加到selection中,再次勾选从selection中移除
    <el-table:data="tableData"ref="tableData"height="450px"class="customer-no-border-table":row-class-name="tableRowClassName":......
  • Android开发 - ViewGroup解析与自定义
    ViewGroup解析ViewGroup是一个特殊的View,可以包含其他视图(称为子视图)。而ViewGroup是View的子类,所以ViewGroup可以当成普通的UI组件使用。ViewGroup是布局和视图容器的基类,该类还定义了ViewGroup.LayoutParams用作布局参数基类的类由于ViewGroup的直接子类和间接子类比较......
  • vue element-ui表格table 表格动态 添加行、删除行、添加列、删除列 自定义表头
       vuetable表格动态添加行、删除行、添加列、删除列自定义表头; 增加一行、删除一行、添加一列、删除一列;每行带输入框input代码1、HTML部分:<template><divclass="app-container"><el-table:data="tableData"borderstyle="width:600px;margin-top:2......
  • echarts的markline自定义起始位置和终点位置
    letmarkPoint=[10,20];markLine:{symbol:["none","none"],//去掉箭头silent:true,label:{show:true,formatter:"{b}",offset:[-......
  • 如何调试 python Flask [84] [CRITICAL] WORKER TIMEOUT?
    调试:gtts.tts:保存到temp.mp37月22日09:10:56PM[2024-07-2215:40:56+0000][84][严重]工作超时(pid:87)|||7月22日09:10:56PM[2024-07-2215:40:56+0000][87][INFO]工人退出(pid:87)7月22日09:10:57PM[2024-07-2215:40:57+0000][95][INF......