加载中

创建新的 Filebeat 模块

重要提示

Elastic 不对用于生成模块和文件集的代码提供任何保证或支持。该生成器主要作为指南提供,供希望创建自己的数据采集器的开发人员参考。

本指南将引导您完成创建新 Filebeat 模块的过程。

目前所有的 Filebeat 模块都位于主要的 Beats 仓库中。要克隆仓库并构建 Filebeat(测试时需要),请遵循 Contributing to Beats(贡献 Beats) 中的通用说明。

每个 Filebeat 模块由一个或多个“文件集”组成。我们通常为支持的每个服务创建一个模块(例如 Nginx 的 nginx,Mysql 的 mysql 等),并为该服务创建的每种日志创建一个文件集。例如,Nginx 模块具有 accesserror 文件集。您可以贡献一个新模块(包含至少一个文件集),或者为现有模块贡献一个新的文件集。

注意

在本指南中,我们使用 {{module}}{{fileset}} 作为模块和文件集名称的占位符。您需要将它们替换为您创建模块和文件集时输入的实际名称。仅使用 [a-z] 字符,如果需要,可以使用下划线 (_)。不允许使用其他字符。

filebeat 文件夹中运行以下命令

make create-module MODULE={module}
		

运行 make create-module 命令后,您将在 module/{{module}} 下找到该模块及其生成的文件。该目录包含以下文件

module/{module}
├── module.yml
└── _meta
    └── docs.md
    └── fields.yml
    └── kibana
		

让我们逐一查看这些文件。

该文件包含模块所有可用仪表板的列表,并由 export_dashboards.go 脚本用于导出仪表板。每个仪表板由 ID 和本地保存仪表板的 JSON 文件名定义。生成新文件集时,此文件将自动使用新文件集的“默认”仪表板设置进行更新。请确保这些设置正确。

该文件包含模块特定的文档。您应该包括有关测试了哪些服务版本以及每个文件集中定义了哪些变量的信息。

模块级 fields.yml 包含模块级字段的描述。

创建默认文件后,请确保

  • 更新模块和每个字段的 description(描述)。
  • 添加一个 version 属性,其中包含有关产品生命周期和添加该模块的版本的信息。例如,如果一个模块是在 Elastic Stack 9.1.0 版本中以 beta 形式添加的
    - key: {module}
      title: "{module}"
      version:
        beta: 9.1.0
      description: >
        {module} module
    		

有关微调 fields.yml 文件以生成文档的更多提示,请参阅 贡献文档 > 更新 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'
		
  1. 如果尚未构建 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} 下找到该文件集及其生成的文件。该目录包含以下文件

module/{module}/{fileset}
├── manifest.yml
├── config
│   └── {fileset}.yml
├── ingest
│   └── pipeline.json
├── _meta
│   └── fields.yml
│   └── kibana
│       └── default
└── test
		

让我们逐一查看这些文件。

manifest.yml 是该模块的控制文件,用于定义变量并引用其他文件。它是一个 YAML 文件,但在文件中的许多地方,您可以使用 {{.variable}} 语法来使用内置或已定义的变量。

文件的 var 部分定义了文件集变量及其默认值。模块变量可以在其他配置文件中引用,并且它们的值可以在运行时通过 Filebeat 配置进行覆盖。

作为文件集创建者,您可以为定义的变量使用任何名称。每个变量必须有一个默认值。因此,最简单的形式如下所示,您可以如何定义一个新变量

var:
  - name: pipeline
    default: with_plugins
		

大多数文件集都应该定义一个 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.darwinos.windows 关键字引入的。如果 Filebeat 在相应的操作系统上执行,这些键下的值将成为该变量的默认值。

除了变量定义之外,manifest.yml 文件还包含对要使用的采集管道和输入配置的引用(请参阅后续章节)

ingest_pipeline: ingest/pipeline.json
input: config/testfileset.yml
		

这些应该指向文件集中的相应文件。

请注意,在评估这些文件的内容时,变量会被展开,这使您可以根据变量的值选择一个文件或另一个文件。例如

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
		

当指定多个采集管道时,列表中的第一个被视为入口管道。

使用多个管道的一个原因可能是将此文件集收集的所有日志发送到入口管道,并让它将处理的不同部分委托给其他管道。您可以在 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 Inputs(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" >}"
      }
    }
  ]
}
		
  1. 使用 IngestPipeline 模板函数来解析名称。此函数将指定的名称转换为存储在 Elasticsearch 中的完全限定管道 ID。

为了使上述管道正常工作,Filebeat 必须将入口管道以及任何子管道加载到 Elasticsearch 中。您可以通过在其 manifest.yml 文件中为文件集指定所有必要的管道来告知 Filebeat 这样做。列表中的第一个管道被视为入口管道。

ingest_pipeline:
  - ingest/main.json
  - ingest/plain_logs.yml
  - ingest/json_logs.json
		

在开发管道定义时,我们建议利用 Simulate Pipeline API(模拟管道 API) 进行测试和快速迭代。

默认情况下,如果已加载,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 目录下按照以下过程在本地运行测试

  1. 在本地启动 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
    		
  2. 在该 Elasticsearch 实例上创建一个 "admin" 用户

    curl -u elastic:changeme \
      https://:9200/_security/user/admin \
      -X POST -H 'Content-Type: application/json' \
      -d '{"password": "changeme", "roles": ["superuser"]}'
    		
  3. 创建测试二进制文件: make filebeat.test

  4. 更新 fields yaml: make update

  5. 创建 python 环境: make python-env

  6. 加载 python 环境: source ./build/python-env/bin/activate

  7. 运行测试,例如检查 nginx 访问日志解析

    INTEGRATION_TESTS=1 BEAT_STRICT_PERMS=false ES_PASS=changeme \
    TESTING_FILEBEAT_MODULES=nginx \
    pytest tests/system/test_modules.py -v --full-trace
    		
  8. 根据需要添加和删除选项环境变量。以下是一些有用的环境变量

    • TESTING_FILEBEAT_ALLOW_OLDER:如果设置为 1,则允许连接较旧版本的 Elasticsearch
    • TESTING_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 的错误消息。

© . This website operates independently and is not affiliated with or endorsed by Elasticsearch B.V. All brand names, logos, and trademarks are the property of their respective owners.