Tail Notes

Author Avatar
叠搭宝箱 8月 28, 2016

周日一觉醒来看到airflow上这么一排红色的 failed , 心中万头羊驼呼啸而过

需求很简单, 就是一直读取squid的日志然后把日志塞到队列里(通过http请求的方式), 大致的代码如下

1
2
3
4
5
6
tail -f access.log |
while IFS= read -r line
do
curl -XPOST -H 'Content-Type: application/json' -d '{"url":"'$line'"}' http://example.com/api
echo ''
done

处于懵逼状态的我兴冲冲的跑到公司, 发现access.log文件依然是稳定的增长, 但是显然脚本tail不到任何东西了, 虽然以前也出现过这种问题, 但都是比较暴力的重启脚本解决的, 如此稳定的异常的肯定是那个地方做的不对, 仔细的看了下日志文件, 发现在凌晨的时候squid对其进行了切分压缩(周期7天), 正好跟印象中的异常出现的频率一直, 最后怀疑是日志切分导致这类问题

经测试。。果然特么是的 (测试过程不做赘述)

查了一下资料, 使用 -f 的时候, 解释如下

With –follow (-f), tail defaults to following the file descriptor,which means that even if a tail’ed file is renamed, tail will continue to track its end. This default behavior is not desirable when you eally want to track the actual name of the file, not the file descriptor (e.g., log rotation). Use –follow=name in that case. That causes tail to track the named file in a way that accommodates renaming, removal and creation.

也就是说, -f 模式下监听的是文件描述符, 如果文件改名了, 监听的还是该文件(改名后文件描述符是不变的), 解决方法是使用 -F 参数

-F: same as –follow=name –retry
–retry: keep trying to open a file even when it is or becomes inaccessible; useful when following by name, i.e., with –follow=name

类似情况还有Nginx的日志切分, nginx日志切分完成之后需要向nginx master进程发送一个 USR1 信号 来让nginx master进程重新打开日志文件, 如果不发送该信号的话, access.log 会无法记录日志

Over