V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
NeverBelieveMe
V2EX  ›  Python

多接口写日志的时候,日志会重叠起来,怎么解决

  •  
  •   NeverBelieveMe · Nov 19, 2019 · 5894 views
    This topic created in 2352 days ago, the information mentioned may be changed or developed.

    -- coding: utf-8 --

    import logging import os class Log(object):

    def __init__(self, name, ):
        self.name = name
        self.path = os.getcwd() + "/logs/"
        self.formatter = logging.Formatter("%(asctime)s - %(filename)s -[line:%(lineno)d] - %(levelname)s: %(message)s",
                                           "%Y-%m-%d %H:%M:%S")
    
    def getLogger(self):
        logger = logging.getLogger(self.name)
        logger.setLevel(logging.DEBUG)
    
        logger.addHandler(self.get_console_handler())
        return logger
    
    def get_console_handler(self):
        console_handler = logging.StreamHandler()
        console_handler.setLevel(logging.DEBUG)
        console_handler.setFormatter(self.formatter)
        return console_handler
    

    flask_logger = Log(name="flask").getLogger()

    上面是代码。 遇到的情况是在 a.pyb.py 文件分别引入了 flask_logger,接口 A 和接口 B 分别是 logger.info(“A start")...logger.info(“A end")和 logger.info(“B start")...logger.info(“B end"),在接口被频繁调用的时候,就会出现 A start B start B end A end 这种混在一起打印的情况。想知道有没有什么办法解决

    19 replies    2019-11-20 10:03:02 +08:00
    valkyrja
        1
    valkyrja  
       Nov 19, 2019   ❤️ 2
    用 nginx 的话,可以使用 nginx 的 request id,应用通过 request id 串联请求内的日志: https://www.nginx.com/blog/application-tracing-nginx-plus/

    不用 nginx 就自己生成 request id 放到 flask 上下文: https://flask.palletsprojects.com/en/1.0.x/appcontext/
    conn4575
        2
    conn4575  
       Nov 19, 2019 via Android
    楼上+1,两个请求本来就是并发的,给每个请求分配一个唯一 ID
    panyanyany
        3
    panyanyany  
       Nov 19, 2019
    logger 最好是一个模块用一个 logger = logging.getLogger(__name__),不要一个 logger 在不同的模块引用来引用去的
    locoz
        4
    locoz  
       Nov 19, 2019
    我的接口服务在打日志的时候是用的 JSONLogger,然后每个日志里面都带上了一个请求初始化时生成的 request_id,在 Kibana 里查的时候直接搜 request_id 就能看到某一次请求的所有日志了。
    itskingname
        5
    itskingname  
       Nov 19, 2019
    使用第三方库 loguru,不要用自带的 logging 模块,就能解决你这个问题。
    forrestchang
        6
    forrestchang  
       Nov 19, 2019
    日志统一放到一个消息队列里,然后开一个 job 来处理这些日志。
    Roney
        7
    Roney  
       Nov 19, 2019
    @forrestchang 正解
    TypeErrorNone
        8
    TypeErrorNone  
       Nov 19, 2019
    在中间件里给每个请求加上 request_id,打日志的时候记录 request_id
    flyingghost
        9
    flyingghost  
       Nov 19, 2019   ❤️ 1
    日志汇总吧,并发请求就会交错起来,不方便跟踪一个请求(一个业务)的日志。
    按请求分开吧,日志之间的时序关系就会丢失,不方便观察服务器状态,尤其是一些请求无关的全局的状态和资源。

    各有利弊。

    我的做法是:
    1,默认日志按时序,需要的时候用 requestID 来过滤就可以方便的按照请求来查看日志序列。全局时序也方便日志切割、轮转、储存、查找等大部分场景。
    2,关键业务日志独立,按业务来冗余记录。比如一个用户 /一个订单的所有日志。
    3,以上两点结合也比较方便。输入还是正常输入,输出独立多个 Adapter,按不同规则去路由到不同文件即可。
    robinlovemaggie
        10
    robinlovemaggie  
       Nov 19, 2019
    a.py --> a stream--> a.log
    b.py --> b stream -->b.log
    Varobjs
        11
    Varobjs  
       Nov 19, 2019
    1. 并发写日志肯定会窜行
    2. 可以先把日志写到内存,生命周期结束统一刷到磁盘,减少窜行可能性
    3. 最后就是,每个生命周期,完全可以加个 reqId 的静态变量,每行日志加上[reqId] 前缀
    Varobjs
        12
    Varobjs  
       Nov 19, 2019
    类似这种

    ```
    [2019-11-19 16:45:05 472][DEBUG][7e42d668] logger
    ```
    tiedan
        13
    tiedan  
       Nov 19, 2019
    加 trace_id 想找哪个请求,用 trace_id 过滤即可
    kaid97
        14
    kaid97  
       Nov 19, 2019
    并行肯定会的阿。。你要不封装一层加个队列,不然无解
    sunhk25
        15
    sunhk25  
       Nov 19, 2019 via Android
    学习,顺便问一下这种日志放到文件里好还是放到 db 中好呢
    1462326016
        16
    1462326016  
       Nov 19, 2019
    要么单例要么队列
    NeverBelieveMe
        17
    NeverBelieveMe  
    OP
       Nov 20, 2019
    @valkyrja request id 在 logging.Formatter 里面能定义这个字段么?还是自己在打印的时候加上去?
    NeverBelieveMe
        18
    NeverBelieveMe  
    OP
       Nov 20, 2019
    @flyingghost 关键业务日志独立是怎么做到的?
    mxy940127
        19
    mxy940127  
       Nov 20, 2019
    flask 不是有个 before_request 和 after_request 的钩子么,为什么不在那个钩子里写日志呢. trace_id 或者 request_id 自己建一个 uuid,写入日志就行
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   4935 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 55ms · UTC 09:52 · PVG 17:52 · LAX 02:52 · JFK 05:52
    ♥ Do have faith in what you're doing.