flume 1.7.0 推出了 taildirSource 组件。tail 监控 目录下匹配上正则表达式的 的所有文件,实现断点续传。
#问题
但是官方的 taildirSource 组件貌似是支持nginx 日志,对于log4j 日志好像不太管用。
因为log4j 日志会自动切分,log4j 切分日志其实就是新建一个文件,然后把原来的日志文件都改名。但是 taildirSource 组件时不支持文件改名的。如果文件改名会认为是新文件,就会重新读取,这就导致了日志文件重读。
#解决
为了解决这个问题,我去读了 taildirSource 的源码。
发现了两个地方 需要修改
#1.修改 ReliableTaildirEventReader
修改ReliableTaildirEventReader 类的 updateTailFiles 方法。
将其中的 tf.getPath().equals(f.getAbsolutePath()) 判断条件去除。
只用判断文件不为空即可,不用判断文件的名字,因为log4j 日志切分文件被重命名了。
// if (tf == null || !tf.getPath().equals(f.getAbsolutePath())) {
if (tf == null) {//文件不存在 position 中则全读。
#2.修改TailFile
修改TailFile 类的 updatePos 方法
此处同样的原因,inode 已经能够确定唯一的 文件了,所以不用加 path 作为判定条件了。所以去掉该条件就支持了文件重命名情况。
// if (this.inode == inode && this.path.equals(path))
if (this.inode == inode)
修改这两个地方就支持了文件重命名 的问题,实现了目录下多文件监控,断点续传。
添加自定义source入口,也就是将源码拷贝过来,然后将修改过的代码打包为自定义source的jar 包运行flume 。
参考 : flume自定义组件的 jar 包管理
提供 taildirsource 的配置文件如下
a1.sources = r1
a1.sources.r1.type = com.xx.xx.source.taildir.TaildirSource
a1.sources.r1.channels = c1
a1.sources.r1.positionFile = /opt/apps/log4j/taildir_position.json
a1.sources.r1.filegroups = f1
a1.sources.r1.filegroups.f1 = /opt/apps/log4j/logs/*.log.*
a1.sources.r1.fileHeader = true
通过这些修改就 实现了多文件监控和断点续传。支持log4j 日志监控。
#4. 监控多个文件夹下的多个文件
监控多个文件夹下的多个文件,只用 配置多个filegroups 即可。
a1.sources = r1
a1.sources.r1.type = com.xx.xx.source.taildir.TaildirSource
a1.sources.r1.channels = c1
a1.sources.r1.positionFile = /opt/apps/log4j/taildir_position.json
a1.sources.r1.filegroups = f1 f2
a1.sources.r1.filegroups.f1=/opt/apps/log4j/test*.log
a1.sources.r1.filegroups.f2=/opt/apps/log4j2/test*.log
a1.sources.r1.fileHeader = true
源码传送门: https://github.com/527515025/bigdata/tree/master/flume/tailDirSource/src/main/java/com/us/source/taildir
参考: http://blog.csdn.net/test103/article/details/55096786#reply