flask请求时间记录和日志处理

这篇具有很好参考价值的文章主要介绍了flask请求时间记录和日志处理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

时间记录

在Python中,如果需要记录一个函数执行的时间,可以通过装饰器的方式来实现,避免在每个函数中进行重复编码。

def time_summary(func):
    def wrapper(*args, **kwargs):
        # 以秒为单位的时间戳
        start = time.time()
        result = func(*args, **kwargs)
        logger.info(f"function use time {(time.time() - start) * 1000:.5f}ms")
        return result

    return wrapper

@time_summary
def hello_world():
    return "hello world"

flask日志处理

在logging日志处理中,每次日志输出都是一个全新的LogRecord事件,所以每次的输出之间是相互不关联的。但是在实际的项目中,我们希望能够在日志中获取每一次请求所对应的输出时间。

为实现上述需求,我们需要将同一次请求的事件关联起来,添加相同的标识打印到日志中。在日志的格式化输出中,通过LogRecord属性打印标识,但是每次日志输出都是一个全新的LogRecord事件。flask中是存在上下文的,所以考虑在一次请求的上下文中添加指定标识,然后在每次输出日志时,LogRecord获取该标识进行输出,管理同一请求。

全局上下文实现

import logging
import time
import uuid

from flask import Flask, g, has_app_context

app = Flask(__name__)


class RequestFilter(logging.Filter):
    def filter(self, record):
        if has_app_context() and hasattr(g, "trace_id"):
            record.trace_id = g.trace_id
        else:
            record.trace_id = None
        return record


handler = logging.StreamHandler()
handler.setFormatter(
    logging.Formatter(
        '[%(asctime)s] - [%(trace_id)s] - [%(levelname)s] - [%(message)s]')
)
handler.addFilter(RequestFilter())

logger = logging.getLogger()
logger.addHandler(handler)
logger.setLevel(logging.INFO)


def time_summary(func):
    def wrapper(*args, **kwargs):
        # 以秒为单位的时间戳
        start = time.time()
        result = func(*args, **kwargs)
        logger.info(f"function use time {(time.time() - start) * 1000:.5f}ms")
        return result

    return wrapper


@app.before_request
def add_trace_id():
    g.trace_id = str(uuid.uuid4())


@app.route("/", methods=["GET"])
@time_summary
def hello_world():
    logger.info("hello world")
    return "hello world"
# [2024-02-20 18:21:14,605] - [60b03671-10e4-4143-922e-2c336ff6df44] - [INFO] - [hello world]
# [2024-02-20 18:21:14,606] - [60b03671-10e4-4143-922e-2c336ff6df44] - [INFO] - [function use time 0.16093ms]

在上述示例中,通过@app.before_request拦截器在请求前向全局上下文中添加了trace_id属性,通过Filter在每次输出日志时获取请求全局上下文的trace_id属性,使每一次日志输出的请求通过uuid进行关联。

实现优化

随着微服务的发展,我们希望在多个微服务之间能够关联相同的uuid,但是通过全局上下文的方式只能保证每一次请求的uuid相同,原因在于我们的uuid是直接生成的,若是能在多个服务之间关联起uuid,当请求时,则可根据关联的uuid获取相同的日志内容。

考虑添加参数,但存在参数值时,以该值为同一请求日志追踪标识,不存在则生成。

这里在方法的请求头中添加参数实现,若在每个flask请求上添加参数实现,需要多次重复实现且当实现变更时,容易漏改

from wsgiref.headers import Headers

@app.before_request
def add_trace_id():
    if request.headers.get("X-Trace-Id") is None:
        headers = Headers()
        for key, value in request.headers.items():
            headers[key] = value
        headers["X-Trace-Id"] = str(uuid.uuid4())
        request.headers = headers
    g.trace_id = request.headers.get("X-Trace-Id")

在flask中,headers是不可变对象,所以不可以直接修改headers对象。
虽然headers是不可变对象,但是headers指针却不是固定的,所以通过获取原来的headers内容,修改指针的方式来解决不可变对象问题(headers不可拷贝,所以以迭代遍历的方式获取)文章来源地址https://www.toymoban.com/news/detail-836108.html

到了这里,关于flask请求时间记录和日志处理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ELK日志记录——Kibana组件——grok 正则捕获插件、mutate数据修改插件、multiline 多行合并插件、date 时间处理插件

    grok 使用文本片段切分的方式来切分日志事件 内置正则表达式调用 %{SYNTAX:SEMANTIC} ●SYNTAX代表匹配值的类型,例如,0.11可以NUMBER类型所匹配,10.222.22.25可以使用IP匹配。 ●SEMANTIC表示存储该值的一个变量声明,它会存储在elasticsearch当中方便kibana做字段搜索和统计,你可以将一

    2024年02月16日
    浏览(35)
  • Python Flask + Gunicorn + Docker 的日志输出设置

    我们一个项目使用了 Python Flask 框架来实现 Web 服务,之前的日志输出一直有问题。而从项目需求、运行维护出发,正确的日志输出对使用者来说都是非常重要的。 这里完整的整理了从 开发 Flask 时的日志设置,到生产环境使用 Gunicorn 运行 Flask 的日志设置 以及 使用 Docker 容器

    2024年02月05日
    浏览(29)
  • python在flask中的请求数据“无限流”

    在flask请求中,有个需求是让调用方一直调接口,并立马返回,而接口方缓存请求,依次执行。 注意: 需要注意的是, request_queue.get() 之后队列里的值就直接推出了,不用显式推出。 以上就可以做到讲请求立刻返回,接口缓存请求内容自我\\\"消化\\\"。Enjoy~ ∼ O n e   p e r s o n  

    2024年02月21日
    浏览(28)
  • 【python】flask模板渲染引擎Jinja2,通过后端数据渲染前端页面

    ✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN新星创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开

    2024年04月11日
    浏览(44)
  • 【Python】flask框架请求体数据,文件上传,请求头信息获取方式案例汇总

    ✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN新星创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开

    2024年03月22日
    浏览(28)
  • 后端flask,前端vue,实现post请求chatgpt流式响应

    vue2写法 vue3 setup写法

    2024年01月21日
    浏览(33)
  • 【Python系列】python 如何打印带时间的日志

    💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老 导航 檀越剑指大厂系列:全面总

    2024年04月23日
    浏览(33)
  • Python 日志记录:6大日志记录库的比较

    日志记录框架是一种工具,可帮助您标准化应用程序中的日志记录过程。虽然某些编程语言提供内置日志记录模块作为其标准库的一部分,但大多数日志记录框架都是第三方库,例如logging (Python)、Log4j (Java)、 Zerolog (Go) 或 Winston (Node.js)。有时,组织会选择开发自定义日志记录

    2024年02月14日
    浏览(32)
  • 课程27:API接口请求日志【后端】

    本文是《.Net Core从零学习搭建权限管理系统》教程专栏的课程(点击链接,跳转到专栏主页,欢迎订阅,持续更新…) 专栏介绍 :以实战为线索,基于.Net 7 + REST + Vue、前后端分离,不依赖任何第三方框架,从零一步一步讲解权限管理系统搭建。 专栏适用于人群 :Web后端开

    2024年02月15日
    浏览(30)
  • 【python】flask查询更新指定的某一条记录

    PackageRecord.query.filter_by(id=package_id).update(json_data)  这段代码的问题在于它不能正确地更新指定的记录。这是因为  update()  方法是 SQLAlchemy 提供的一种批量更新的方法,他通过接收一个字典对象来更新记录。但是在你的代码中, json_data  应该是一个 JSON 字符串,而不是一个字

    2024年02月15日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包