V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Sponsored by
LinkedIn
不坐班的神仙工作 · 去任何你想去的地方远程,赚一线城市的工资
2000 个不用出门 Social 的全球远程工作,帮助 V2EX 的小伙伴开启全新的工作方式。
Promoted by LinkedIn
PowerRocker
V2EX  ›  Django

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

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

    求教各位,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  
       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   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1339 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 37ms · UTC 23:07 · PVG 07:07 · LAX 16:07 · JFK 19:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.