多接口写日志的时候,日志会重叠起来,怎么解决 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
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 2019-11-19 14:55:24 +08:00 5537 次点击
    这是一个创建于 2157 天前的主题,其中的信息可能已经有所发展或是发生改变。

    -- 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 条回复    2019-11-20 10:03:02 +08:00
    valkyrja
        1
    valkyrja  
       2019-11-19 15:04:48 +08:00   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  
       2019-11-19 15:08:53 +08:00 via Android
    楼上+1,两个请求本来就是并发的,给每个请求分配一个唯一 ID
    panyanyany
        3
    panyanyany  
       2019-11-19 15:10:10 +08:00
    logger 最好是一个模块用一个 logger = logging.getLogger(__name__),不要一个 logger 在不同的模块引用来引用去的
    locoz
        4
    locoz  
       2019-11-19 15:11:56 +08:00
    我的接口服务在打日志的时候是用的 JSONLogger,然后每个日志里面都带上了一个请求初始化时生成的 request_id,在 Kibana 里查的时候直接搜 request_id 就能看到某一次请求的所有日志了。
    itskingname
        5
    itskingname  
       2019-11-19 15:26:45 +08:00
    使用第三方库 loguru,不要用自带的 logging 模块,就能解决你这个问题。
    forrestchang
        6
    forrestchang  
       2019-11-19 15:28:16 +08:00
    日志统一放到一个消息队列里,然后开一个 job 来处理这些日志。
    Roney
        7
    Roney  
       2019-11-19 16:21:25 +08:00
    @forrestchang 正解
    TypeErrorNone
        8
    TypeErrorNone  
       2019-11-19 16:30:29 +08:00
    在中间件里给每个请求加上 request_id,打日志的时候记录 request_id
    flyingghost
        9
    flyingghost  
       2019-11-19 16:39:46 +08:00   1
    日志汇总吧,并发请求就会交错起来,不方便跟踪一个请求(一个业务)的日志。
    按请求分开吧,日志之间的时序关系就会丢失,不方便观察服务器状态,尤其是一些请求无关的全局的状态和资源。

    各有利弊。

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

    ```
    [2019-11-19 16:45:05 472][DEBUG][7e42d668] logger
    ```
    tiedan
        13
    tiedan  
       2019-11-19 17:41:47 +08:00
    加 trace_id 想找哪个请求,用 trace_id 过滤即可
    kaid97
        14
    kaid97  
       2019-11-19 17:42:45 +08:00
    并行肯定会的阿。。你要不封装一层加个队列,不然无解
    sunhk25
        15
    sunhk25  
       2019-11-19 17:52:07 +08:00 via Android
    学习,顺便问一下这种日志放到文件里好还是放到 db 中好呢
    1462326016
        16
    1462326016  
       2019-11-19 18:42:00 +08:00
    要么单例要么队列
    NeverBelieveMe
        17
    NeverBelieveMe  
    OP
       2019-11-20 09:47:33 +08:00
    @valkyrja request id 在 logging.Formatter 里面能定义这个字段么?还是自己在打印的时候加上去?
    NeverBelieveMe
        18
    NeverBelieveMe  
    OP
       2019-11-20 09:49:18 +08:00
    @flyingghost 关键业务日志独立是怎么做到的?
    mxy940127
        19
    mxy940127  
       2019-11-20 10:03:02 +08:00
    flask 不是有个 before_request 和 after_request 的钩子么,为什么不在那个钩子里写日志呢. trace_id 或者 request_id 自己建一个 uuid,写入日志就行
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1413 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 16:47 PVG 00:47 LAX 09:47 JFK 12:47
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86