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

2021-01-11 11:00:04 +08:00
 PowerRocker

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

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

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

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

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

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

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

这样可以用 logrotate 灵活配置

可以参考 oslo_log.watchers.FastWatchedFileHandler
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
2021-01-11 17:26:22 +08:00
熟悉 django 的话那么就选 sentry?
zachlhb
2021-01-11 18:15:32 +08:00
settings 里配置 log 就可以按天啊
614457662
2021-01-11 23:35:55 +08:00
logrotate,按天或者按文件大小分隔,记得 logrotate 在配置时加上 usr1 信号发给 gunicorn,让 gunicorn 重载日志就可以了。完美解决多 worker 日志压缩错误的问题。
johnsona
2021-01-12 01:59:18 +08:00
题主说法不准确,python 自带的 logging 是线程安全的,多线程环境下按时间和大小滚动没问题,但是多进程不安全,而 gunicorn 是多进程,方案的话。有说让操作系统切割,有说开启 socket server 但是存在网络问题会不会丢日志,sentry 是记录错误日志的,或者 elk 一把梭,还有就是有一个 multiprocesing log 库,用的文件锁还是什么不清楚,还有 logru 这个库,还有人重写 handler 什么的,各有各的写法,换 go 吧,伤心了
PowerRocker
2021-01-12 09:53:58 +08:00
@aladdindingding
@lolizeppelin
@encro
@zachlhb
@614457662
@johnsona
感谢各位大佬,目前也是重写了 handler,整体问题不大,就是一直想知道有没有什么最佳实践,想找些开源项目多学习学习

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/743743

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX