介绍
Fluentd是一个开源的数据收集器,专为处理数据流设计,使用JSON作为数据格式。它采用了插件式的架构,具有高可扩展性高可用性,同时还实现了高可靠的信息转发。具备每天收集5000+台服务器上5T的日志数据,每秒处理50000条消息的性能;
Fluentd是由Fluent+d得来,d生动形象地标明了它是以一个守护进程的方式运行。官网上将其描述为data collector,在使用上,我们可以把各种不同来源的信息,首先发送给Fluentd,接着Fluentd根据配置通过不同的插件把信息转发到不同的 地方,比如文件、SaaS Platform、数据库,甚至可以转发到另一个Fluentd。
Fluentd的作用
作为日志统一采集的解耦层
使用Fluentd前,日志系统的状态:
使用Fluentd后,日志系统的状态:
应用场景
特点
Fluentd的功能
1)安装方便
2)占用空间小
3)半结构化数据日志记录
4)灵活的插件机制
5)可靠的缓冲
6)日志转发
Fluentd原理机制
逻辑结构
Fluentd由三部分组成
Input/Buffer/Output
Input
Input负责接收数据或者主动抓取数据。支持syslog,http,file tail等。
Buffer
Buffer负责数据获取的性能和可靠性,也有文件或内存等不同类型的Buffer可以配置。
Output
Output负责输出数据到目的地例如文件,AWS S3或者其它的Fluentd
代码结构
由于其简单的结构,Fluentd的核心只包含3000行Ruby。Fluentd收集各种输入源的事件并将它们写入输出接收器。 eg:输入源:HTTP, Syslog, Apache Log输出源:Files, Mail, RDBMS databases, NoSQL storages
FLuentd 的扩展性非常好,客户可以自己定制(Ruby)Input/Buffer/Output。 使用Ruby开发,Footprint会小一些。另外采用JSON统一数据/日志格式是它的另一个特点。
Fluentd安装
官方指导中有很多个系统的安装配置。
官方安装指导
这里以CentOS7的为例
安装
curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent3.sh | sh
安装完成后可以在/usr/lib/systemd/system/td-agent目录进行启动停止操作。
$ sudo systemctl start td-agent.service
$ sudo systemctl status td-agent.service
或者
$ sudo /etc/init.d/td-agent start
$ sudo /etc/init.d/td-agent stop
$ sudo /etc/init.d/td-agent restart
$ sudo /etc/init.d/td-agent status
Fluentd服务的日志路径
cat /var/log/td-agent/td-agent.log
配置文件
上面安装方式配置文件位置如下:
/etc/td-agent/td-agent.conf
Fluentd的配置主要由source和match Block组成。
source指定输入资源
其中:
type tail: tail方式是 Fluentd 内置的输入方式,其原理是不停地从源文件中获取新的日志。
format apache: 指定使用 Fluentd 内置的 Apache 日志解析器。
path /var/log/apache2/access_log: 指定日志文件位置。
tag mongo.apache: 指定tag,tag被用来对不同的日志进行分类
每个source指令必须包含一个type(类型)参数,type参数指定输入插件使用。source把事件提交到Fluentd的路由引擎中。一个事件包含三个实体标签:tag,time和record。
tag是一个通过.来分离的字符串(例如myapp.access),用作Fluentd内部路由引擎的方向,time是当事件产生unix时间,而record是一个JSON对象。
match指定输出目的地
match标签后面可以跟正则表达式以匹配我们指定的tag,只有匹配成功的tag对应的日志才会运用里面的配置,type参数指定输出插件使用,flush_interval是用来控制多长时间将日志写入一次。 另外,可以使用include来导入单独的配置文件;
默认配置文件是通过http的方式来获取日志,输出到/var/log/td-agent/td-agent.log路径。
可以使用如下命令发送日志:
curl -X POST -d 'json={"json":"message"}' http://localhost:8888/debug.test
其他配置
filter:过滤,也即事件处理流水线,可在输入和输出之间运行。
system:系统级别的设置。
label:定义一组操作,从而实现复用和内部路由。
@include:引入其他文件,和Java、python的import类似
端口说明
Fluentd (td-agent) 服务启用后,默认会开启127.0.0.1:24230, 0.0.0.0:24224和0.0.0.0:8888这三个端口。
分別介紹一下这些Port 的作用:
127.0.0.1:24230 是 Debug Agent
以下配置表示仅开放本地连接,log才会被其他服务连接,导致信息泄露。而对外只通过debug_agent来开放服务。
<source>
@type debug_agent
bind 127.0.0.1
port 24230
</source>
0.0.0.0:8888是用来接收日志信息的Log HTTP Service,可以直接通过HTTP送Log进来。不需要认证直接发送信息
curl -X POST -d 'json={"message":"show me!"}' http://localhost:8888/td.myTag.test
对应配置信息如下:
<source>
@type http
port 8888
</source>
0.0.0.0:24224是Forward Service,可以用来接收其他Fluentd传送过来的Log,对应配置如下:
<source>
@type forward
</source>
注意事项
很多时候我们希望Fluentd去读取的log是服务用户的权限目录,有可能读取不到。
可以使用如下命令替换Fluentd的执行权限,以替换为root权限为例使用命令如下:
sudo sed -i "s/TD_AGENT_USER=td-agent/TD_AGENT_USER=root/g" /etc/init.d/td-agent
sudo sed -i "s/TD_AGENT_GROUP=td-agent/TD_AGENT_GROUP=root/g" /etc/init.d/td-agent
上述命令会修改这两个参数
TD_AGENT_USER=td-agent
TD_AGENT_GROUP=td-agent
修改后重启服务
sudo service td-agent restart
监听apache输出到mongodb示例
输入
<source>
@type tail
path /var/log/apache2/access_log
pos_file /var/log/td-agent/apache2.access_log.pos
<parse>
@type apache2
</parse>
tag mongo.apache.access
</source>
输出
<match mongo.**>
# plugin type
@type mongo
# mongodb db + collection
database apache
collection access
# mongodb host + port
host localhost
port 27017
# interval
<buffer>
flush_interval 10s
</buffer>
# make sure to include the time key
<inject>
time_key time
</inject>
</match>
测试,访问apache服务10次,使用ab命令Apache Bench。
ab -n 100 -c 10 http://localhost/
c 10 即:每次并发10个
n 100 即: 共发送100个请求
查看mongodb内容如下:
$ mongo
> use apache
> db["access"].findOne();
{ "_id" : ObjectId("4ed1ed3a340765ce73000001"), "host" : "127.0.0.1", "user" : "-", "method" : "GET", "path" : "/", "code" : "200", "size" : "44", "time" : ISODate("2011-11-27T07:56:27Z") }
{ "_id" : ObjectId("4ed1ed3a340765ce73000002"), "host" : "127.0.0.1", "user" : "-", "method" : "GET", "path" : "/", "code" : "200", "size" : "44", "time" : ISODate("2011-11-27T07:56:34Z") }
{ "_id" : ObjectId("4ed1ed3a340765ce73000003"), "host" : "127.0.0.1", "user" : "-", "method" : "GET", "path" : "/", "code" : "200", "size" : "44", "time" : ISODate("2011-11-27T07:56:34Z") }
监听文件输出到ES
<source>
@type tail
path /var/log/syslog
pos_file /var/log/td-agent/syslog.log.pos
tag td.syslog
format /^(?<time>[^ ]*\s*[^ ]* [^ ]*) (?<host>[^ ]*) (?<ident>[a-zA-Z0-9_\/\.\-]*)(?:\[(?<pid>[0-9]+)\])?(?:[^\:]*\:)? *(?<message>.*)$/
time_format %b %d %H:%M:%S
</source>
<match **>
@type elasticsearch
host localhost
port 9200
index_name fluentd
type_name log
</match>
其他项目中使用
很多语言都有Fluentd的插件包,可以集成后直接给Fluentd发送日志信息。
参考如下:
使用Fluentd管理docker容器日志
配置docker转储日志有两种方法,指定特定的容器或者配置docker daemon将所有容器日志均存储到Fluentd中。
docker中快速启动Fluentd服务,使用命令
docker run -d -p 24224:24224 -p 24224:24224/udp -v /data:/fluentd/log fluent/fluentd
此时会在宿主机/data目录下生成data.<fluentd容器id>.log,所有收集到的日志文件将存储至此。
方法1:启动容器时时指定日志输出方式
如下启动ngix容器:
docker run -d --log-driver fluentd --log-opt fluentd-address=localhost:24224 --log-opt tag="nginx-test" --log-opt fluentd-async-connect --name nginx-test -p 8080:80 nginx
–log-driver: 配置log驱动
–log-opt: 配置log相关的参数
fluentd-address: fluentd服务地址
fluentd-async-connect:fluentd-docker异步设置,避免fluentd挂掉之后导致Docker容器也挂了
配置好之后访问nginx页面,每次刷新会出现如下日志
2018-11-02T10:21:55+00:00 nginx-test {
"container_name": "/nginx-test",
"source": "stdout",
"log": "172.96.247.193 - - [03/May/2018:07:21:55 +0000] \"GET / HTTP/1.1\" 304 0 \"-\" \"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36\" \"-\"",
"container_id": "0dafdsdfasweraewrfdasfdsafqwerqwerqwrqwerqwerqwfdafhgggg"
}
方法2: 设置全局log-driver
docker daemon --log-driver=fluentd
或者
cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://zcg96r7h.mirror.aliyuncs.com"],
"log-driver": "fluentd",
"log-opts": {
"fluentd-address": "127.0.0.1:24224"
}
}
注意
a、使用了fluentd之后,将无法使用docker logs 查看;
b、在配置fluentd之前创建的容器日志不会写入到Fluentd,如果想要存储进去需要重建容器;
c、全局配置fluentd之后,如果fluentd服务异常,将无法启动容器
其他配置场景
日志采集工具的对比
logstash
开源界鼎鼎大名ELK stack中的"L",社区活跃,生态圈提供大量插件支持。
logstash基于JRuby实现,可以跨平台运行在JVM上。
模块化设计,有很强的扩展性和互操作性。
logtail
阿里云日志服务的生产者,目前在阿里集团内部机器上运行,经过3年多时间的考验,目前为阿里公有云用户提供日志收集服务。
采用C++语言实现,对稳定性、资源控制、管理等下过很大的功夫,性能良好。相比于logstash、fluentd的社区支持,logtail功能较为单一,专注日志收集功能。
对比详情参考
日志客户端(Logstash,Fluentd, Logtail)横评
三款日志工具各有特点:
logstash支持所有主流日志类型,插件支持最丰富,可以灵活DIY,但性能较差,JVM容易导致内存使用量高。
fluentd支持所有主流日志类型,插件支持较多,性能表现较好。
logtail占用机器cpu、内存资源最少,结合阿里云日志服务的E2E体验良好,但目前对特定日志类型解析的支持较弱,后续需要把这一块补起来。