求教 Django(DRF)日志最佳实践 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
PowerRocker
V2EX    Django

求教 Django(DRF)日志最佳实践

  •  1
     
  •   PowerRocker 2021-01-11 11:00:4 +08:00 4442 次点击
    这是一个创建于 1806 天前的主题,其中的信息可能已经有所发展或是发生改变。

    求教各位,DRF 、gunicorn 、supervisor 部署的后端,有没有关于日志的最佳实践 为了能实现日志按天分隔,因为有多线程,默认人 log handler 会有问题,遂重写了个 handler 同时 gunicorn 本身的日志貌似也有点问题

    求教各位有没有什么开源项目可以考下,我看了很多项目,对日志这一块都没有什么比较好的处理,很多项目甚至都没有记录日志

    23 条回复    2021-01-12 17:34:23 +08:00
    leeguo
        1
    leeguo  
       2021-01-11 11:42:34 +08:00
    我也想知道, 我想写个日志中间件的, 但是感觉自己写的不会太好...
    tinypig
        2
    tinypig  
       2021-01-11 12:04:20 +08:00   2
    django log 到一个文件里,然后用系统的 logrotate 来按天分割
    TimePPT
        3
    TimePPT  
    PRO
       2021-01-11 13:42:28 +08:00 via Android
    loguru
    zzzmj
        4
    zzzmj  
       2021-01-11 13:49:49 +08:00
    logging.handlers.TimedRotatingFileHandler
    PowerRocker
        5
    PowerRocker  
    OP
       2021-01-11 14:11:32 +08:00
    @TimePPT 感谢
    PowerRocker
        6
    PowerRocker  
    OP
       2021-01-11 14:12:08 +08:00
    @zzzmj gunicorn 启动多个 worker 会有 bug
    zzzmj
        7
    zzzmj  
       2021-01-11 14:20:41 +08:00
    @PowerRocker 打扰了,没认真看描述
    lolizeppelin
        8
    lolizeppelin  
       2021-01-11 15:12:33 +08:00   1
    openstack/oslo.log 你值得拥有
    lolizeppelin
        9
    lolizeppelin  
       2021-01-11 15:14:43 +08:00
    @tinypig

    代码里没写接信号重新打开 fd 尽量不要直接用 logrotate 分割
    人家 nginx 是收了信号的
    tmackan
        10
    tmackan  
       2021-01-11 15:19:21 +08:00
    @PowerRocker
    1.py 自带的 log 不是多线程安全的,所以需要用一个文件锁来控制并发丢日志问题
    2.log 库切割不是定时任务,而是每次 log 的时候判断下是否达到了切割时机
    3.log 整体压缩的 shell 脚本需要与 log 切割的时间点错开,这里涉及到一个文件描述符的占用问题,建议压缩时间延后

    一点经验
    tmackan
        11
    tmackan  
       2021-01-11 15:23:51 +08:00
    https://github.com/tmacjx/flask-quickstart/blob/master/common/log.py

    这里的 MultiProcessTimedRotatingFileHandler 可以参考下,只能按天切割
    没支持按大小切割,当日志量比较大的话,grep 很慢,这是个坑。。。
    PowerRocker
        12
    PowerRocker  
    OP
       2021-01-11 15:32:31 +08:00
    @tmackan 谢谢大佬,看了下你的项目,和你使用的方法一样,不知大佬有没有一些 Django 相关的开源项目对日志这一块处理的比较好的
    aladdindingding
        13
    aladdindingding  
       2021-01-11 16:38:20 +08:00
    自己写一个 logserver 然后日志统一用 server 来打 这个应该写成一个公共组件了 多进程也没问题
    lolizeppelin
        14
    lolizeppelin  
       2021-01-11 16:48:49 +08:00
    linux 下可以用 pyinotify 监控 IN_MOVED_FROM 和 IN_DELETE

    监控到事件以后重新打开文件

    这样可以用 logrotate 灵活配置

    可以参考 oslo_log.watchers.FastWatchedFileHandler
    encro
        15
    encro  
       2021-01-11 17:21:59 +08:00
    supervisor 将日志重定向?

    https://channels.readthedocs.io/en/stable/deploying.html

    [fcgi-program:asgi]
    # TCP socket used by Nginx backend upstream
    socket=tcp://localhost:8000

    # Directory where your site's project files are located
    directory=/my/app/path

    # Each process needs to have a separate socket file, so we use process_num
    # Make sure to update "mysite.asgi" to match your project name
    command=daphne -u /run/daphne/daphne%(process_num)d.sock --fd 0 --access-log - --proxy-headers mysite.asgi:application

    # Number of processes to startup, roughly the number of CPUs you have
    numprocs=4

    # Give each process a unique name so they can be told apart
    process_name=asgi%(process_num)d

    # Automatically start and recover processes
    autostart=true
    autorestart=true

    # Choose where you want your log to go
    stdout_logfile=/your/log/asgi.log
    redirect_stderr=true
    encro
        16
    encro  
       2021-01-11 17:26:22 +08:00
    熟悉 django 的话那么就选 sentry?
    zachlhb
        17
    zachlhb  
       2021-01-11 18:15:32 +08:00 via Android
    settings 里配置 log 就可以按天啊
    614457662
        18
    614457662  
       2021-01-11 23:35:55 +08:00 via Android
    logrotate,按天或者按文件大小分隔,记得 logrotate 在配置时加上 usr1 信号发给 gunicorn,让 gunicorn 重载日志就可以了。完美解决多 worker 日志压缩错误的问题。
    johnsona
        19
    johnsona  
       2021-01-12 01:59:18 +08:00 via iPhone
    题主说法不准确,python 自带的 logging 是线程安全的,多线程环境下按时间和大小滚动没问题,但是多进程不安全,而 gunicorn 是多进程,方案的话。有说让操作系统切割,有说开启 socket server 但是存在网络问题会不会丢日志,sentry 是记录错误日志的,或者 elk 一把梭,还有就是有一个 multiprocesing log 库,用的文件锁还是什么不清楚,还有 logru 这个库,还有人重写 handler 什么的,各有各的写法,换 go 吧,伤心了
    PowerRocker
        20
    PowerRocker  
    OP
       2021-01-12 09:53:58 +08:00
    @aladdindingding
    @lolizeppelin
    @encro
    @zachlhb
    @614457662
    @johnsona
    感谢各位大佬,目前也是重写了 handler,整体问题不大,就是一直想知道有没有什么最佳实践,想找些开源项目多学习学习
    tmackan
        21
    tmackan  
       2021-01-12 14:37:59 +08:00
    @johnsona 说的有道理,的确是进程不安全,log 这块有使用 threadlock,所以是多线程安全
    johnsona
        22
    johnsona  
       2021-01-12 15:27:17 +08:00 via iPhone
    @PowerRocker 我也想,linux 自带的 logrotate 不知道怎么解决 gunicorn 的日志问题,openstck 的 oslo 我也是看这个帖子才知道,说不定可以
    todd7zhang
        23
    todd7zhang  
       2021-01-12 17:34:23 +08:00
    1. python 代码里面只用 logging.StreamHandler(),
    2. supervisor 启动 django,同时配置 stdout_logfile=/log/log.log redirect_stderr=true,
    3. logrotate 按天分割 /log/log.log 文件
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5346 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 06:42 PVG 14:42 LAX 22:42 JFK 01:42
    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