EFK家族---Fluentd日志收集

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/q383965374/article/details/83657257

介绍

Fluentd是一个开源的数据收集器,专为处理数据流设计,使用JSON作为数据格式。它采用了插件式的架构,具有高可扩展性高可用性,同时还实现了高可靠的信息转发。具备每天收集5000+台服务器上5T的日志数据,每秒处理50000条消息的性能;

Fluentd是由Fluent+d得来,d生动形象地标明了它是以一个守护进程的方式运行。官网上将其描述为data collector,在使用上,我们可以把各种不同来源的信息,首先发送给Fluentd,接着Fluentd根据配置通过不同的插件把信息转发到不同的 地方,比如文件、SaaS Platform、数据库,甚至可以转发到另一个Fluentd。

官网

源码github

官方文档

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发送日志信息。

参考如下:

Python

Java

使用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服务异常,将无法启动容器

其他配置场景

根据日志的不同来放在不同的路径

Fluentd将Docker log中stdout和stderr分开

日志采集工具的对比

logstash
开源界鼎鼎大名ELK stack中的"L",社区活跃,生态圈提供大量插件支持。
logstash基于JRuby实现,可以跨平台运行在JVM上。
模块化设计,有很强的扩展性和互操作性。

logtail
阿里云日志服务的生产者,目前在阿里集团内部机器上运行,经过3年多时间的考验,目前为阿里公有云用户提供日志收集服务。
采用C++语言实现,对稳定性、资源控制、管理等下过很大的功夫,性能良好。相比于logstash、fluentd的社区支持,logtail功能较为单一,专注日志收集功能。

对比详情参考
日志客户端(Logstash,Fluentd, Logtail)横评

三款日志工具各有特点:
logstash支持所有主流日志类型,插件支持最丰富,可以灵活DIY,但性能较差,JVM容易导致内存使用量高。
fluentd支持所有主流日志类型,插件支持较多,性能表现较好。
logtail占用机器cpu、内存资源最少,结合阿里云日志服务的E2E体验良好,但目前对特定日志类型解析的支持较弱,后续需要把这一块补起来。

转载请注明出处:EFK家族—Fluentd日志收集

猜你喜欢

转载自blog.csdn.net/q383965374/article/details/83657257