首页
/ Telegraf webhooks 插件之 Particle 子 Webhook:把 Particle.io 设备事件接入时序数据的完整实践

Telegraf webhooks 插件之 Particle 子 Webhook:把 Particle.io 设备事件接入时序数据的完整实践

2026-09-13 15:12:32作者:董灵辛Dennis

导读

本文围绕 Particle Webhook 插件说明文档 展开,系统讲解 Telegraf 的 webhooks 服务插件中 Particle 子 Webhook 的完整接入链路:从服务端 TOML 配置、Particle 控制台的 Webhook 设置,到设备端事件消息的 JSON 结构约定。读完本文,你将掌握:

  • 如何在 Telegraf 中启用 Particle Webhook 监听路径,并理解它在 webhooks 服务插件中的运行机制;
  • 如何配置 Particle 控制台侧的 Webhook 目标地址、Basic Auth 与高级设置中的 measurement 字段;
  • Particle 设备端应发布何种格式的事件数据,以及 tags/values 如何被映射为 Telegraf 指标的标签与字段;
  • 源码层面 particle_webhooks.go 的消息解析、measurement 回退、时间戳处理与鉴权逻辑。

一、插件定位:webhooks 服务插件与 Particle 子 Webhook

Particle Webhook 并不是一个独立的输入插件,而是 webhooks 输入插件 内置的子 Webhook 之一。父插件 webhooks.go 是一个 service input(服务输入):它启动一个 HTTP 服务器(默认监听 :1619),并依据配置将各个子 Webhook 注册到同一个 gorilla/mux 路由上。

sample.conf 可以看到,webhooks 插件同时支持 Artifactory、Filestack、Github、Mandrill、Papertrail、Particle、Rollbar 七个子 Webhook。Particle 对应的配置块为:

[[inputs.webhooks]]
  ## Address and port to host Webhook listener on
  service_address = ":1619"

  [inputs.webhooks.particle]
    path = "/particle"

    ## HTTP basic auth
    #username = ""
    #password = ""

关键配置项说明:

配置项 所属层级 说明
service_address [[inputs.webhooks]] Webhook HTTP 服务监听地址,默认 :1619,Particle 回调地址即基于此端口拼接
read_timeout / write_timeout <a href="https://link.gitcode.com/i/439a5f70a4037b479b5c629579125ea1" target="_blank">[inputs.webhooks]] 请求读取/响应写入超时,代码中默认值均为 10 秒(见 [webhooks.go 的 defaultReadTimeout/defaultWriteTimeout 常量)
path [inputs.webhooks.particle] Particle Webhook 的路由路径,默认 /particle,必须与 Particle 控制台配置的 URL 路径一致
username / password [inputs.webhooks.particle] 可选的 HTTP Basic Auth 凭据;两者均为空时不做鉴权,任一配置后则所有请求必须携带正确的 Authorization

父插件的注册机制值得注意:Start 方法通过 availableWebhooks() 用反射遍历 Webhooks 结构体的字段,凡是指向非 nil 且实现了 Webhook 接口(Register(router, acc, log))的字段都会被注册到路由上(见 webhooks.go)。也就是说,只有配置了 [inputs.webhooks.particle] 表,Particle 路由才会生效,未配置的子 Webhook 不会占用路由。

二、Particle 控制台侧配置

按照 插件说明文档 的操作步骤:

  1. 登录 Particle 开发者控制台(console.particle.io),进入 Integrations > New Integration > Webhook 创建一个新的 Webhook 集成;

  2. URL 设置为 Telegraf 实例地址加上 Particle 路由路径,例如:

    http://<my_ip>:1619/particle
    

    其中端口 1619 来自 service_address 的默认值,/particle 必须与 [inputs.webhooks.particle]path 一致;

  3. Advanced Settings 中切换到 JSON,追加以下内容用于指定指标名:

    {
        "measurement": "your_measurement_name"
    }
    

    这段 JSON 会随每个 Webhook 回调一并发送到 Telegraf,measurement 字段的值将作为生成指标的 measurement 名称;

  4. 若 Telegraf 侧配置了 Basic Auth(username/password),需要在集成中填写对应的用户名和密码;

  5. 点击 Save 完成保存;

  6. 额外要求(文档特别强调):在 Webhooks 设置中开启 JSON 消息,并勾选 "include default data" 选项,这样回调中才会携带 published_at 等默认字段;

  7. Particle 官方 Webhook 参考文档可在其开发者文档站(docs.particle.io 的 reference/webhooks)中查阅。

三、设备端事件格式:tags 与 values

Particle 设备端需要发布一个内容为 JSON 的事件。文档给出的设备端(C++ 风格)示例如下:

String data = String::format("{ \"tags\" : {
     \"tag_name\": \"tag_value\",
     \"other_tag\": \"other_value\"
    },
 \"values\": {
     \"value_name\": %f,
  \"other_value\": %f,
    }
    }",  value_value, other_value
 );
    Particle.publish("event_name", data, PRIVATE);

要点:

  • 事件数据必须是 {"tags": {...}, "values": {...}} 结构。tags 内的键值对会被映射为指标标签(且必须是字符串),values 内的键值对映射为指标字段;
  • 文档明确指出:标签数量和字段数量没有上限,一次 Webhook 调用可以携带任意数量的键值对;
  • 在源文件中拼接 JSON 字符串时,双引号需要按语言规则转义(文档提示 "Escaping the "" is required in the source file");
  • 发布选项使用 PRIVATE 私有事件即可,Telegraf 通过已配置的 Webhook URL 接收回调,不需要公开事件。

从测试用例 particle_webhooks_test.go 中的 newItemJSON() 可以还原出 Telegraf 实际接收到的完整回调报文结构:

{
  "event": "temperature",
  "data": {
      "tags": {
          "id": "230035001147343438323536",
          "location": "TravelingWilbury"
      },
      "values": {
          "temp_c": 26.68,
          "temp_f": 80.02,
          "humidity": 44.94,
          "pressure": 998.99,
          "altitude": 119.33,
          "broadband": 1266.0,
          "infrared": 528.0,
          "lux": 0.0
      }
  },
  "ttl": 60,
  "published_at": "2017-09-28T21:54:10.897Z",
  "coreid": "123456789938323536",
  "userid": "1234ee123ac8e5ec1231a123d",
  "version": 10,
  "public": false,
  "productID": 1234,
  "name": "sensor",
  "measurement": "mydata"
}

各字段与源码 event 结构体 的对应关系:

回调字段 源码字段 用途
event Name 事件名,当 measurement 为空时作为 measurement 名回退
data.tags Data.Tagsmap[string]string 指标标签
data.values Data.Fieldsmap[string]interface{} 指标字段
ttl TTL 事件 TTL,仅解析未使用
published_at PublishedAt 事件发布时间,格式 2006-01-02T15:04:05Z,解析成功后用作指标时间戳
measurement Measurement 来自控制台高级设置 JSON 的指标名,优先于事件名

也就是说,文档要求控制台勾选 "include default data" 的价值就在于保证 published_at 等默认字段存在,使指标能带上事件的实际发布时间。

四、源码级实现解析

Particle 子 Webhook 的完整实现在 particle_webhooks.go,逻辑清晰,可分为四部分:

1. 路由注册

func (rb *Webhook) Register(router *mux.Router, acc telegraf.Accumulator, log telegraf.Logger) {
	router.HandleFunc(rb.Path, rb.eventHandler).Methods("POST")
	rb.log = log
	rb.log.Infof("Started the webhooks_particle on %s", rb.Path)
	rb.acc = acc
}

注册为 仅接受 POST 的处理器,与 Particle Webhook 的回调方式一致;启动时打印日志 Started the webhooks_particle on /particle,可用于确认路由是否生效。

2. 鉴权

if !rb.Verify(r) {
	w.WriteHeader(http.StatusUnauthorized)
	return
}

Webhook 结构体内嵌了 auth.BasicAuthVerify 的逻辑是:usernamepassword 均为空时直接放行(return true);否则要求请求携带 Basic Auth,且使用 subtle.ConstantTimeCompare 做恒定时间比较(防时序侧信道)。鉴权失败返回 401 Unauthorized 且不产生任何指标。

