Telegraf inputs.sip 插件实战:对 SIP/VoIP 服务器做健康探测与延迟监控
Telegraf 自 v1.38.0 起提供 inputs.sip 输入插件,通过向 SIP(Session Initiation Protocol)服务器发送 OPTIONS 等探测请求来监测 PBX 系统、SIP 代理、注册服务器和 VoIP 服务商的可用性与响应时延。本文以该插件的官方文档 plugins/inputs/sip/README.md 为主线,完整覆盖其配置参数、SIP 方法选择、指标结构与排错方法,并结合源码 plugins/inputs/sip/sip.go 和测试 plugins/inputs/sip/sip_test.go 深入讲解请求构造、摘要认证与超时处理的底层实现,帮助你在部署 VoIP 基础设施时快速搭建一套可落地的 SIP 健康监控方案。
插件概述与适用场景
inputs.sip 是一个主动探测型(active probe)插件,它的工作模式非常直白:
- 按采集周期向配置好的 SIP 服务器发送 SIP 请求(默认
OPTIONS方法); - 测量从发出请求到收到响应的时间,并记录 SIP 状态码与原因短语;
- 将结果写入名为
sip的 measurement,供后续告警、聚合与可视化使用。
插件标注分类为 network,平台为 all(所有平台均可用)。它适用于以下典型场景:
- 监控 Asterisk、FreeSWITCH 等 PBX 或 SIP 代理的存活与延迟;
- 监测 SIP 注册服务器对 OPTIONS 的响应能力;
- 验证需要摘要认证(Digest Authentication)的 VoIP 服务的可达性;
- 使用 TLS(
sips://)加密通道探测的合规性检查。
插件基于第三方 Go 库 github.com/emiago/sipgo(当前仓库 go.mod 中版本为 v1.6.0)实现 SIP 协议栈,插件在 plugins/inputs/all/sip.go 中完成注册,可通过 telegraf --test 等常规方式验证。
完整配置参考
以下配置完整继承自插件的示例配置 plugins/inputs/sip/sample.conf,可直接复制到 Telegraf 主配置文件中:
# SIP (Session Initiation Protocol) health check plugin
[[inputs.sip]]
## SIP server address to monitor
## Format: sip://host[:port] or sips://host[:port]
## sip:// - Standard SIP (default port 5060)
## sips:// - Secure SIP with TLS (default port 5061)
server = "sip://sip.example.com:5060"
## Transport protocol
## Valid values: udp, tcp, ws, wss
# transport = "udp"
## SIP method to use for health checks
## Valid values: OPTIONS, INVITE, MESSAGE
# method = "OPTIONS"
## Request timeout
# timeout = "5s"
## From user as it appears in SIP header
# from_user = "telegraf"
## From domain (domain part of From header)
## If not specified, uses the server hostname
# from_domain = ""
## To user as it appears in SIP header
## If not specified, uses the same value as from_user
# to_user = ""
## Local address to use for outgoing requests
# local_address = ""
## SIP digest authentication credentials
## Leave empty to use no authentication
# username = ""
# password = ""
## Optional TLS Config (only used for sips:// URLs or transport=tls/wss)
## Set to true/false to enforce TLS being enabled/disabled. If not set,
## enable TLS only if any of the other options are specified.
# tls_enable =
## Trusted root certificates for server
# tls_ca = "/path/to/cafile"
## Used for TLS client certificate authentication
# tls_cert = "/path/to/certfile"
## Used for TLS client certificate authentication
# tls_key = "/path/to/keyfile"
## Password for the key file if it is encrypted
# tls_key_pwd = ""
## Send the specified TLS server name via SNI
# tls_server_name = "kubernetes.example.com"
## Minimal TLS version to accept by the client
# tls_min_version = "TLS12"
## List of ciphers to accept, by default all secure ciphers will be accepted
## Use "all", "secure" and "insecure" to add all support ciphers, secure
## suites or insecure suites respectively.
# tls_cipher_suites = ["secure"]
## Renegotiation method, "never", "once" or "freely"
# tls_renegotiation_method = "never"
## Use TLS but skip chain & host verification
# insecure_skip_verify = false
参数详解与默认值
结合 sip.go 中 Init() 与 init() 的源码,各参数的实际默认值与语义如下:
| 参数 | 默认值 | 说明 |
|---|---|---|
server |
必填 | 被监测服务器地址,格式 sip://host[:port] 或 sips://host[:port];省略端口时分别默认 5060 / 5061 |
transport |
sip:// 时默认 udp,sips:// 时默认 tcp |
传输层协议,合法取值 udp、tcp、ws、wss |
method |
OPTIONS |
探测使用的 SIP 方法,合法取值 OPTIONS、INVITE、MESSAGE(大小写敏感,全大写) |
timeout |
5s |
单次请求超时时间,不允许为负值 |
from_user |
telegraf |
SIP From 头中的用户部分 |
from_domain |
服务器主机名 | SIP From 头中的域名部分 |
to_user |
与 from_user 相同 |
SIP To 头中的用户部分 |
local_address |
空 | 指定本地出口地址,会同时影响 Via 头主机名与 Contact 头 |
username / password |
空(不认证) | SIP 摘要认证凭据,支持 secret store 注入 |
tls_* 系列 |
见示例 | 标准 Telegraf TLS 配置,仅在 sips:// 安全模式下生效 |
几点值得注意的实现细节(均可在 sip.go 的 Init() 中确认):
- scheme 与 transport 的合法性是强约束。
sip://只允许非安全传输(udp/tcp/ws),sips://只允许安全传输(tcp/wss);任何不匹配组合都会导致插件初始化失败并报错,而非静默降级。 tls作为 transport 取值已被拒绝。源码注释明确说明tls传输已按 RFC 3261 弃用,应改用sips://scheme;测试用例TestInitRejectsDeprecatedTLSTransport(sip_test.go)专门验证了这一点。- 方法名大小写敏感。
TestInitInvalidMethodCase(sip_test.go)验证了options、OpTiOnS等写法都会报invalid SIP method错误。 - 凭据字段使用
config.Secret类型,即username与password支持 secret store(配置方式参见 docs/CONFIGURATION.md 的 "Secret store secrets" 小节),无需把明文密码写入配置文件。
server 地址与端口规则
从 TestParseServer 的测试用例(sip_test.go)可以看到地址解析的完整行为:
| server 配置 | 解析结果 |
|---|---|
sip://sip.example.com:5060 |
host=sip.example.com, port=5060, 非安全 |
sips://sip.example.com:5061 |
host=sip.example.com, port=5061, 启用 TLS |
sip://sip.example.com(无端口) |
默认 port=5060 |
sips://secure.example.com(无端口) |
默认 port=5061 且强制 TLS |
sip://192.168.1.100:5070 |
支持 IP 地址与非标准端口 |
使用 sips:// 时,即使一个 TLS 参数都不设置,插件也会强制启用 TLS(采用系统默认证书链),这是 Init() 中的显式行为:ClientConfig.Enable 未设置时会被置为 true(见 sip.go)。
SIP 探测方法选择
插件支持三种 SIP 方法,对应文档中的说明:
- OPTIONS(推荐):标准 SIP 能力查询方法,查询服务器能力而不建立会话,对服务器无副作用,是健康检查的首选。
- INVITE:发起会话建立。文档明确提示需谨慎使用,因为它可能在服务器上产生通话记录(call records)。
- MESSAGE:发送即时消息,适合验证消息类基础设施的连通性。
测试代码(TestSIPMethodINVITE、TestSIPMethodMESSAGE)通过只注册对应方法的 mock 服务器来验证插件确实按配置发送了相应方法。注意:如果目标服务器不响应你选择的方法(例如仅接受 OPTIONS),你会观察到 503 Service Unavailable 之类的状态码,这属于配置排查项而非插件缺陷。
指标说明与示例输出
插件产生 measurement 名 sip 的指标:
Tags(标签)
source:配置的 SIP 服务器地址(server原值);method:使用的 SIP 方法,小写形式(options/invite/message);transport:传输协议(udp/tcp/ws/wss);status_code:SIP 响应状态码(如"200"、"404"),超时场景下不存在该 tag。
Fields(字段)
response_time_s(float,秒):收到响应所耗时;超时场景下等于配置的timeout值;result(string):请求结果。收到响应时为 SIP 原因短语(如"OK"、"Not Found"、"Unauthorized");无有效响应时取哨兵值Timeout、Error或No Response;server_agent(string,可选):响应中Server头的值,标识远端服务器软件(例如"Asterisk PBX 18.15.0")。
文档给出的示例输出(原样继承自 README):
sip,host=telegraf-host,method=options,source=sip://sip.example.com:5060,status_code=200,transport=udp response_time_s=0.023,result="OK" 1640000000000000000
sip,host=telegraf-host,method=options,source=sip://unreachable.example.com:5060,transport=udp response_time_s=5.0,result="Timeout" 1640000000000000000
sip,host=telegraf-host,method=options,source=sip://sip.provider.com:5060,status_code=404,transport=udp response_time_s=0.045,result="Not Found" 1640000000000000000
sip,host=telegraf-host,method=options,source=sips://secure.voip.example.com:5061,status_code=200,transport=tcp response_time_s=0.067,result="OK",server_agent="Asterisk PBX 18.15.0" 1640000000000000000
注意第二行超时样本:没有 status_code tag,response_time_s 恰好等于配置的 5 秒超时值——这两点与源码中 context.DeadlineExceeded 分支的行为完全一致(sip.go),测试 TestSIPServerTimeout 也断言了 response_time_s 与超时值在 0.01 秒内相等。
源码解析:请求是如何构造和发送的
生命周期:Init / Start / Gather
插件遵循 Telegraf service input 的三段式生命周期:
Init()(sip.go):填充默认值、校验server/method/transport合法性、解析出host+port,并把可复用的请求组件缓存下来——requestURI(含transportURI 参数)以及To、User-Agent头。User-Agent头使用internal.ProductToken(),即标准 Telegraf 产品标识。Start()(sip.go):创建 sipgo 的UserAgent与Client。如果配置了local_address,会以sipgo.WithClientHostname选项将其作为 Via 头的主机名——这一行为正是 CHANGELOG.md 中记录的local_address用途。Gather()(sip.go):每次采集周期执行一次探测。
From 头为什么不缓存
Gather() 中每次请求都会重新构造 From 头,并追加一个 16 位随机 tag(sip.GenerateTagN(16)),源码注释解释了原因:From tag 每次请求必须动态生成,无法像其他头那样在 Init() 阶段缓存。这也是 SIP 协议避免事务冲突的常规做法。
摘要认证:两轮请求机制
当配置了 username/password 且服务器返回 401 或 407 时,插件走 SIP 摘要认证流程(sip.go):
- 第一次请求不携带认证信息,服务器返回
401/407挑战(含WWW-Authenticate头与 nonce); - 插件取出凭据(
config.Secret的Get()取值后显式Destroy()释放),调用 sipgo 的DoDigestAuth携带 Digest 凭据重发同一请求。
由于 SIP 摘要认证必须先拿到服务器挑战中的 nonce 才能计算响应,首次请求无法预认证——源码注释对此有明确说明。测试 TestSIPAuthenticationSuccess(sip_test.go)验证了服务器恰好被调用两次(初始请求 + 认证重试),最终指标为 status_code=200, result="OK"。
一个安全相关的测试断言值得留意:该测试遍历最终指标的所有 tag 和 field,确认用户名和口令字符串绝不出现在任何输出字段中,避免凭据泄漏到指标系统。
失败路径的分类处理
Gather() 对失败做了精细区分,且所有失败都返回 nil 而不是错误——即探测失败本身不会让插件退出,而是转化为指标值:
| 场景 | result 字段 |
response_time_s |
status_code tag |
|---|---|---|---|
| 正常收到响应 | SIP 原因短语,如 OK |
实际耗时 | 有 |
超过 timeout |
Timeout |
等于配置超时值 | 无 |
| 传输层/其他错误 | Error |
实际耗时 | 无 |
| 响应对象为 nil | No Response |
实际耗时 | 无 |
这种设计使得你可以直接用 result 字段或 status_code 是否存在来编写告警,例如:result != "OK" 且持续 N 个周期即触发告警。
测试如何验证整个链路
sip_test.go 使用 sipgo 库在本地起了一个真实的 UDP mock SIP 服务器(监听 127.0.0.1 的随机端口),覆盖了插件的关键行为:
- 默认值:
TestInitDefaults验证OPTIONS/telegraf/udp默认值; - URL 解析:
TestParseServer验证 6 组地址/端口/scheme 组合; - TLS 行为:
TestTLSConfiguration、TestTLSServerName、TestSecureProtocolWithoutTLSConfig验证sips://触发 TLS 选项、sip://不触发,以及 SNI 配置; - 响应状态码:
TestSIPServerSuccess(200)、TestSIPServerErrorResponse(404)、TestSIPDifferentStatusCodes(200/404/503)验证 status_code tag 与 reason 短语映射; - 超时与延迟:
TestSIPServerTimeout(服务器故意不响应)与TestSIPServerDelayedResponse(延迟 50ms 响应)验证时间测量与超时哨兵值; - 认证:
TestSIPAuthenticationRequired(无凭据时如实上报 401)与TestSIPAuthenticationSuccess(有凭据时完成两轮认证并验证凭据不泄漏)。
这些测试的存在意味着文档中描述的每一种响应行为(包括"404 可能仍代表服务器健康"这类细微语义)都有对应的自动化验证,可以直接用 go test ./plugins/inputs/sip/... 复现。
故障排查
以下内容继承自官方 README 的 Troubleshooting 小节,并结合源码行为补充。
权限问题
某些 SIP 实现可能需要特定网络权限。若遇到权限错误,请确认 Telegraf 进程具备相应的网络访问能力。
防火墙配置
请确保:
- 允许到 SIP 端口(通常 5060/5061)的出站连接;
- 若使用 UDP,防火墙需放行 UDP 包;
- 允许该事务的返回流量(UDP 无连接,返回包必须能回到探测方)。
超时问题
如果出现频繁超时(指标中 result="Timeout" 且 response_time_s 恒等于 timeout 值):
- 增大
timeout取值; - 确认到 SIP 服务器的网络连通性;
- 检查 SIP 服务器是否配置为响应你所选择的方法(如服务器不处理 OPTIONS 会返回 503);
- 确认选择了正确的
transport(UDP 服务器配 TCP 会收不到响应)。
响应码判读
不同 SIP 服务器对 OPTIONS 的响应码可能不同:
200 OK— 服务器运行正常且在响应;404 Not Found— 用户或资源不存在,但这往往仍表示服务器本身健康(插件默认探测to_user常为telegraf,服务器不认识该用户是正常现象);401 Unauthorized/407 Proxy Authentication Required— 需要认证。未配置凭据时插件会如实上报 401;配置凭据后正常路径是最终上报 200。
因此设计告警规则时,建议把 200、404 都视为"服务器存活",把 Timeout/Error/No Response 以及 503 等视为异常。
集成步骤小结
将插件纳入现有 Telegraf 部署只需三步:
- 在 Telegraf 配置文件中添加
[[inputs.sip]]段,按上文参数表设置server(必填)与按需的method、timeout、认证与 TLS 项; - 用
telegraf --test或telegraf --config <你的配置>试运行,确认sip指标按预期输出(可对照上文的示例输出); - 在输出端配置告警,关注
result字段(Timeout/Error/No Response为异常哨兵值)与response_time_s的趋势变化。
该插件的演进记录可在 CHANGELOG.md 中追溯:插件本身由上游 PR #18183 引入,后续 PR #18569 补充了 local_address 对 Via 头主机名的支持。若需了解其他输入/输出插件的通用配置(标签、字段过滤、插件顺序等),参见 docs/CONFIGURATION.md。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.24 K638- DDeepSeek-V4.1-FlashDeepSeek-V4.1-Flash 是一个多模态混合专家(MoE)模型,拥有 5520 亿骨干参数,并支持最多一百万 token 的上下文长度。该模型原生支持图像和文本输入,并以自回归方式生成文本Python650
SlideSCIPPT插件,支持素材库、AI助手、一键添加图片标题,复制粘贴位置、一键图片对齐、一键插入Markdown(加粗、超链接等行内样式、代码块、LaTeX等块级样式)、便捷导出图片!C#180
hello-agents📚 《从零开始构建智能体》——从零开始的智能体原理与实践教程Python52774
new-apiAI模型聚合管理中转分发系统,一个应用管理您的所有AI模型,支持将多种大模型转为统一格式调用,支持OpenAI、Claude、Gemini等格式,可供个人或者企业内部管理与分发渠道使用。🍥 A Unified AI Model Management & Distribution System. Aggregate all your LLMs into one app and access them via an OpenAI-compatible API, with native support for Claude (Messages) and Gemini formats.Go22545
JeecgBoot🔥企业级低代码平台集成了AI应用平台,帮助企业快速实现低代码开发和构建AI应用!前后端分离架构 SpringBoot,SpringCloud、Mybatis,Ant Design4、 Vue3.0、TS+vite!强大的代码生成器让前后端代码一键生成,无需写任何代码! 引领AI低代码开发模式: AI生成->OnlineCoding-> 代码生成-> 手工MERGE,显著的提高效率,又不失灵活~Java36351