转载自http://blog.csdn.net/qq_27252133/article/details/53520416

原文https://blog.laisky.com/p/fluentd/

最近为了做一些数据分析,把我自己服务器上所有应用的日志都通过 fluentd 转存到 mongodb 了,第一次用 fluentd,记录一些笔记。

因为是初学,绝大部分内容来源于官方文档2,等实际线上使用一段时间后再来更新一些心得。


一、Install

fluent 比较烦的一点是,从 gem 安装和从 rpm、yum 安装的名字不一样,连配置文件的路径都不一样,需要记住的是:

  • 从 gem 安装的,配置文件和执行程序都叫做 fluent;
  • 从 rpm 安装的,配置文件和执行程序都叫做 td-agent。

1、安装 fluentd

详细可参见官方文档

以 CentOS 为例:

# 安装
$ sudo curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sh # 启动
$ sudo /etc/init.d/td-agent start

2、安装插件

# 从 rpm 安装的话,
# 比如要使用下例的 mongo,需要安装
# $ sudo td-agent-gem install fluent-plugin-mongo
$ sudo td-agent-gem <PLUGIN_NAME> # 从 gem 安装的话
$ sudo gem install <PLUGIN_NAME>

二、简介

fluentd 是一个日志收集系统,通过丰富的插件,可以收集来自于各种系统或应用的日志,然后根据用户定义将日志做分类处理。

通过 fluentd,你可以非常轻易的实现像追踪日志文件并将其过滤后转存到 MongoDB 这样的操作。fluentd 可以彻底的将你从繁琐的日志处理中解放出来。

用图来做说明的话,使用 fluentd 以前,你的系统是这样的:

使用了 fluentd 后,你的系统会成为这样:

