Metricset 详情
本主题提供了关于创建指标集的更多详细信息。
每个指标集都可以定义其自己的配置变量。要使用这些变量,必须扩展 New 方法。例如,假设你想向指标集添加一个 password 配置选项。你需要按如下方式扩展 beat.yml
metricbeat.modules:
- module: {module}
metricsets: ["{metricset}"]
password: "test1234"
要读取新的 password 配置选项,你需要修改 New 方法。首先,定义一个包含要读取的值类型的配置结构体。你可以根据需要设置默认值。然后,将该配置传递给 UnpackConfig 方法以加载配置。
你的实现应该类似于这样
type MetricSet struct {
mb.BaseMetricSet
password string
}
func New(base mb.BaseMetricSet) (mb.MetricSet, error) {
// Unpack additional configuration options.
config := struct {
Password string `config:"password"`
}{
Password: "",
}
err := base.Module().UnpackConfig(&config)
if err != nil {
return nil, err
}
return &MetricSet{
BaseMetricSet: base,
password: config.Password,
}, nil
}
每次调用 Fetch 方法时,它都会向服务发出请求,因此正确处理连接非常重要。我们建议你在 New 方法中建立连接,并将它们持久化在 MetricSet 对象中。这样可以复用连接。
非常重要的一点是,连接必须遵守超时变量:base.Module().Config().Timeout。如果请求在完成之前超时,则必须结束请求并返回错误,以确保下一个请求能按时开始。默认情况下,超时时间被设置为 Period(周期),因此在一个新请求发出之前,旧请求会被结束。
如果请求必须结束或发生错误,请确保返回有用的错误消息。此错误消息也会被发送到 Elasticsearch,这不仅可以从服务获取指标,还可以报告指标集可能存在的问题或错误。
如果 Fetch 方法中需要进行大量的数据转换,我们建议你在指标集所在的同一个包中创建第二个名为 data.go 的文件。data.go 文件应包含一个名为 eventMapping(...) 的函数。虽然不需要单独的文件,但目前这是一种最佳实践,因为它将指标集和 Fetch 方法的功能与数据映射分离开来。
你可以在 beats 代码仓库中为每个 metricbeat 模块找到多达 3 种不同类型的名为 fields.yml 的文件
metricbeat/fields.yml:包含创建 Elasticsearch 模板、Kibana 索引模式配置以及指标集导出字段文档的定义。为了确保 Elasticsearch 模板正确,保持此文件随所有更改同步更新非常重要。通常,你不应该手动修改此文件,因为它是由构建环境中的某些命令生成的。metricbeat/module/{{module}}/_meta/fields.yml:包含模块中所有指标集的通用顶层结构。通常,你只需要修改此文件中的描述。这是 MySQL 模块中fields.yml文件的一个示例。- key: mysql title: "MySQL" description: > MySQL server status metrics collected from MySQL. short_config: false release: ga version: beta: 9.0.0 ga: 9.1.0 fields: - name: mysql type: group description: > `mysql` contains the metrics that were obtained from MySQL query. fields:- 这用于添加产品生命周期和版本相关的标签,以说明产品是如何演变的。在此示例中,该模块在 9.0.0 版本中以 beta 版添加,并在 9.1.0 版本中正式发布 (GA)。阅读更多内容请参阅 为文档做贡献 > 累积文档。
metricbeat/module/{{module}}/{metricset}/_meta/fields.yml:包含指标集检索到的所有字段定义。作为字段类型,每个字段必须具有 Elasticsearch 支持的核心数据类型。这是一个非常基础的示例,展示了 MySQLstatus指标集中的一个组- name: status type: group description: > `status` contains the metrics that were obtained by the status SQL query. version: ga: 9.0.0 fields: - name: aborted type: group description: Aborted status fields. fields: - name: clients type: integer description: > The number of connections that were aborted because the client died without closing the connection properly. - name: connects type: integer version: beta: 9.1.0 description: > The number of failed attempts to connect to the MySQL server.- 这用于添加产品生命周期和版本相关的标签,以说明产品是如何演变的。在此示例中,该指标集在 9.0.0 版本中以 GA 版添加。阅读更多内容请参阅 为文档做贡献 > 累积文档。
- 这说明在 9.1.0 版本中,一个新字段以 beta 版被添加到现有的指标集中。
为你的指标集添加测试也很重要。测试 Beat 需要三种不同类型的测试
- 单元测试
- 集成测试
- 系统测试
我们建议你在创建指标集时使用这三种测试。单元测试是用 Go 编写的,没有任何依赖。集成测试也是用 Go 编写的,但需要模块收集指标的服务也在运行。Metricbeat 的系统测试在大多数情况下也需要服务在运行,并且是基于我们的小型 Python 测试框架用 Python 编写的。我们使用 venv 来处理 Python 依赖。你可以直接运行命令 make python-env,然后运行 . build/python-env/bin/activate 。
你应该结合使用这三种测试类型来测试你的指标集,因为每种方法都有其优缺点。要开始编写你自己的测试,最好先查看现有的测试。你可以在现有模块和指标集下的 _test.go 文件中找到单元测试和集成测试。集成测试通常采用 TestFetch 和 TestData 的形式。系统测试位于 tests/systems 下。
集成测试和系统测试需要一个运行服务的环境。你可以使用 Docker 和 docker compose 文件来创建此环境。如果你添加了一个需要服务的模块,则必须将该服务添加到虚拟环境中。为此,你需要
- 更新你的环境对应的
docker-compose.yml文件 - 更新
docker-entrypoint.sh脚本
docker-compose.yml 文件位于 Metricbeat 的根目录。大多数服务都有现成的 Docker 模块,可以像添加 Redis 一样简单地添加它们
redis:
image: redis:3.2.3
为了允许 Beat 访问你的服务,请确保在 docker compose 文件中定义了环境变量,并添加了指向容器的链接
beat:
links:
- redis
environment:
- REDIS_HOST=redis
- REDIS_PORT=6379
为了确保在测试开始之前服务正在运行,请修改 docker-entrypoint.sh 脚本,添加一个验证服务是否正在运行的检查。例如,Redis 的检查如下所示
waitFor ${REDIS_HOST} ${REDIS_PORT} Redis
该环境要求你的服务一旦从给定的地址和端口收到响应,即视为可用。
每个指标集通常都包含两个集成测试:TestFetch 和 TestData。这两个测试都会启动你的指标集的一个新实例并获取一个事件。为了启动指标集,你需要创建一个配置对象
func getConfig() map[string]interface{} {
return map[string]interface{}{
"module": "{module}",
"metricsets": []string{"{metricset}"},
"hosts": []string{GetEnvHost() + ":" + GetEnvPort()},
}
}
func GetEnvHost() string {
host := os.Getenv("{module}_HOST")
if len(host) == 0 {
host = "127.0.0.1"
}
return host
}
func GetEnvPort() string {
port := os.Getenv("{module}_PORT")
if len(port) == 0 {
port = "1234"
}
return port
}
- 在此处添加你的指标集所需的任何其他配置选项。
- 指标集使用的端点需要可配置,以便进行手动和自动测试。环境变量应在模块下的
_meta/env中定义,并包含在 docker compose 文件中。
TestFetch 集成测试将返回来自你的指标集的单个事件,你可以使用它来测试数据的有效性。TestData 将(重新)生成记录指标集所报告数据的 _meta/data.json 文件。
import (
"os"
"testing"
"github.com/stretchr/testify/assert"
"github.com/elastic/beats/libbeat/tests/compose"
mbtest "github.com/elastic/beats/metricbeat/mb/testing"
)
func TestFetch(t *testing.T) {
compose.EnsureUp(t, "{module}")
f := mbtest.NewReportingMetricSetV2Error(t, getConfig())
events, errs := mbtest.ReportingFetchV2Error(f)
if len(errs) > 0 {
t.Fatalf("Expected 0 errord, had %d. %v\n", len(errs), errs)
}
assert.NotEmpty(t, events)
}
func TestData(t *testing.T) {
f := mbtest.NewReportingMetricSetV2Error(t, getConfig())
err := mbtest.WriteEventsReporterV2Error(f, t, "")
if !assert.NoError(t, err) {
t.FailNow()
}
}
- 使用此命令启动与你的指标集关联的 docker 服务。
- 添加任何进一步的有效性检查以验证指标集是否正常工作。
WriteEventsReporterV2Error将获取指标集中的第一个有效事件并将其写入_meta/data.json
要运行所有测试,请运行 make testsuite。如果只想运行单元测试,请运行 mage unitTest;对于集成测试,请运行 mage integTest。请注意,集成测试和系统测试需要运行 Docker 环境。
要运行 TestData 并生成 data.json 文件,请在测试所在的目录中运行 go test -tags=integration -data -run TestData。
要运行单个模块的集成测试,请将 MODULE 环境变量设置为模块目录的名称。例如,你可以运行以下命令来运行 apache 模块的集成测试
MODULE=apache mage integTest
每个模块都必须有文档。文档基于 Markdown,模块的文档位于 module/{{module}}/_meta/docs.md 文件中,指标集的文档位于 module/{{module}}/{metricset}/_meta/docs.md 中。包含配置文件和输出示例的基础文档会自动生成。请使用这些文件来记录具体的配置选项或使用示例。