3. 解析与容错

e := newEvent()
if err := json.NewDecoder(r.Body).Decode(e); err != nil {
	rb.acc.AddError(err)
	w.WriteHeader(http.StatusBadRequest)
	return
}
  • 反序列化目标是通过 newEvent() 预置了空 map 的 event,因此即使 datatagsvalues 缺失也不会因 nil map 引发后续问题——这正对应测试 TestUnknowItem:发送只有 {"event": "roger"} 的"未知事件",处理器依然返回 200 而不报错;
  • 解析失败(JSON 非法)时通过 acc.AddError 记录插件错误并返回 400 Bad Request

4. 时间戳、measurement 回退与指标产出

pTime, err := e.time()
if err != nil {
	pTime = time.Now()
}

// Use 'measurement' event field as the measurement, or default to the event name.
measurementName := e.Measurement
if measurementName == "" {
	measurementName = e.Name
}

rb.acc.AddFields(measurementName, e.Data.Fields, e.Data.Tags, pTime)
w.WriteHeader(http.StatusOK)
  • published_at2006-01-02T15:04:05Z(精确到秒的 RFC3339)解析;解析失败(例如测试数据 2017-09-28T21:54:10.897Z 带毫秒尾缀)则回退为服务器当前时间,保证指标始终有可用时间戳;
  • measurement 名称优先取控制台高级设置中的 measurement 字段,为空则回退为事件名 event。测试 TestDefaultMeasurementName 验证了这一点:measurement: "" 时指标名使用事件名 eventName;而 TestNewItem 验证了 measurement: "mydata" 时以 mydata 为指标名,且 8 个 fields、2 个 tags 完整落库。

五、端到端验证路径

接入完成后的验证建议:

  1. 启动 Telegraf,观察日志中出现 Started the webhooks service on :1619Started the webhooks_particle on /particle(分别由父插件与 Particle 子插件打印);
  2. 在设备上触发一次 Particle.publish,或用任意 HTTP 客户端向 http://<my_ip>:1619/particle 发送与上文 newItemJSON() 结构一致的 POST 报文(可参考 particle_webhooks_test.go 中的三段测试报文作为现成请求体);
  3. 检查下游输出或 telegraf --test 场景外的指标流中是否出现对应 measurement、标签与字段;
  4. 若配置了 Basic Auth,注意未携带凭据的请求会收到 401,报文 JSON 非法会收到 400,可用这两种状态码区分问题所在层。

六、注意事项与适用边界

  • 该功能依赖 Particle 云平台主动向 Telegraf 发起 HTTP 回调,因此 Telegraf 实例必须能被 Particle 云端访问(公网可达或经反向代理暴露);回调 URL 使用 HTTP 明文,生产环境建议在前方加 TLS 终止的反向代理并配合 Basic Auth 使用;
  • 由于是 service input,interval 设置对其不生效,--test/--once 等 CLI 选项可能不产生输出,这与 webhooks 插件说明 中 Service Input 章节的描述一致;
  • values 字段类型宽松(map[string]interface{}),测试数据均为浮点值,但从结构上看整数、布尔等 JSON 数值类型同样可被解码;tags 要求字符串映射,若设备端在 tags 中放入非字符串值,JSON 反序列化到 map[string]string 会失败并按 400 处理;
  • 相关核心文件汇总:particle_webhooks.go(实现)、particle_webhooks_test.go(测试)、sample.conf(配置样例)、webhooks.go(父插件服务与路由注册)。
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
34
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.21 K
2.81 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
945
1.86 K
docsdocs
暂无描述
Markdown
906
5.84 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
537
607
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
864
1.36 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
4.28 K
1.03 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.39 K
1.48 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
550
401
flutter_flutterflutter_flutter
本仓库是 Flutter SDK 与 Flutter Engine 的 OpenHarmony 适配版本,由 CPF-Flutter 团队维护。开发者可使用熟悉的 Flutter 技术栈开发 OpenHarmony 应用,3.35.7 及以后的适配版本可基于本仓库源码构建支持 OpenHarmony 的 Flutter Engine。
Dart
1.19 K
347