有关日志功能是否严重影响 web 框架效率? - 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
LeeReamond
V2EX    Python

有关日志功能是否严重影响 web 框架效率?

  •  
  •   LeeReamond 2021-06-16 23:13:31 +08:00 4888 次点击
    这是一个创建于 1603 天前的主题,其中的信息可能已经有所发展或是发生改变。

    发主题的时候主要想法是局限在 python 的异步框架,不过也很好奇其他语言的框架都用什么解决方案,所以标题里没有写明是 python 。

    问题简单来说,我们都知道 python 的 IO 流,例如常见的 print,是一个同步阻塞操作。而目前网络端的解决方案在向异步非阻塞转移,比如 fastapi/aiohttp 这类框架,转移的同时,日志又是很重要的一个功能,总不可能一个服务没有日志。这是否意味着框架转发性能将被严重降低,有什么解决方案吗?

    第 1 条附言    2021-06-17 02:52:26 +08:00
    贴个条,确实有这个问题,fastapi 默认 logger 在 echo 测试中大概会让响应能力下降几十倍。我试了试把 logger 替换成 loguru,异步写入日志,理论上来说应该有产生日志-》异步写入文件描述符-》系统实际落盘,这几个过程,echo 性能大概也不超过 5000,总的来说还是慢了不少。
    27 条回复    2021-06-18 10:11:16 +08:00
    lishunan246
        1
    lishunan246  
       2021-06-16 23:23:54 +08:00 via Android
    日志可以用 syslog 或者 http 方式输出给专门的 agent 收集。
    特别在意性能可以考虑换其他语言实现。
    catcn
        2
    catcn  
       2021-06-16 23:25:46 +08:00
    放内存,慢慢落磁盘,落得慢直接扔掉
    binux
        3
    binux  
       2021-06-16 23:28:22 +08:00 via Android
    我们都知道 python 的 IO 流,例如常见的 print,是一个同步阻塞操作

    不一定,看往哪写
    joApioVVx4M4X6Rf
        4
    joApioVVx4M4X6Rf  
       2021-06-16 23:39:02 +08:00
    同问
    LeeReamond
        5
    LeeReamond  
    OP
       2021-06-16 23:39:31 +08:00
    @lishunan246 不是很在意性能,业务不会在这里达到瓶颈,只是好奇通常是怎么处理的
    nightwitch
        6
    nightwitch  
       2021-06-16 23:42:06 +08:00
    单独起一个线程负责 IO,其他要写日志的往一个 queue 里写,这个线程从 queue 里拿到日志就往硬盘里写就好了。
    GG668v26Fd55CP5W
        7
    GG668v26Fd55CP5W  
       2021-06-16 23:42:36 +08:00 via iPhone   1
    openresty 就提供了非阻塞日志函数 ngx.log
    ikas
        8
    ikas  
       2021-06-17 00:19:43 +08:00   1
    参考 java 平台,先有 slf4j 通用日志接口,然后有各种不同日志框架实现.比如 log4j2,logback. 他们都支持配置 Appender,根据不同 Appender 你可以实现写入文件,db,console,或者其他服务.他们也都支持配置为异步,减少对业务影响,提高性能.
    同时,编写业务日志也要注意日志粒度,如果是 debug 日志也要先判断 debug level,减少日志拼接损耗
    est
        9
    est  
       2021-06-17 00:28:07 +08:00
    我就用的 udp 打日志到 es 。
    abersheeran
        10
    abersheeran  
       2021-06-17 00:44:28 +08:00 via Android
    我一般多线程+队列进行异步落盘。因为一般不用分析、追溯日志。

    如果有单独的日志存放服务,比如楼上说的 es,那么就走 Unix Socket 、UDP 、TCP 之类的。
    3dwelcome
        11
    3dwelcome  
       2021-06-17 03:43:58 +08:00
    "我们都知道 python 的 IO 流,例如常见的 print,是一个同步阻塞操作。"

    先写在大片纯内存里,满了再刷到磁盘上。

    过程就只是一个拷贝内存的开销,理论上能做到很快吧。
    LeeReamond
        12
    LeeReamond  
    OP
       2021-06-17 03:49:20 +08:00
    @3dwelcome 没有这么单纯,物理上落盘虽然只有一次,但是你还是要先写回内核里,这个过程是同步阻塞的
    neoblackcap
        13
    neoblackcap  
       2021-06-17 04:53:39 +08:00
    日志是走网络用 UDP 发到别的机器不就可以解决这些性能问题么?你的网络 IO 是同步非堵塞,性能只取决于你的发送。
    xuanbg
        14
    xuanbg  
       2021-06-17 06:57:52 +08:00
    @ikas 我们一般情况下不允许打日志。因为所有异常都统一捕获并输出日志了,网关也输出了接口调用参数、响应时间和返回数据的日志,业务里面也就不需要打日志了。偶尔遇到莫名其妙的问题,也是临时加点日志看一下帮助定位问题,用过后也是要删除才能上线的。
    zjqzxc
        15
    zjqzxc  
       2021-06-17 08:05:23 +08:00
    python 的 logging 模块提供了多种 handler,看起来 DatagramHandler ( UDP 发送日志),MemoryHandler,QueueHandler 这几个也许能好点,可以试试看?
    codehz
        16
    codehz  
       2021-06-17 08:18:07 +08:00 via Android
    @LeeReamond 首先可以开线程写,即使 py,做系统调用的时候也会释放 gil 不会阻塞别的线程
    其次,这不是还有 io-uring 异步读写方法吗(
    myCupOfTea
        17
    myCupOfTea  
       2021-06-17 08:52:05 +08:00
    确实影响效率.10%-20%左右
    ScepterZ
        18
    ScepterZ  
       2021-06-17 10:14:19 +08:00   2
    测 echo 性能没有意义,得看你的业务运行要多久,比如直接 echo 0.01ms,log 0.1ms ,但是业务要 10ms,对于业务就没影响,但是你测 echo 性能就下降了 90%
    LeeReamond
        19
    LeeReamond  
    OP
       2021-06-17 10:59:36 +08:00 via Android
    @ScepterZ 意义党可以退散了,我的绝大多数业务离框架瓶颈都很远,按照你的理论可以说大部分性能测试都没意义。我只是发个帖问问有没有人清楚 common practice
    rockyliang
        20
    rockyliang  
       2021-06-17 11:18:56 +08:00 via iPhone
    @xuanbg 网关把接口参数和返回数据都记录下来,请求量大的话,日志文件体积岂不是巨大?
    statement
        21
    statement  
       2021-06-17 11:45:44 +08:00
    日志等级可以用开关控制。完全可以关掉大多数日志。 需要的时候再打开必要的日志等级
    ScepterZ
        22
    ScepterZ  
       2021-06-17 11:56:12 +08:00
    @LeeReamond 你是看不懂“测 echo 性能没有意义”么,测性能当然有意义,但是用 echo 测试说这个对性能影响很大是不准确的
    Digitalzz
        23
    Digitalzz  
       2021-06-17 11:57:42 +08:00
    python 不太清除,Java 可以参考一下,java 中使用 log4j2 等日志框架,在打印的位置信息的时候会进行加锁操作,导致大量线程处于 block 状态,可以导致性能下降 50%甚至 100%,解决办法就是不打印位置信息,按需自己编写代码时可以手动添加。就 IO 流的问题我个人感觉影响不大,可以使用日志框架的一些缓存打印,问题是可能会出现日志丢失
    4BVL25L90W260T9U
        24
    4BVL25L90W260T9U  
       2021-06-17 15:59:28 +08:00
    首先,正经代码没人用 print 写日志的。。
    LeeReamond
        25
    LeeReamond  
    OP
       2021-06-17 22:47:30 +08:00
    @ScepterZ 你是看不懂我想问实现,而所谓性能下降比率是完全是无关紧要的事么? block 了
    LeeReamond
        26
    LeeReamond  
    OP
       2021-06-17 22:50:25 +08:00
    @Digitalzz 丢失问题具体怎么解决呢,按目前的回复,工业级应该就是靠消息队列解决,确实有可靠性的问题,比如一些涉及到金钱往来的业务如果出现纠纷且恰好日志丢失了某行,岂不是很蛋疼?
    myCupOfTea
        27
    myCupOfTea  
       2021-06-18 10:11:16 +08:00
    命令行不打印,或者减少打印(并且换 loguru 拦截打印),发送数据到 logstash 想办法异步发送丢 ensure_future 里执行
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3804 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 00:52 PVG 08:52 LAX 16:52 JFK 19:52
    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