Telegraf:Go 集成代理
作者:Noah Crowley / 用例,产品,开发者
2018年1月25日
导航到
收集代理是任何监控基础设施的关键部分:它们可以在您的宿主上运行,收集有关您的系统和应用程序的数据,或者它们可以在远程操作,通过您的应用程序暴露的端点在网络中收集数据。
2015年,InfluxData 发布了 Telegraf:一个由 Go 编写的轻量级、插件驱动的收集代理。虽然许多开发者已经使用各种收集代理将指标发送到 InfluxDB 和其他时间序列数据库,但 InfluxData 想要一个围绕标签度量概念设计的项目,这是 InfluxDB 和 OpenTSDB 等数据库中使用的数据模型。
Telegraf 具有基于插件的架构,并且设计成让用户可以轻松地为项目贡献功能,而无需了解任何代码库。Telegraf 有四种不同的插件类型:输入、处理器、聚合器和输出插件,每个插件处理数据路径的一部分。自 2015 年成立以来,Telegraf 插件的数量已增长到超过 150 个——其中大部分都是由社区贡献的——使 Telegraf 能够从各种输入收集指标并将它们写入各种输出。
一些示例插件
postgresql
一个输入插件,可以收集关于您 Postgres 安装的性能指标。它使用内置的pg_stat_database
和pg_stat_bgwriter
视图中的数据。apache
一个输入插件,使用 mod_status 模块从 Apache HTTP 服务器 收集服务器性能信息prometheus
一个输入插件,从暴露 Prometheus 格式指标的 HTTP 服务器收集指标。influxdb
一个输出插件,通过 HTTP 或 UDP 将数据写入 InfluxDBopentsdb
一个输出插件,通过“telnet”或 HTTP 模式将数据写入 OpenTSDB 实例
使用 Telegraf
如果您想运行 Telegraf,首先 安装 Telegraf。
Telegraf具有根据您指定的插件生成配置文件的能力。您可以在运行Telegraf时使用-sample-config
参数创建新的配置。
$ telegraf -sample-config -input-filter apache -output filter influxdb > telegraf.conf
这将创建一个位于您工作目录下的telegraf.conf
文件。接下来,您可以使用新配置启动Telegraf。
$ telegraf -config telegraf.conf
如果您以服务形式运行Telegraf,则需要将新生成的配置文件放入适当的目录(例如Linux上的/etc/telegraf
),然后重启Telegraf。在Debian / Ubuntu上,配置文件将放入/etc/telegraf
,而可以使用systemctl restart telegraf
命令重启Telegraf。
接口 & 编写插件
Telegraf使用Go接口实现插件。每种插件类型由一个接口定义,编写新插件就像实现这些接口并将您的插件导入Telegraf主包一样简单。
如果您已创建新插件,或修复或添加了现有插件的功能,请在GitHub上提交PR并分享您的辛勤工作!对于贡献者来说,还有一些额外的步骤需要完成,例如添加适当的文档和测试,您可以在Telegraf仓库中的贡献文档中找到更多关于这些信息。
该文档还提供了有关编写Telegraf不同插件接口的详细信息。
入门
如果您对开发自己的Telegraf插件感兴趣,您需要在您的机器上安装Go 1.5+。Golang网站有一个很好的入门指南,其中包含安装说明和下载页面链接。
安装Go后,使用go get
下载Telegraf源代码,在git中检出您的工作分支,并尝试使用make
构建二进制文件。
$ go get github.com/influxdata/telegraf
$ cd $GOPATH/github.com/influxdata/telegraf
$ git checkout -b MyPlugin $ make
源代码将被下载到您的Gopath中的src
目录,而make
命令将在bin
目录下创建Telegraf二进制文件。
让我们看看一个现有的示例。Telegraf有一个名为Trig的插件,它通常用于演示目的,并基于三角函数正弦和余弦发出数据。我们将在下一节中介绍创建Trig插件的过程。
输入插件
首先,将以下行添加到telegraf/plugins/inputs/all/all.go
github.com/influxdata/telegraf/plugin/inputs/trig
以导入您的插件并确保Telegraf可以运行您编写的代码。因为任何创建插件的任何人都需要编辑此文件,所以在准备合并代码时可能会遇到合并冲突。但是,在开始本地开发之前添加此信息是必不可少的——没有它,您编写的代码将无法运行。
Telegraf的输入插件只需要满足三个接口。从Godoc
type Input interface {
// SampleConfig returns the default configuration of the Input
SampleConfig() string
// Description returns a one-sentence description on the Input
Description() string
// Gather takes in an accumulator and adds the metrics that the Input
// gathers. This is called every "interval"
Gather(Accumulator) error }
都使用Description
和SampleConfig
,Telegraf用于生成配置文件。Telegraf配置使用TOML编写;每个部分前面都有一个包含Description()
函数返回的字符串的一行注释,后面是插件本身的配置变量,由SampleConfig()
函数返回。
插件配置有一个变量,即amplitude
# Inserts sine and cosine waves for demonstration purposes
[[inputs.trig]]
## Set the amplitude
amplitude = 10.0
以下是trig.go中的实现
var TrigConfig = `
## Set the amplitude
amplitude = 10.0
`
func (s *Trig) SampleConfig() string {
return TrigConfig
}
func (s *Trig) Description() string {
return "Inserts sine and cosine waves for demonstration purposes"
}
注意:在编写TOML配置时,请确保使用两个空格来缩进一行,而不是制表符,这样当Telegraf生成配置时,您的条目就可以很好地与其他条目对齐。
对于输入插件来说,最后的接口方法是Gather
。这就是我们收集输入数据所有相关工作的地方。在这个阶段,它返回nil,因为我们还没有为Gather
方法添加任何代码,但我们可以继续构建Telegraf并测试生成配置以确保其工作正常。
在您的当前工作目录中输入以下内容:
$ make $ telegraf -sample-config -input-filter trig -output-filter influxdb -debug
-debug
标志会向输出添加额外的信息,以帮助识别您可能遇到的问题。
您应该在输出的底部看到以下内容:
#
# INPUTS:
#
# Inserts sine and cosine waves for demonstration purposes
[[inputs.trig]]
# Sets the amplitude
amplitude = 10.0
由于我们在配置中添加了配置参数,我们还需要在我们的结构体中添加相应的属性。您将在trig.go中看到以下行:
type Trig struct {
x float64
Amplitude float64
}
Amplitude
是我们配置中定义的值,而x
是用于在收集间隔之间存储插件状态的变量。
经过测试并正常工作的配置,以及添加到结构体中的适当属性,我们现在可以为Gather
方法创建实现。
Telegraf定期收集并将指标“刷新”到您的输出;收集和刷新间隔都可以在Telegraf配置中的[agent]
部分定义,使用interval
和flush_interval
变量。如果您将前者设置为1s
,后者设置为10s
,Trig插件将每秒生成新点,但您不会看到它们出现在数据库中,直到Telegraf每10秒将数据刷新到数据库。
Gather()
方法接受一个参数,即telegraf.Accumulator
,它通过telegraf.Accumulator.AddFields(measurement, tags, fields)
方法创建新的测量值。该方法接受三个参数:一个measurement
,它是string
类型;tags
,它是一个字符串键和值的map[string]string
;以及fields
,它是一个键为字符串、字段为任何类型的map[string]interface{}
。
让我们看看Trig的Gather
方法:
func (s *Trig) Gather(acc telegraf.Accumulator) error {
sinner := math.Sin((s.x*math.Pi)/5.0) * s.Amplitude
cosinner := math.Cos((s.x*math.Pi)/5.0) * s.Amplitude
fields := make(map[string]interface{})
fields["sine"] = sinner
fields["cosine"] = cosinner
tags := make(map[string]string)
s.x += 1.0
acc.AddFields("trig", fields, tags)
return nil
}
首先,我们使用之前值以及我们在配置中定义的振幅,在正弦和余弦波上生成一个新的点。然后我们创建字段和标签,并分配适当的信息,在调用AddFields
生成测量值之前,更新我们的状态以便下一次调用Gather
。
注意:在您设计Telegraf插件时,设计良好的模式非常重要。需要考虑的一个常见问题是所谓的“系列基数”,即您在数据库中存储的唯一系列数量。例如,如果您为每个测量值分配一个UUID,那么可以快速达到大量系列,这将影响数据库的内存使用和性能。
Trig插件所需的最后一件事是一个起始状态,我们将在trig.go
的init
函数中定义它。
func init() {
inputs.Add("trig", func() telegraf.Input { return &Trig{x: 0.0} })
}
此函数接受整个插件并将其传递给Telegraf代理,然后每当收集间隔过去时,它都会遍历所有活动插件,并在每次收集间隔过去时调用Gather
函数。
是时候测试了!让我们重新生成我们的配置并运行Telegraf
$ make
$ telegraf -sample-config -input-filter trig -output-filter influxdb >> telegraf.conf.test
$ telegraf -config telegraf.conf.test -debug
调试输出将显示插件正在运行并收集指标。
您在这个阶段也应该为您的插件编写一些测试。如果您想将您的插件贡献到上游,这是一个要求。每次有新的构建时都会运行测试,以捕获任何可能的回归或引入的问题。在Go中,编写测试相对简单,并且是语言本身的一部分。您将编写传递测试结构的方法,并使用它来断言插件的行为。您可以在相应的trig_test.go
文件中找到trig.go
的测试(GitHub上的链接)。
贡献
除了测试之外,您还需要为您的插件创建一个README.md文件,其中包含有关插件功能的信息。您还需要确保您有一个LICENSE文件和输入/输出格式的样本。如果您的插件有其他依赖项,您也想要添加这些依赖项。如果您有兴趣进行贡献,请查看GitHub上的优秀指南。