Metricset 详情
本主题提供关于创建 metricset 的更多详情。
每个 metricset 都可以定义自己的配置变量。要使用这些变量,您必须扩展 New
方法。 例如,假设您想向 metricset 添加一个 password
配置选项。 您需要按以下方式扩展 beat.yml
:
metricbeat.modules:
- module: {module}
metricsets: ["{metricset}"]
password: "test1234"
要读取新的 password
配置选项,您需要修改 New
方法。首先,您定义一个包含要读取的值类型的 config struct。 您可以根据需要设置默认值。 然后,将 config 传递给 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,从而不仅可以从服务中获取指标,还可以报告 metricset 的潜在问题或错误。
如果必须在 Fetch
方法中进行大量数据转换,我们建议您在与 metricset 相同的包中创建一个名为 data.go
的第二个文件。data.go
文件应包含一个名为 eventMapping(...)
的函数。 虽然不需要单独的文件,但这是目前最好的实践,因为它将 metricset 和 Fetch
方法的功能与数据映射隔离开来。
您可以在每个 metricbeat 模块的 beats 存储库中找到最多 3 种不同类型的文件,名为 fields.yml
metricbeat/fields.yml
: 包含用于创建 Elasticsearch 模板、Kibana 索引模式配置和 metricset 的导出字段文档的定义。 为了确保 Elasticsearch 模板正确,请务必使用所有更改来更新此文件。 通常,您不应手动触摸此文件,因为它是由构建环境中的某些命令生成的。metricbeat/module/{{module}}/_meta/fields.yml
: 包含模块中所有 metricset 的常规顶级结构。 通常,您只需要修改此文件中的描述。 这是来自 MySQL 模块的fields.yml
文件的示例。- key: mysql title: "MySQL" description: > MySQL server status metrics collected from MySQL. short_config: false release: ga fields: - name: mysql type: group description: > `mysql` contains the metrics that were obtained from MySQL query. fields:
metricbeat/module/{{module}}/{metricset}/_meta/fields.yml
: 包含 metricset 检索的所有字段定义。 作为字段类型,每个字段必须具有 elasticsearch 支持的 核心数据类型。 这是一个非常基本的示例,显示了 MySQLstatus
metricset 中的一个组- name: status type: group description: > `status` contains the metrics that were obtained by the status SQL query. 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 description: > The number of failed attempts to connect to the MySQL server.
为您的 metricset 添加测试也很重要。 您需要三种不同类型的测试来测试 Beat
- 单元测试
- 集成测试
- 系统测试
我们建议您在创建 metricset 时使用所有三种测试。 单元测试是用 Go 编写的,没有依赖项。 集成测试也是用 Go 编写的,但需要运行模块从中收集指标的服务。 Metricbeat 的系统测试也需要在大多数情况下运行该服务,并且是用 Python 编写的,基于我们的小型 Python 测试框架。 我们使用 venv 来处理 Python 依赖项。 您可以简单地运行命令 make python-env
,然后运行 . build/python-env/bin/activate
。
您应该使用三种测试类型的组合来测试您的 metricset,因为每种方法都有优点和缺点。 要开始您自己的测试,最好查看现有测试。 您将在现有模块和 metricset 下的 _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
该环境希望您的服务在收到来自给定地址和端口的响应后立即可用。
通常,每个 metricset 都有两个集成测试:TestFetch
和 TestData
。 这两个测试都将启动一个新的 metricset 实例并获取一个事件。 为了启动一个 metricset,您需要创建一个配置对象
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
}
- 在此处添加您的 metricset 需要的任何其他配置选项。
- metricset 使用的端点需要可配置,以进行手动和自动测试。 环境变量应在模块下的
_meta/env
中定义,并包含在docker-compose.yml
文件中。
TestFetch
集成测试将从您的 metricset 返回一个事件,您可以使用该事件来测试数据的有效性。 TestData
将(重新)生成 _meta/data.json
文件,该文件记录 metricset 报告的数据。
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()
}
}
- 使用它来启动与您的 metricset 关联的 docker 服务。
- 添加任何进一步的有效性检查以验证 metricset 是否正常工作。
WriteEventsReporterV2Error
将从 metricset 中获取第一个有效事件并将其写入_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
每个模块都必须记录在案。 该文档基于 asciidoc,位于模块的 module/{{module}}/_meta/docs.asciidoc
文件中,以及 metricset 的 module/{{module}}/{metricset}/_meta/docs.asciidoc
文件中。 带有配置文件和示例输出的基本文档会自动生成。 使用这些文件来记录特定的配置选项或使用示例。