بنقرة واحدة
catpaw-plugin-development
// 为 Catpaw 项目开发、修改、补全或评审插件。用户只要提到 Catpaw 插件、监控检查、plugins 目录下的新插件、补充 agent 注册、生成 conf.d 示例、实现 Gather/Init/partials、对照现有插件仿写或重构插件时,都应使用这个 skill。
// 为 Catpaw 项目开发、修改、补全或评审插件。用户只要提到 Catpaw 插件、监控检查、plugins 目录下的新插件、补充 agent 注册、生成 conf.d 示例、实现 Gather/Init/partials、对照现有插件仿写或重构插件时,都应使用这个 skill。
| name | catpaw-plugin-development |
| description | 为 Catpaw 项目开发、修改、补全或评审插件。用户只要提到 Catpaw 插件、监控检查、plugins 目录下的新插件、补充 agent 注册、生成 conf.d 示例、实现 Gather/Init/partials、对照现有插件仿写或重构插件时,都应使用这个 skill。 |
按 Catpaw 现有插件体系工作,不要发明新的注册方式、配置格式或事件模型。
先读这些文件,再开始实现:
docs/plugin-development.mdplugins/plugins.goagent/agent.goreferences/examples.md如果任务只涉及修改已有插件,优先读目标插件目录下的 .go、design.md 和对应 conf.d/p.<name>/<name>.toml。
除非用户明确只要方案或解释,否则直接落地代码,通常至少包含:
plugins/<name>/<name>.goagent/agent.go 中的匿名导入conf.d/p.<name>/<name>.toml复杂插件可以补:
plugins/<name>/design.mdplugins/<name>/<name>_test.go先确定:
pluginName 必须与目录名和配置目录名一致check label 是什么target 应该是什么稳定标识partialsInit() 做参数校验和默认值填充一个维度对应一个独立 event。不要把多个检查结果塞进同一个 event。
不要从零设计。总是找最相近的现有插件比照实现:
zombie、uptimeping、http、netfilefd、procfd、filechecklogfile、journaltail、systemdpartials:ping、http、net遵循现有骨架:
const pluginName = "myplugin"
type Instance struct {
config.InternalConfig
// instance fields
}
type MyPlugin struct {
config.InternalConfig
Instances []*Instance `toml:"instances"`
}
func init() {
plugins.Add(pluginName, func() plugins.Plugin {
return &MyPlugin{}
})
}
func (p *MyPlugin) GetInstances() []plugins.Instance { ... }
func (ins *Instance) Init() error { ... }
func (ins *Instance) Gather(q *safe.Queue[*types.Event]) { ... }
只有在确实需要模板复用时才实现 ApplyPartials() error 并在 plugin 顶层增加 Partials []Partial。
所有插件都要遵守这些约定:
check label 必填,格式为 <plugin>::<dimension>target label 必填,值要稳定、可读event.SetAttrs(map[string]string{...}),不参与 AlertKey 计算Description 只写纯文本,不写 Markdown[TPL]${check} ${from_hostip} ${target},否则用 [TPL]${check} ${from_hostip})types.EventStatusOk 或默认 OK event,以支持恢复如果某个检查维度有独立阈值、标题规则或属性,就给它独立 event 和独立 builder,避免在 Gather() 里堆大量分支。
Init()Init() 用来做这几类事:
warn < criticalInit() 返回错误时,实例不会启动。校验应尽量具体,错误信息直接指出字段和值。
Gather()Gather() 只负责采集和组装 event:
如果使用 goroutine,并发单元内部要自己做 panic 保护,参考 ping、http。
实现完插件后同步完成:
agent/agent.go 的 import 块里添加匿名导入conf.d/p.<name>/<name>.tomltoml tag 与示例配置一致不要只写插件代码而漏掉导入或默认配置。
partials 何时使用只有多个 instance 共享大量相同配置时才使用 partials。常见信号:
实现时遵守当前项目习惯:
Partials []PartialPartial string \toml:"partial"``ApplyPartials() 只在 instance 字段为空值时回填 partial 值不要让 partial 覆盖 instance 显式配置。
提交前至少自检这些点:
GetInstances() 是否正确返回 []plugins.InstanceInit() 和 Gather() 的接收者是否是 *Instancecheck/target 是否完整agent/agent.go 是否已注册conf.d/p.<name>/<name>.toml 是否可作为最小可用示例如果用户要求“写一个插件”,最终输出应优先是已修改的仓库文件,而不是只给伪代码。
如果用户要求“设计一个插件”,输出至少要包含:
Instance/Plugin 结构check label 设计