目前系统到处都打印日志,有各自模块的 logger ( gorm ,gin ,业务日志...),目前用的是 supervisor 管理,但是当系统并发数较高,日志打印过多,会导致 supervisor 的 cpu 飚升。
尽管各个日志都有 logger ,可以设置 SetOutput 直接写到文件,但是总有一些第三方库输出到 stdout ,所以没有办法实现统一定向到日志文件。目前找到的一个办法是:
file, err := os.OpenFile("log", os.O_APPEND|os.O_WRONLY|os.O_CREATE, os.ModePerm)
syscall.Dup2(int(file.Fd()), int(os.Stdout.Fd()))
syscall.Dup2(int(file.Fd()), int(os.Stderr.Fd()))
这样可以将 stdout 直接输出到日志,可以实现自己的需求,但是感觉不像是一个常规的方案,有没有比较好的日志方案,尽量简洁,能做到所有日志写入文件,最好能实现自动 rotate 。
仔细测试,研究了一下,发现DUP2对性能还是比较有影响的,另外也没有必要过于追求都要所有的stdout日志。所以还是直接写入日志文件了,进行了自动分卷。
这个是我基于别人的代码修改的,做了自动分卷的功能,大家可以参考一下。
https://github.com/seaguest/log
1
adoal 2021-11-13 23:40:01 +08:00 1
换个思路,你是写业务系统的程序员,这些“运维”性质的功能不要在业务系统里自己写,要善用现有的基础设施。
如果只是在 Linux 用,不考虑兼容 Windows ,可以打到 syslog 去,然后由 logrotate 来卷。正常的 Linux 发行版,默认安装都带了 syslog 服务(多数是 rsyslogd )和 logrotate ,人家是专业干这个的,久经生产环境考验了。 |
2
masterclock 2021-11-14 00:14:02 +08:00
日志就输出到 stdout 或 stderr ,其他啥都不要考虑,这不是一个程序应该关心的事情。
|
3
vvhhaaattt 2021-11-14 08:39:55 +08:00 via Android
supervisor 在 std 输出过多时,性能确实不太好。
但你直接写到文件,轮转也需要注意。 systemd 是个好东西,不管是功能还是性能都很好,而且作为系统服务,能力范围也更大,但 supervisor 用惯了的也大有人在 |
4
seaguest OP @adoal
谢谢你的建议,目前因为系统处于初级阶段,还是部署在云服务器上,但是后面稳定了会开始部署到 K8S 里。 syslog 的话会不会和系统其他应用所有的日志混合在一起了?假如机器上部署了 A ,B ,C 三个服务,他们的日志会混在一起么? 另外考虑到未来会部署在 Docker 里面,要么选择 loki 方案,或者 ELK ,但是这样也面临一个问题,第三方库打印的日志,就可能丢失。 |
5
seaguest OP @vvhhaaattt
看了几个 golang log-rotate 的开源项目,其实也不复杂,用了几个试试,效果比 supervisor 那个好太多了。 systemd 单机还行,但是我们后面等系统成熟了会部署到 k8s ,就必须考虑 Docker 里面的方案, 目前的这种 log.SetOutput()方式,如果写入 ELK 也是比较方便配置的。 |
6
adoal 2021-11-14 13:28:42 +08:00 via iPhone
syslog 可以配置过滤,可以配置打到远程服务器。
对老派 Unix/Linux 用户(甚至只是用户,不是职业运维)来说这些都是挺基本的技能。 不过貌似云时代的 PPT 架构师们都不太把这些老派的玩意当回事😄 |