(图片来源3


三、配置文件

1、路径

分为两种情况:

  • 如果是通过 gem 安装的,那么可以通过下列命令生成和编辑配置文件
$ sudo fluentd --setup /etc/fluent
$ sudo vi /etc/fluent/fluent.conf
  • 如果是通过 RPM, Deb 或 DMG 安装的,那么配置文件在:
$ sudo vi /etc/td-agent/td-agent.conf

2、重用

你可以在配置文件里使用 @include 来切分你的配置文件,include 支持多种写法:

# 绝对路径
include /path/to/config.conf
# 相对路径
@include conf.d/*.conf
# 甚至 URL
@include http://example.com/fluent.conf

3、数据格式

在配置文件里你需要为很多参数赋值,这些值必须使用 fluentd 支持的数据格式,有下列这些:

  • string:字符串,最常见的格式,详细支持语法见文档1
  • integer:整数
  • float:浮点数;
  • size 大小,仅支持整数
    • <INTEGER>k 或 <INTERGER>K
    • <INTEGER>m 或 <INTERGER>M
    • <INTEGER>g 或 <INTERGER>G
    • <INTEGER>t 或 <INTERGER>T
  • time:时间,也只支持整数;
    • <INTEGER>s 或 <INTERGER>S
    • <INTEGER>m 或 <INTERGER>M
    • <INTEGER>h 或 <INTERGER>H
    • <INTEGER>d 或 <INTERGER>D
  • array:按照 JSON array 解析;
  • hash:按照 JSON object 解析。

四、命令

配置文件的核心是各种命令块(directives),每一种命令都是为了完成某种处理,命令与命令之前还可以组成串联关系,以 pipline 的形式流式的处理和分发日志。

最常见的方式就是 source 收集日志,然后由串联的 filter 做流式的处理,最后交给 match 进行分发。

同时你还可以用 label 将任务分组,用 error 处理异常,用 system 修改运行参数。

下面是详细的说明。

1、source

source 是 fluentd 的一切数据的来源,每一个 source 内都包含一个输入模块,比如原生集成的包含 http 和 forward 两个模块,分别用来接收 HTTP 请求和 TCP 请求:

# Receive events from 24224/tcp
# This is used by log forwarding and the fluent-cat command
<source>
@type forward
port 24224
</source> # http://this.host:9880/myapp.access?json={"event":"data"}
<source>
@type http
port 9880
</source>

当然,除了这两个外,fluentd 还有大量的支持各种协议或方式的 source 插件,比如最常用的 tail 就可以帮你追踪文件。

每一个具体的插件都包含其特有的参数,比如上例中 port 就是一个参数,当你要使用一个 source 插件的时候,注意看看有哪些参数是需要配置的,然后将其写到 source directive 内。

source dirctive 在获取到输入后,会向 fluent 的路由抛出一个事件,这个事件包含三个要素:

  • tag
  • time
  • record

那上例代码中的第二个 source 举例,当我们发起一个 http://this.host:9880/myapp.access?json={"event":"data"} 的请求时,这个 source 会抛出:

# generated by http://this.host:9880/myapp.access?json={"event":"data"}
tag: myapp.access
time: (current time)
record: {"event":"data"}

关于如何编写一个输入插件,可以参考文档4

2、match

match 用来指定动作,通过 tag 匹配 source,然后执行指定的命令来分发日志,最常见的用法就是将 source 收集的日志转存到数据库。

# http://this.host:9880/myapp.access?json={"event":"data"}
<source>
@type http
port 9880
</source> # 将标记为 myapp.access 的日志转存到文件
<match myapp.access>
@type file
path /var/log/fluent/access
</match>

上例中的 myapp.access 就是 tag,tag 有好几种匹配模式:

  • *:匹配任意一个 tag;
  • **:匹配任意数量个 tag;
  • a b:匹配 a 或 b;
  • {X,Y,Z}:匹配 X, Y, Z 中的一个。

比如我可以写成这样:

<match a.*>
<match **>
<match a.{b,c}>
<match a.* b.*>

fluentd 按照 match 出现的顺序依次匹配,一旦匹配成功就不会再往下匹配,所以如果你先写了一个 match **,然后后面的所有的 match 都会被忽略。

然后我们使用了 @type file 插件来处理事件,这个插件有一个 path 属性,用来指定输出文件。

用法和 source 几乎一模一样,不过 source 是抛出事件,match 是接收并处理事件。你同样可以找到大量的各式各样的输出插件,也可以参考文档5自己写一个。

3、filter

filter 和 match 的语法几乎完全一样,但是 filter 可以串联成 pipeline,对数据进行串行处理,最终再交给 match 输出。

# http://this.host:9880/myapp.access?json={"event":"data"}
<source>
@type http
port 9880
</source> <filter myapp.access>
@type record_transformer
<record>
host_param "#{Socket.gethostname}"
</record>
</filter> <match myapp.access>
@type file
path /var/log/fluent/access
</match>

这个例子里,filter 获取数据后,调用原生的 @type record_transformer 插件,在事件的 record 里插入了新的字段 host_param,然后再交给 match 输出。

你可以参考文档6来学习如何编写自定义的 filter。

虽然各个插件都有各自的参数,不过 fluentd 为所有的插件都设定了一组默认的参数: - @type:指定插件类型; - @id:给插件指定一个 id; - @label:指定 label; - @log_level:指定插件接收的日志级别。

你可以在任意插件内指定这些参数。

4、system

fluentd 的相关设置,可以在启动时设置,也可以在配置文件里设置,包含:

  • log_level
  • suppress_repeated_stacktrace
  • emit_error_log_interval
  • suppress_config_dump
  • without_source

5、label

label 用于将任务进行分组,方便复杂任务的管理。

你可以在 source 里指定 @label @<LABEL_NAME>,这个 source 所触发的事件就会被发送给指定的 label 所包含的任务,而不会被后续的其他任务获取到。

看个例子:

<source>
@type forward
</source> <source>
# 这个任务指定了 label 为 @SYSTEM
# 会被发送给 <label @SYSTEM>
# 而不会被发送给下面紧跟的 filter 和 match
@type tail
@label @SYSTEM
</source> <filter access.**>
@type record_transformer
<record>
# ...
</record>
</filter>
<match **>
@type elasticsearch
# ...
</match> <label @SYSTEM>
# 将会接收到上面 @type tail 的 source event
<filter var.log.middleware.**>
@type grep
# ...
</filter>
<match **>
@type s3
# ...
</match>
</label>

6、error

用来接收插件通过调用 emit_error_event API 抛出的异常,使用方法和 label 一样,通过设定 <label @ERROR> 就可以接收到相关的异常。


五、Demo

1、Config

一个监听 Nginx 日志的例子:

<source>
@type tail
@id nginx-access
@label @nginx
path /var/log/nginx/access.log
pos_file /var/lib/fluentd/nginx-access.log.posg
tag nginx.access
format /^(?<remote>[^ ]*) (?<host>[^ ]*) \[(?<time>[^\]]*)\] (?<code>[^ ]*) "(?<method>\S+)(?: +(?<path>[^\"]*) +\S*)?" (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$/
time_format %d/%b/%Y:%H:%M:%S %z
</source> <source>
@type tail
@id nginx-error
@label @nginx
path /var/log/nginx/error.log
pos_file /var/lib/fluentd/nginx-error.log.posg
tag nginx.error format /^(?<time>\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}) \[(?<log_level>\w+)\] (?<pid>\d+).(?<tid>\d+): (?<message>.*)$/
</source> <label @nginx>
<match nginx.access>
@type mongo
database nginx
collection access
host 10.47.12.119
port 27016 time_key time
flush_interval 10s
</match>
<match nginx.error>
@type mongo
database nginx
collection error
host 10.47.12.119
port 27016 time_key time
flush_interval 10s
</match>
</label>

为了匹配,你也需要修改 Nginx 的 log_format 为:

log_format main '$remote_addr $host [$time_local] $status "$request" $body_bytes_sent "$http_referer" "$http_user_agent"';

2、Docker

我自己在用的一个 docker 的镜像和 docker-compose.yml

fluentd学习笔记的更多相关文章

  1. Kubernetes 学习笔记(一):基础概念

    个人笔记,仅本人查阅使用,不保证正确. 零.微服务 微服务架构专注于应用解耦合,通过将应用彻底地组件化和服务化,每个微服务只包含一个非常小的功能,比如权限管理.日志收集等等.由这一组微服务组合起来,提 ...

  2. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  3. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  4. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  5. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  6. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  7. seaJs学习笔记2 – seaJs组建库的使用

    原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...

  8. CSS学习笔记

    CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...

  9. HTML学习笔记

    HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...

随机推荐

  1. 【LeetCode】221. Maximal Square 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 动态规划 日期 题目地址: https://leet ...

  2. 【LeetCode】392. Is Subsequence 解题报告(Python)

    [LeetCode]392. Is Subsequence 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/problems/is-subseq ...

  3. webSocket 与HTTP

    WebSocket 协议在2008年诞生,2011年成为国际标准.现在所有浏览器都已经支持了.WebSocket 的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真 ...

  4. 【嵌入式】arduino IDE串口监视器可以正常使用但其他软件发送串口指令没有反应的问题

    解决办法: 1.检查 波特率baudrate 是否一致 2.检查 数据位长度databits 是否一致 3.检查 停止位长度stopbits 是否一致 4.检查 奇偶校验位 是否一致 5.(特殊)是否 ...

  5. 源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

    1. 概述 老话说的好:要善于思考,有创新意识. 言归正传,之前聊了 Springboot 的启动过程,今天来聊聊 Eureka Client 的注册过程. 2. Eureka Client 的注册过 ...

  6. CS5213设计说明书|Capstone CS5213|CS5213设计参考电路

    Capstone CS5213是一款HDMI到VGA转换器结合了HDMI输入接口和模拟RGB DAC输出且带支持片上音频数模转换器.CS5213芯片设计简单,整体芯片尺寸精悍,外围电路集成优化度较高, ...

  7. Oracle数据库安装Version12c

    1.安装规划 Oracle数据库版本: Linuxamd64_12102_database 12c Linux服务器系统: CentOS Linux release 7.5.1804 (Core) 6 ...

  8. Swoole 中使用 Atomic 实现进程间无锁计数器

    使用示例: $atomic = new Swoole\Atomic(); $serv = new Swoole\Server('127.0.0.1', '9501'); $serv->set([ ...

  9. Selenium_POM架构(17)

    POM是Page Object Model的简称,它是一种设计思想,意思是,把每一个页面,当做一个对象,页面的元素和元素之间操作方法就是页面对象的属性和行为. POM一般使用三层架构,分别为:基础封装 ...

  10. JMeter_用户自定义变量

    在实际测试过程中,我们经常会碰到脚本开发时与测试执行时的服务地址不一样的情况,为了方便,我们会把访问地址参数化,当访问地址变化了,我们只需要把参数对应的值改动一下就可以了. 一.添加用户自定义变量元件 ...