文章目录
官方文档地址: Tail
tail
输入插件允许监控一个或几个文本文件。它具有与tail -f
shell 命令类似的行为。
插件读取Path
模式中每个匹配的文件,每发现一行(用\n
分隔),它就会生成一个新的记录。可以选择使用数据库文件,来记录文件的历史和偏移量状态,如果服务重新启动,就可以恢复到之前的状态。
1. 配置参数
插件支持以下配置参数:
参数 | 描述 | 默认值 |
---|---|---|
Buffer_Chunk_Size | 设置读取文件数据的初始缓冲区大小。此值用于增加缓冲区大小。该值必须符合 Unit Size 规格。 | 32k |
Buffer_Max_Size | 设置每个监视文件缓冲区大小的限制。当缓冲区需要增加时(例如:非常长的行),这个值用于限制内存缓冲区可以增长多少。如果读取文件超过此限制,则从监控文件列表中删除该文件。该值必须符合 Unit Size 规格。 | 32k |
Path | 通过使用通用通配符指定特定日志文件或多个日志文件的模式。也允许使用逗号分隔的多个模式。 | |
Path_Key | 如果启用,它将添加被监视文件的名称作为记录的一个字段。字段名为该参数的值,字段值为被监视文件的名称。 | |
Exclude_Path | 设置一个或多个 shell 模式,以逗号分隔,以排除匹配某些条件的文件,例如:Exclude_Path *.gz,*.zip ,表示排除gz 和zip 文件。 | |
Offset_Key | 如果启用,Fluent Bit 将添加当前监控文件的偏移量作为记录的一个字段。字段名为该参数的值,字段值为被监视文件的偏移量。 | |
Read_from_Head | 对于开始时发现的新文件(没有数据库偏移 / 位置记录),从文件的头部读取内容,而不是尾部。 | False |
Refresh_Interval | 刷新监控文件列表的时间间隔,以秒为单位。 | 60 |
Rotate_Wait | 指定在文件被旋转一次时监视文件的额外时间(以秒为单位),以防某些挂起的数据被刷新。 | 5 |
Ignore_Older | 忽略比这个时间(以秒为单位)更早的记录。支持 m,h,d(分钟,小时,天)语法。默认行为是从指定文件中读取所有记录。仅当指定了 Parser 并且它可以解析记录的时间时可用。 | |
Skip_Long_Lines | 当一个被监视的文件由于非常长的行(Buffer_Max_Size)而达到它的缓冲区容量时,默认行为是停止监视该文件。Skip_Long_Lines 会改变这种行为,并指示 Fluent Bit 跳过长行,继续处理适合缓冲区大小的其他行。 | Off |
DB | 指定跟踪被监视文件和偏移量的数据库文件。 | |
DB.sync | 设置默认同步(I/O)方法。取值范围:Extra,Full,Normal,Off。这个标志影响内部 SQLite 引擎如何进行磁盘同步,关于每个选项的详细信息请参阅这里。大多数工作负载场景都可以使用normal 模式,但是如果在每次写操作之后都需要完全同步,那么应该设置full 模式。请注意,full 具有很高的 I/O 性能成本。 | normal |
DB.journal_mode | 设置数据库的日志模式(WAL)。开启 WAL 可以提供更高的性能。注意,WAL 与共享网络文件系统不兼容。 | WAL |
Mem_Buf_Limit | 设置Tail 插件在添加数据到引擎时可以使用的内存限制。如果达到了极限,就会暂停;当刷新数据时,它将恢复。 | |
exit_on_eof | 当读取一个文件时,当它到达文件的末尾时就会退出。用于批量加载和测试。 | false |
Parser | 指定解析器的名称,以将条目解释为结构化消息。 | |
Key | 当消息是非结构化的(没有应用解析器)时,它将作为字符串附加到名称为log 的 key 下。此选项允许为该 key 定义另一个名称。 | log |
Tag | 设置一个标记(带有regex-extract字段),它将被放置在读取的行上。如:kube.<namespace_name>.<pod_name>.<container_name> 。注意,支持“标签扩展”:如果标签包含星号(*),该星号将被替换为监控文件的绝对路径(也可以查看 Tail + Kubernetes Filter 的工作流程) | |
Tag_Regex | 设置正则表达式从文件名中提取字段。如:(?<pod_name>[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)_(?<namespace_name>[^_]+)_(?<container_name>.+)- |
注意,如果没有指定数据库参数DB
,默认情况下,插件将从头开始读取每个目标文件。这也可能导致一些不需要的行为,例如,当一行大于Buffer_Chunk_Size
并且Skip_Long_Lines
没有打开时,每次Refresh_Interval
刷新都将从开始读取该文件,直到文件被旋转。
2. 多行支持
从 Fluent Bit v1.8 开始,我们引入了新的 Multiline core 功能。对于 Tail 输入插件来说,这意味着它现在既支持旧的配置机制,也支持新的配置机制。为了避免破坏性的更新,我们保留这两中配置机制,但鼓励用户使用最新的配置机制。我们将这两种机制称为:
- Multiline Core(多行核心)
- Old Multiline(旧的多行)
2.1. 多行核心 (v1.8)
新的多行核心通过以下配置项暴露:
参数 | 描述 |
---|---|
multiline.parser | 指定应用于内容的一个解析器或多行解析器定义。 |
正如 Multiline Parser 文档中所述,现在我们提供了内置的配置模式。注意,当使用一个新的multiline.parser
定义,你必须在你的tail
中disable
(禁用)旧的配置,如:
- parser
- parser_firstline
- parser_N
- multiline
- multiline_flush
- docker_mode
2.2. 多行和容器 (v1.8)
如果您运行 Fluent Bit 来处理 Docker 或 CRI 等容器的日志,则可以为此使用新的内置模式。这将有助于重新组装原来由 Docker 或 CRI 分割的多行消息:
[INPUT]
name tail
path /var/log/containers/*.log
multiline.parser docker, cri
用逗号分隔的两个选项表示多种格式:尝试 docker 和 cri 的多行格式。
我们仍在努力扩展对嵌套堆栈跟踪等的多行支持。在 Fluent Bit v1.8.x 的发布周期中,我们将更新文档。
2.3. 旧的多行配置参数
对于旧的多行配置,存在以下选项来配置多行日志的处理:
参数 | 描述 | 默认值 |
---|---|---|
Multiline | 如果启用,插件将尝试发现多行消息,并使用适当的解析器来编写发送的消息。注意,当启用此选项时,不会使用 Parser 选项。 | Off |
Multiline_Flush | 处理排队的多行消息的等待时间周期(以秒为单位)。 | 4 |
Parser_Firstline | 匹配多行消息开头行的解析器名称。注意,在解析器中定义的正则表达式必须包括组名(命名捕获),并且最后一个匹配组的值必须是一个字符串。 | |
Parser_N | 可选的额外解析器,用于解释和构造多行条目。这个选项可以用来定义多个解析器,例如:Parser_1 ab1 ,Parser_2 ab2 ,Parser_N abN 。 |
2.4. 旧的 Docker 模式配置参数
Docker 模式的存在是为了重新组合由 Docker 守护进程分割(由于它的行长度限制)的 JSON 日志行。要使用这个特性,配置tail
插件的相应解析器,然后启用 Docker 模式:
参数 | 描述 | 默认值 |
---|---|---|
Docker_Mode | 如果启用,该插件将在被分割的 Docker 日志行传递给上述配置的任何解析器之前重新组合它们 ,该模式不能与 Multiline 模式同时使用。 | Off |
Docker_Mode_Flush | 刷新排队中未完成的拆分行所需的等待时间(以秒为单位)。 | 4 |
Docker_Mode_Parser | 为 docker 多行模式的第一行指定一个可选解析器。要指定的解析器名称必须在parser.conf 文件中注册。 |
3. 入门指南
为了跟踪文本或日志文件,你可以从命令行或通过配置文件运行插件:
3.1. 命令行
在命令行中,您可以使用以下选项让 Fluent Bit 解析文本文件:
$ fluent-bit -i tail -p path=/var/log/syslog -o stdout
3.2. 配置文件
在你的主配置文件中添加以下输入和输出部分。可以在这里找到一个可视化的例子:
[INPUT]
Name tail
Path /var/log/syslog
[OUTPUT]
Name stdout
Match *
3.3. 旧的多行示例
当使用多行配置时,您需要首先在配置中指定Multiline On
,并在需要时使用Parser_Firstline
和其他解析器参数Parser_N
。如果我们试图将下面的 Java Stacktrace 作为单个事件读取:
Dec 14 06:41:08 Exception in thread "main" java.lang.RuntimeException: Something has gone wrong, aborting!
at com.myproject.module.MyProject.badMethod(MyProject.java:22)
at com.myproject.module.MyProject.oneMoreMethod(MyProject.java:18)
at com.myproject.module.MyProject.anotherMethod(MyProject.java:14)
at com.myproject.module.MyProject.someMethod(MyProject.java:10)
at com.myproject.module.MyProject.main(MyProject.java:6)
我们需要指定一个Parser_Firstline
参数来匹配多行事件的第一行。一旦匹配成功,Fluent Bit 将读取所有未来的行,直到与Parser_Firstline
再次匹配。
在上面的例子中,我们可以使用下面的解析器,它将 Time 提取为time
,将 multiline 的其余部分提取为log
:
[PARSER]
Name multiline
Format regex
Regex /(?<time>Dec \d+ \d+\:\d+\:\d+)(?<message>.*)/
Time_Key time
Time_Format %b %d %H:%M:%S
如果我们想进一步解析整个事件,我们可以使用Parser_N
添加额外的解析器,其中N
是一个整数。最终的 Fluent Bit 配置如下所示:
# 注意,[PARSER] 通常被添加到 parser.conf 文件中,并在 [SERVICE] 中引用。
[PARSER]
Name multiline
Format regex
Regex /(?<time>Dec \d+ \d+\:\d+\:\d+)(?<message>.*)/
Time_Key time
Time_Format %b %d %H:%M:%S
[INPUT]
Name tail
Multiline On
Parser_Firstline multiline
Path /var/log/java.log
[OUTPUT]
Name stdout
Match *
我们的输出如下所示:
[0] tail.0: [1607928428.466041977, {"message"=>"Exception in thread "main" java.lang.RuntimeException: Something has gone wrong, aborting!
at com.myproject.module.MyProject.badMethod(MyProject.java:22)
at com.myproject.module.MyProject.oneMoreMethod(MyProject.java:18)
at com.myproject.module.MyProject.anotherMethod(MyProject.java:14)
at com.myproject.module.MyProject.someMethod(MyProject.java:10)", "message"=>"at com.myproject.module.MyProject.main(MyProject.java:6)"}]
4. 保持跟踪文件状态
tail
输入插件的一个特性,以保存跟踪文件的状态,强烈建议您启用此功能。为此,可以使用db
属性,例如:
$ fluent-bit -i tail -p path=/var/log/syslog -p db=/path/to/logs.db -o stdout
当运行时,会创建数据库文件/path/to/logs.db
,这个数据库由 SQLite3 支持,所以如果你有兴趣探索内容,你可以使用 SQLite 客户端工具打开它,例如:
$ sqlite3 tail.db
-- Loading resources from /home/edsiper/.sqliterc
SQLite version 3.14.1 2016-08-11 18:53:32
Enter ".help" for usage hints.
sqlite> SELECT * FROM in_tail_files;
id name offset inode created
----- -------------------------------- ------------ ------------ ----------
1 /var/log/syslog 73453145 23462108 1480371857
sqlite>
确保在 Fluent Bit 不努力处理数据库文件时进行浏览,否则您将看到一些错误:数据库被锁定的消息。
4.1. 格式化 SQLite
默认情况下,SQLite 客户端工具不会以人类容易读取的方式格式化列,所以要研究in_tail_files
表,可以在~/.sqliterc
中创建一个配置文件具有以下内容:
.headers on
.mode column
.width 5 32 12 12 10
5. SQLite 和 WAL
Fluent Bit 通过使用 SQLite 数据库文件来保持每个文件的状态或检查点,因此,如果服务重新启动,它可以继续从最后一个检查点位置(偏移量)消费文件。为了高性能和损坏安全,该选项默认启用。
启用的 SQLite 日志模式为Write Ahead Log
或WAL
。这可以提高对磁盘读写操作的性能。当启用时,您将在文件系统中看到正在创建的附加文件。
[INPUT]
name tail
path /var/log/containers/*.log
db test.db
上面的配置启用了一个名为test.db
的数据库文件,SQLite 将在该文件的相同路径上创建两个额外的文件:
- test.db-shm
- test.db-wal
这两个文件旨在支持WAL
机制,帮助提高性能并减少所需的系统调用。-wal
文件指的是存储要提交的新更改的文件,在某个点,WAL
文件事务会被移回真正的数据库文件。-shm
文件是一个共享内存类型,允许并发用户访问WAL
文件。
5.1. WAL 和内存使用率
WAL 机制为我们提供了更高的性能,但也可能增加 Fluent Bit 的内存使用。这种使用大部分来自内存映射和缓存页面。在某些情况下,您可能会看到内存使用量保持较高,给人以内存泄漏的印象,但实际上并不相关,除非您希望您的内存指标恢复正常。从 Fluent Bit v1.7.3 开始,我们引入了新的选项db.journal_mode
来设置数据库日志模式,默认情况下是WAL (Write-Ahead Logging)
,目前db.journal_mode
允许的配置是:DELETE
| TRUNCATE
| PERSIST
| MEMORY
| WAL
| OFF
。
6. 文件旋转
文件旋转被妥善处理,包括 logrotate 的copytruncate
模式。
注意,Path
模式不能匹配已旋转的文件。否则,将再次读取已旋转的文件并导致重复记录。