Categraf 内置了丰富的采集插件,但仍难以覆盖所有监控场景。当需要采集特定数据时,通常有两种方案:一是使用通用的 EXEC 插件执行脚本;二是直接使用 Golang语言及其生态 编写原生插件并贡献给社区。本文将详细介绍第二种方法,手把手演示如何为 Categraf 开发一个全新的采集插件。
一、拉取代码
首先,将 Categraf 的代码仓库克隆到本地开发环境中。
cd /path/to/your/workspace
git clone https://github.com/flashcatcloud/categraf.git
二、编译项目
Categraf 使用 Go 语言编写。请确保本地已配置好 Go 开发环境,然后进入代码目录执行 make 命令进行编译。
$ cd /path/to/your/workspace/categraf
$ make
Building version v0.4.32-2a2305b9c8ec3ae4c4d196d94f971345abffa3e4
$ ./categraf -version
v0.4.32-2a2305b9c8ec3ae4c4d196d94f971345abffa3e4
make 命令的具体执行逻辑可以参考项目根目录的 Makefile 文件。编译成功后,通过 ./categraf -version 命令可以正常输出版本号。
三、插件目录结构
所有采集插件都位于代码的 inputs 目录下,每个插件独占一个子目录。例如,tomcat 插件在 inputs/tomcat 下,mysql 插件在 inputs/mysql 下。插件的主要逻辑代码通常以插件名命名,如 tomcat.go。
插件开发完成后,需要将其注册到 Categraf 的主框架中。注册方法是在 agent/metrics_agent.go 文件的 import 部分添加对应插件的引用。
四、编写插件主体
接下来,我们创建一个名为 custom01 的示例插件,展示完整的开发流程。
首先,在 inputs 目录下新建 custom01 文件夹,并在其中创建 custom01.go 文件。文件初始内容如下:
package custom01
import (
"flashcat.cloud/categraf/config"
"flashcat.cloud/categraf/inputs"
"flashcat.cloud/categraf/types"
)
// 插件名称
const inputName = "custom01"
// Instance 结构体保存单个采集实例的配置信息
// Categraf 通常支持同时采集多个目标实例,每个实例可拥有独立配置(如地址、认证信息)
type Instance struct {
// config.InstanceConfig 内嵌了通用的实例配置项
config.InstanceConfig
}
// Init 方法用于实例初始化,可进行配置校验或建立长期连接(如HTTP Client)
func (ins *Instance) Init() error {
return nil
}
// Custom01 结构体定义了插件的全局配置
type Custom01 struct {
// config.PluginConfig 内嵌了通用的插件配置项
config.PluginConfig
// Instances 保存多个实例的配置,对应配置文件中的 [[instances]]
Instances []*Instance `toml:"instances"`
}
// 以下为框架要求的固定函数
func init() {
inputs.Add(inputName, func() inputs.Input {
return &Custom01{}
})
}
func (t *Custom01) Clone() inputs.Input {
return &Custom01{}
}
func (t *Custom01) Name() string {
return inputName
}
func (t *Custom01) GetInstances() []inputs.Instance {
ret := make([]inputs.Instance, len(t.Instances))
for i := 0; i < len(t.Instances); i++ {
ret[i] = t.Instances[i]
}
return ret
}
// Gather 是核心采集函数,所有数据采集逻辑在此实现
func (ins *Instance) Gather(slist *types.SampleList) {}
然后,在 agent/metrics_agent.go 文件中注册该插件:
import (
// ...
_ "flashcat.cloud/categraf/inputs/custom01"
)
五、编译测试
完成以上步骤后,执行 make 命令重新编译 Categraf。
make
编译无报错即表示成功。但当前插件的 Gather 函数为空,无法采集任何数据。接下来我们将完善采集逻辑。
六、实现 Gather 函数
Gather 函数是插件的核心,它接收一个 *types.SampleList 参数,用于存放采集到的监控指标。我们首先实现一个简单功能:采集名为 current_time 的指标,其值为当前系统时间的 Unix 时间戳。
func (ins *Instance) Gather(slist *types.SampleList) {
slist.PushFront(types.NewSample(inputName, "current_time", time.Now().Unix(), nil))
}
为测试插件,需要创建对应的配置文件。配置文件路径为 conf/input.custom01/custom01.toml,内容如下:
interval = 1
[[instances]]
请确保 conf/input.custom01 目录存在,否则 Categraf 会认为插件未启用。随后进行编译和测试:
$ cat conf/input.custom01/custom01.toml
interval = 1
[[instances]]
$ make
Building version v0.4.32-2a2305b9c8ec3ae4c4d196d94f971345abffa3e4
$ ./categraf --test --inputs custom01 2>/dev/null | grep current
1766048751 17:05:51 custom01_current_time agent_hostname=bogon 1766048751
1766048752 17:05:52 custom01_current_time agent_hostname=bogon 1766048752
1766048753 17:05:53 custom01_current_time agent_hostname=bogon 1766048753
1766048754 17:05:54 custom01_current_time agent_hostname=bogon 1766048754
配置中 interval = 1 表示每秒采集一次。测试命令说明:
--test: 启用测试模式,采集数据但不发送后端。
--inputs custom01: 仅启用 custom01 插件。
2>/dev/null: 屏蔽错误输出。
| grep current: 过滤显示含 “current” 的结果行。
输出行中,custom01_current_time 是指标名,agent_hostname=bogon 是自动附加的标签,最后的数字是指标值。
七、数据结构进阶
上例展示了最简单的指标上报。在实际场景中,我们经常需要为指标添加标签。例如,为 current_time 指标添加一个表示环境的 env 标签。
func (ins *Instance) Gather(slist *types.SampleList) {
tags := map[string]string{
"env": "prod",
}
slist.PushFront(types.NewSample(inputName, "current_time", time.Now().Unix(), tags))
}
在 Prometheus 生态中,一个指标由指标名和一组标签唯一确定,上述代码即可生成符合其规范的指标。
有时,同一组标签下会对应多个指标值,例如系统负载(1分钟、5分钟、15分钟)。Categraf 提供了更便捷的 PushSamples 方法来处理这种情况。
func (ins *Instance) Gather(slist *types.SampleList) {
tags := map[string]string{"env": "prod"}
fields := map[string]interface{}{
"load1": 1.0,
"load5": 0.5,
"load15": 0.25,
}
slist.PushSamples(inputName, fields, tags)
}
八、更多参考
建议深入学习以下官方插件源码,它们是理解 监控运维和DevOps实践 中数据采集逻辑的优秀范例:
inputs/tomcat/tomcat.go
inputs/dns_query/dns_query.go
通过以上步骤,你已掌握了为 Categraf 开发自定义采集插件的完整流程,可以根据实际需求,编写代码采集任何特定的监控数据。