V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
PowerRocker
V2EX  ›  Django

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

  •  1
     
  •   PowerRocker · Jan 11, 2021 · 4695 views
    This topic created in 1938 days ago, the information mentioned may be changed or developed.

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

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

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

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

    一点经验
    tmackan
        11
    tmackan  
       Jan 11, 2021
    https://github.com/tmacjx/flask-quickstart/blob/master/common/log.py

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

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

    这样可以用 logrotate 灵活配置

    可以参考 oslo_log.watchers.FastWatchedFileHandler
    encro
        15
    encro  
       Jan 11, 2021
    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  
       Jan 11, 2021
    熟悉 django 的话那么就选 sentry?
    zachlhb
        17
    zachlhb  
       Jan 11, 2021 via Android
    settings 里配置 log 就可以按天啊
    614457662
        18
    614457662  
       Jan 11, 2021 via Android
    logrotate,按天或者按文件大小分隔,记得 logrotate 在配置时加上 usr1 信号发给 gunicorn,让 gunicorn 重载日志就可以了。完美解决多 worker 日志压缩错误的问题。
    johnsona
        19
    johnsona  
       Jan 12, 2021 via iPhone
    题主说法不准确,python 自带的 logging 是线程安全的,多线程环境下按时间和大小滚动没问题,但是多进程不安全,而 gunicorn 是多进程,方案的话。有说让操作系统切割,有说开启 socket server 但是存在网络问题会不会丢日志,sentry 是记录错误日志的,或者 elk 一把梭,还有就是有一个 multiprocesing log 库,用的文件锁还是什么不清楚,还有 logru 这个库,还有人重写 handler 什么的,各有各的写法,换 go 吧,伤心了
    PowerRocker
        20
    PowerRocker  
    OP
       Jan 12, 2021
    @aladdindingding
    @lolizeppelin
    @encro
    @zachlhb
    @614457662
    @johnsona
    感谢各位大佬,目前也是重写了 handler,整体问题不大,就是一直想知道有没有什么最佳实践,想找些开源项目多学习学习
    tmackan
        21
    tmackan  
       Jan 12, 2021
    @johnsona 说的有道理,的确是进程不安全,log 这块有使用 threadlock,所以是多线程安全
    johnsona
        22
    johnsona  
       Jan 12, 2021 via iPhone
    @PowerRocker 我也想,linux 自带的 logrotate 不知道怎么解决 gunicorn 的日志问题,openstck 的 oslo 我也是看这个帖子才知道,说不定可以
    todd7zhang
        23
    todd7zhang  
       Jan 12, 2021
    1. python 代码里面只用 logging.StreamHandler(),
    2. supervisor 启动 django,同时配置 stdout_logfile=/log/log.log redirect_stderr=true,
    3. logrotate 按天分割 /log/log.log 文件
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2343 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 45ms · UTC 04:41 · PVG 12:41 · LAX 21:41 · JFK 00:41
    ♥ Do have faith in what you're doing.