创建新的 Filebeat 模块
Elastic 不对用于生成模块和 fileset 的代码提供任何保证或支持。该生成器主要作为希望创建自己的数据传输器的开发人员的指导。
本指南将引导您创建新的 Filebeat 模块。
所有 Filebeat 模块目前都位于主 Beats 存储库中。要克隆存储库并构建 Filebeat(您需要它进行测试),请按照 贡献到 Beats 中的一般说明进行操作。
每个 Filebeat 模块由一个或多个“fileset”组成。我们通常为我们支持的每个服务创建一个模块(Nginx 的 nginx
,Mysql 的 mysql
,等等),并为该服务创建的每种类型的日志创建一个 fileset。例如,Nginx 模块具有 access
和 error
fileset。您可以贡献一个新的模块(至少包含一个 fileset),或者为现有模块贡献一个新的 fileset。
在本指南中,我们使用 {{module}}
和 {{fileset}}
作为模块和 fileset 名称的占位符。您需要将这些替换为您创建模块和 fileset 时输入的实际名称。仅使用字符 [a-z]
,如果需要,可以使用下划线 (_
)。不允许使用其他字符。
在 filebeat
文件夹中运行以下命令
make create-module MODULE={module}
运行 make create-module
命令后,您将在 module/{{module}}
下找到该模块及其生成的文件。此目录包含以下文件
module/{module}
├── module.yml
└── _meta
└── docs.asciidoc
└── fields.yml
└── kibana
让我们逐个查看这些文件。
此文件包含模块可用的所有仪表板的列表,并由 export_dashboards.go
脚本用于导出仪表板。每个仪表板由一个 ID 和一个 JSON 文件的名称定义,仪表板本地保存在该文件中。在生成新的 fileset 时,此文件将自动使用新的 fileset 的“默认”仪表板设置进行更新。请确保此设置正确。
此文件包含模块特定的文档。您应该包含有关已测试的服务的哪些版本以及每个 fileset 中定义的变量的信息。
模块级别的 fields.yml
包含模块级别字段的描述。请查看并更新此文件中的标题和描述。标题用作文档中的标题,因此最好将其大写。
此文件夹包含此模块的示例 Kibana 仪表板。要创建它们,您可以在 Kibana 中以可视方式构建它们,然后使用 export_dashboards
导出它们。
该工具将自动导出所有仪表板依赖项(可视化,已保存的搜索)。
您可以在 导出新的和修改过的 Beat 仪表板 中看到使用 export_dashboards
的各种方法。导出它们的推荐方法是在模块的 module.yml
文件中列出您的仪表板
dashboards:
- id: 69f5ae20-eb02-11e7-8f04-beef1daadb05
file: mymodule-overview.json
- id: c0a7ce90-cafe-4242-8647-534bb4c21040
file: mymodule-errors.json
然后像这样运行 export_dashboards
$ cd dev-tools/cmd/dashboards
$ make
$ ./export_dashboards --yml '../../../filebeat/module/{module}/module.yml'
- 如果 export_dashboard 尚未构建
新的 Filebeat 模块可能与 Kibana 5.x 不兼容。要导出与 5.x 兼容的仪表板,请在开发人员虚拟环境中运行以下命令
$ cd filebeat
$ make python-env
$ cd module/{module}/
$ python ../../../dev-tools/export_5x_dashboards.py --regex {module} --dir _meta/kibana/5.x
其中 --regex
参数应与您要导出的仪表板匹配。
请注意,从 Kibana 5.x 导出的仪表板与 Kibana 6.x 不兼容。
您可以通过阅读 本指南 找到有关创建和导出 Kibana 仪表板的更多详细信息。
在 filebeat
文件夹中运行以下命令
make create-fileset MODULE={module} FILESET={fileset}
运行 make create-fileset
命令后,您将在 module/{{module}}/{fileset}
下找到该 fileset 及其生成的文件。此目录包含以下文件
module/{module}/{fileset}
├── manifest.yml
├── config
│ └── {fileset}.yml
├── ingest
│ └── pipeline.json
├── _meta
│ └── fields.yml
│ └── kibana
│ └── default
└── test
让我们逐个查看这些文件。
manifest.yml
是模块的控制文件,变量在其中定义并引用其他文件。它是一个 YAML 文件,但在文件的许多地方,您可以使用 {{.variable}}
语法使用内置或定义的变量。
文件的 var
部分定义了 fileset 变量及其默认值。模块变量可以在其他配置文件中引用,并且它们的值可以在运行时被 Filebeat 配置覆盖。
作为 fileset 创建者,您可以为定义的变量使用任何名称。每个变量必须具有默认值。因此,以最简单的形式,这就是您可以定义新变量的方式
var:
- name: pipeline
default: with_plugins
大多数 fileset 应该定义一个 paths
变量,该变量设置日志文件所在的默认路径
var:
- name: paths
default:
- /example/test.log*
os.darwin:
- /usr/local/example/test.log*
- /example/test.log*
os.windows:
- c:/programdata/example/logs/test.log*
此文件中有很多内容,所以让我们分解一下
- 变量的名称为
paths
,默认值是包含一个元素的数组:"/example/test.log*"
。 - 请注意,变量值不必是字符串。它们也可以是数字、对象或如此示例中所示的数组。
- 我们将使用
paths
变量来设置输入paths
设置,因此可以在此处使用“glob”值。 - 除了
default
值之外,该文件还定义了特定操作系统的值:darwin/OS X/macOS 系统的默认值和 Windows 系统的默认值。这些是通过os.darwin
和os.windows
关键字引入的。如果在相应的操作系统上执行 Filebeat,则这些键下的值将成为变量的默认值。
除了变量定义之外,manifest.yml
文件还包含对要使用的摄取管道和输入配置的引用(请参阅下一节)
ingest_pipeline: ingest/pipeline.json
input: config/testfileset.yml
这些应该指向 fileset 中的相应文件。
请注意,在评估这些文件的内容时,变量会展开,这使您可以根据变量的值选择一个或另一个文件。例如
ingest_pipeline: ingest/{{.pipeline}}.json
此示例根据 pipeline
变量的值选择摄取管道文件。对于前面显示的 pipeline
变量,该路径将解析为 ingest/with_plugins.json
(假设变量值在运行时未被覆盖。)
在 6.6 及更高版本中,您可以指定多个摄取管道。
ingest_pipeline:
- ingest/main.json
- ingest/plain_logs.json
- ingest/json_logs.json
指定多个摄取管道时,列表中的第一个被认为是入口点管道。
使用多个管道的一个原因可能是将此 fileset 收集的所有日志发送到入口点管道,并让它将处理的不同部分委托给其他管道。您可以在 ingest/*.json
部分中阅读有关设置此过程的详细信息。
config/
文件夹包含生成 Filebeat 输入配置的模板文件。Filebeat 输入主要负责跟踪文件、过滤和多行拼接,因此这就是您在模板文件中配置的内容。
一个典型的例子如下所示
type: log
paths:
{{ range $i, $path := .paths }}
- {{$path}}
{{ end }}
exclude_files: [".gz$"]
您将在运行 make create-fileset
时自动生成的模板文件中找到此示例。在此示例中,paths
变量用于构造输入 paths
选项的 paths
列表。
您添加到 config/
文件夹的任何模板文件都需要生成 YAML 格式的有效 Filebeat 输入配置。Filebeat 文档的 Filebeat 输入 部分中记录了输入配置接受的选项。
模板文件使用 Go 标准库 定义的模板语言。
这是另一个也配置多行拼接的示例
type: log
paths:
{{ range $i, $path := .paths }}
- {{$path}}
{{ end }}
exclude_files: [".gz$"]
multiline:
pattern: "^# User@Host: "
negate: true
match: after
虽然您可以在 config/
文件夹下添加多个配置文件,但只会加载 manifest.yml
文件指示的文件。您可以使用变量来动态切换配置。
ingest/
文件夹包含 Elasticsearch 摄取管道配置。摄取管道负责解析日志行并对数据进行其他操作。
此文件夹中的文件是表示 管道定义 的 JSON 或 YAML 文档。就像 config/
文件夹一样,您可以定义多个管道,但只有一个管道在运行时基于 manifest.yml
中的信息加载。
生成器会创建一个类似于此 JSON 对象的对象
{
"description": "Pipeline for parsing {module} {fileset} logs",
"processors": [
],
"on_failure" : [{
"set" : {
"field" : "error.message",
"value" : "{{ _ingest.on_failure_message }}"
}
}]
}
或者,您可以使用 YAML 格式的管道,它使用更简单的语法
description: "Pipeline for parsing {module} {fileset} logs"
processors:
on_failure:
- set:
field: error.message
value: "{{ _ingest.on_failure_message }}"
从这里,您通常会将处理器添加到 processors
数组以进行实际解析。有关可用摄取处理器的信息,请参阅 处理器参考文档。特别是,您可能会发现 grok 处理器 对于解析很有用。这是一个用于解析 Nginx 访问日志的示例。
{
"grok": {
"field": "message",
"patterns":[
"%{IPORHOST:nginx.access.remote_ip} - %{DATA:nginx.access.user_name} \\[%{HTTPDATE:nginx.access.time}\\] \"%{WORD:nginx.access.method} %{DATA:nginx.access.url} HTTP/%{NUMBER:nginx.access.http_version}\" %{NUMBER:nginx.access.response_code} %{NUMBER:nginx.access.body_sent.bytes} \"%{DATA:nginx.access.referrer}\" \"%{DATA:nginx.access.agent}\""
],
"ignore_missing": true
}
}
请注意,您应该遵循以模块和文件集名称为前缀的字段命名约定:{{module}}.{fileset}.field
,例如 nginx.access.remote_ip
。此外,请查看我们的命名约定。
在 6.6 及更高版本中,摄取管道可以使用 pipeline
处理器 将部分处理委托给其他管道。
如果您希望文件集摄取以不同格式呈现的相同逻辑信息,例如同一日志文件的 csv 与 json 版本,这将非常有用。 想象一下一个入口点摄取管道,它检测日志条目的格式,然后有条件地将该日志条目的进一步处理(取决于格式)委托给另一个管道。
{
"processors": [
{
"grok": {
"field": "message",
"patterns": [
"^%{CHAR:first_char}"
],
"pattern_definitions": {
"CHAR": "."
}
}
},
{
"pipeline": {
"if": "ctx.first_char == '{'",
"name": "{< IngestPipeline "json-log-processing-pipeline" >}"
}
},
{
"pipeline": {
"if": "ctx.first_char != '{'",
"name": "{< IngestPipeline "plain-log-processing-pipeline" >}"
}
}
]
}
- 使用
IngestPipeline
模板函数来解析名称。此函数将指定的名称转换为存储在 Elasticsearch 中的完全限定的管道 ID。
为了使上述管道正常工作,Filebeat 必须将入口点管道以及任何子管道加载到 Elasticsearch 中。 您可以通过在其 manifest.yml
文件中指定文件集的所有必要管道来告诉 Filebeat 这样做。 列表中的第一个管道被认为是入口点管道。
ingest_pipeline:
- ingest/main.json
- ingest/plain_logs.yml
- ingest/json_logs.json
在开发管道定义时,我们建议使用 Simulate Pipeline API 进行测试和快速迭代。
默认情况下,如果已加载 Ingest 管道,Filebeat 不会更新它。 如果您想在开发期间强制更新管道,请使用 ./filebeat setup --pipelines
命令。 即使节点上已经存在管道,这也会上传管道。
fields.yml
文件包含文件集中字段的顶层结构。 它用作以下内容的真实来源:
- 生成的 Elasticsearch 映射模板
- 生成的 Kibana 索引模式
- 导出的字段的生成文档
除了文件集中的 fields.yml
文件之外,模块级别还有一个 fields.yml
文件,位于 module/{{module}}/_meta/fields.yml
下,其中应包含在模块级别定义的字段以及模块本身的描述。 在大多数情况下,您应该在文件集级别添加字段。
创建 pipeline.json
后,可以生成一个基本的 field.yml
。
make create-fields MODULE={module} FILESET={fileset}
请始终检查生成的文件,并确保字段正确。 您必须手动添加字段文档。
如果字段正确,现在可以生成文档、配置和 Kibana 索引模式了。
make update
在 test/
目录中,您应该放置由服务生成的示例日志文件。 我们有集成测试,由 CI 自动执行,它将在 test/
文件夹下的每个日志文件上运行 Filebeat,并检查是否存在解析错误以及是否记录了所有字段。
此外,假设您有一个 test.log
文件,您可以在同一目录中添加一个 test.log-expected.json
文件,其中包含通过 Elasticsearch 搜索找到的预期文档。 在这种情况下,集成测试将自动检查每次运行的结果是否相同。
为了使用示例日志测试文件集和/或生成预期的输出,应该在 Filebeat 目录下使用以下过程在本地运行特定模块的测试
在本地启动一个 Elasticsearch 实例。 例如,使用 Docker
docker run \ --name elasticsearch \ -p 9200:9200 -p 9300:9300 \ -e "xpack.security.http.ssl.enabled=false" -e "ELASTIC_PASSWORD=changeme" \ -e "discovery.type=single-node" \ --pull always --rm --detach \ docker.elastic.co/elasticsearch/elasticsearch:master-SNAPSHOT
在该 Elasticsearch 实例上创建一个“admin”用户
curl -u elastic:changeme \ http://localhost:9200/_security/user/admin \ -X POST -H 'Content-Type: application/json' \ -d '{"password": "changeme", "roles": ["superuser"]}'
创建测试二进制文件:
make filebeat.test
更新 fields yaml:
make update
创建 python 环境:
make python-env
激活 python 环境:
source ./build/python-env/bin/activate
运行测试,例如检查 nginx 访问日志解析
INTEGRATION_TESTS=1 BEAT_STRICT_PERMS=false ES_PASS=changeme \ TESTING_FILEBEAT_MODULES=nginx \ pytest tests/system/test_modules.py -v --full-trace
根据需要添加和删除选项环境变量。 这里有一些有用的
TESTING_FILEBEAT_ALLOW_OLDER
:如果设置为 1,则允许连接旧版本的 ElasticsearchTESTING_FILEBEAT_MODULES
:要测试的模块的逗号分隔列表。TESTING_FILEBEAT_FILESETS
:要测试的文件集的逗号分隔列表。TESTING_FILEBEAT_FILEPATTERN
:要测试的文件集中日志文件的 glob 模式。GENERATE
:如果设置为 1,则将生成预期的文档。
filebeat 日志写入到 build
目录。 使用 tail -F build/system-tests/run/test_modules.Test.*/output.log
在另一个终端中追踪它们可能很有用。
例如,如果摄取管道中存在语法错误,则测试可能会挂起。 filebeat 日志输出将包含来自 elasticsearch 的错误消息。