在集群化环境里,日志采集是重要基础设施。本文结合最新的 1.0.9 版,对 logpipe 做一个简单的介绍。开源主流解决方案是基于 flume-ng,但在实际使用中发现 flume-ng 存在诸多问题。
比如 flume-ng 的 spoolDir 采集器只能对文件名转档后的大小不能变化的最终日志文件进行采集,不能满足采集时效性要求,如果要采集正在被不断追加的日志文件,只能用 exec 采集器搭配 tail -F 命令,但 tail -F 命令又不能通配目标目录中将来新增的未知文件名。其它解决方案如 logstash 由于是 JAVA 开发,内存占用和性能都不能达到最优。
作为一个日志采集的本地代理,内存占用应该小而受控,性能应该高效,耗费 CPU 低对应用影响尽可能小,要能异步实时追踪日志文件增长,某些应用会在目标目录下产生多个日志文件甚至现在不能确定将来的日志文件名,架构上要支持多输入多输出流式日志采集传输,为了达成以上需求,我研究了所需技术,评估实现难度并不高,就自研了 logpipe。
logpipe 是一个分布式、高可用的用于采集、传输、对接落地的日志工具,采用了插件风格的框架结构设计,支持多输入多输出按需配置组件用于流式日志收集架构,无第三方依赖。
logpipe 的一种用法是能异步实时监控集群里的所有日志目录,一旦有文件新增或追加写,立即采集并传输到大存储上以相同日志文件名合并落地,或者写入 HDFS。异步意味着不影响应用输出日志的性能,实时意味着一有日志立即采集,很多日志采集工具如 flume-ng、logstash 介绍文档通篇不提采集方式是否实时还是周期性的,这很关键。
logpipe 概念朴实、使用方便、配置简练,没有如 sink 等一大堆新名词。
logpipe 由若干个 input、事件总线和若干个 output 组成。启动 logpipe 管理进程 (monitor),派生一个工作进程 (worker),监控工作进程崩溃则重启工作进程。工作进程装载配置加载若干个 input 插件和若干个 output 插件,进入事件循环,任一 input 插件产生消息后输出给所有 output 插件。
logpipe 自带了几个插件,分别是:
- logpipe-input-file 用 inotify 异步实时监控日志目录,一旦有文件新建或文件增长事件发生(注意:不是周期性轮询文件修改时间和大小),立即捕获文件名和读取文件追加数据。该插件拥有文件大小转档功能,用以替代应用日志库对应功能,提高应用日志库写日志性能。该插件支持数据压缩。
- logpipe-output-file 一旦输入插件有消息产生后用相同的文件名落地文件数据。该插件支持数据解压。
- logpipe-input-tcp 创建 TCP 服务侦听端,接收客户端连接,一旦客户端连接上有新消息到来,立即读取。
- logpipe-output-tcp 创建 TCP 客户端,连接服务端,一旦输入插件有消息产生后输出到该连接。
- logpipe-input-exec 执行长命令并捕获输出
- logpipe-output-hdfs 一旦输入插件有消息产生后用相同的文件名落地到 HDFS 中。该插件支持数据解压。
使用者可根据自身需求,按照插件开发规范,开发定制插件,如 IBMMQ 输入插件、HDFS 输出插件等。
logpipe 配置采用 JSON 格式,层次分明,编写简洁,如示例:
{ "log" : { "log_file" : "/tmp/logpipe_case1_collector.log" , "log_level" : "INFO" } , "inputs" : [ { "plugin":"so/logpipe-input-file.so" , "path":"/home/calvin/log" , "compress_algorithm":"deflate" } ] , "outputs" : [ { "plugin":"so/logpipe-output-tcp.so" , "ip":"127.0.0.1" , "port":10101 } ] }
文章末尾固定信息