kubernetes迁移产生日志收集问题
今天把腾讯kubernetes TKE上的一些服务弄到单机docker-compose里去了。为什么迁TKE的问题先不谈,因为原来的服务日志都是依赖腾讯Loglistener,这个日志端和腾讯TKE是完美配合的,去node上拿文件日志非常方便,也没有去优化。但这次由于结构换了,期望从docker-compose的Fluentd驱动来获得日志然后用kafka协议发到接收端,第一步就是要把容器都输出到/dev/stdout和/dev/stderr。
找不到日志
monolog的配置
代码用的是php里最有名的monolog,先改配置。把日志流输出到path: "php://stderr"
,这里有第一个发现,不能写path: "/dev/stderr"
或者path: "/proc/1/fd/2"
,这两种写法都会报File Append的错误,显然要使用最前面的封装版本,当然这和手册上的有点出入。
推荐你简单使用常量 STDIN、 STDOUT 和 STDERR 来代替手工打开这些封装器。
https://www.php.net/manual/zh/wrappers.php.php 手册上原话。
找不到日志
容器服务是用Supervisor管理的,一个容器上跑php-fpm和nginx,Supervisor里FPM的配置是写到/dev/stderr里去的,但结果就是无论如何配置都无法写到/dev/stderr。
bash-5.1# ps aux | grep master
7 root 0:00 php-fpm: master process (/usr/local/etc/php-fpm.d/www.conf)
8 root 0:00 nginx: master process /usr/local/nginx/sbin/nginx -g daemon off;
查看下进程err输出情况。
bash-5.1# ls -l /proc/7/fd/2
l-wx------ 1 root root 64 Apr 7 14:44 /proc/7/fd/2 -> /usr/local/var/log/php-fpm.log
日志被牢牢的写进了/usr/local/var/log/php-fpm.log,没有进管道,找了半天发现,是一个神奇的配置组合问题。
[program:php-fpm]
command=/usr/local/sbin/php-fpm --force-stderr --nodaemonize --fpm-config /usr/local/etc/php-fpm.d/www.conf
autostart=true
autorestart=true
priority=5
stdout_events_enabled=true
stderr_events_enabled=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
stopsignal=QUIT
关键在于,当你用了nodaemonized,就要用–force-stderr来保证进程写到容器的stderr输出。参考,https://stackoverflow.com/questions/50995042/docker-does-not-catch-php-fpm-outputs-with-symfony-and-monolog
As php-fpm is run in nodaemonized mode, you need to set the –force-stderr flag which "Force output to stderr in nodaemonize even if stderr is not a TTY."
检查一下,连接对了!用docker logs -f container
检查也没问题了!
bash-5.1# ls -l /proc/7/fd/2
l-wx------ 1 root root 64 Apr 7 14:44 /proc/7/fd/2 -> pipe:[13099270]