首页
/ Telegraf inputs.sip 插件实战:对 SIP/VoIP 服务器做健康探测与延迟监控

Telegraf inputs.sip 插件实战:对 SIP/VoIP 服务器做健康探测与延迟监控

2026-09-13 12:23:58作者:管翌锬

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.goInit()init() 的源码,各参数的实际默认值与语义如下:

参数 默认值 说明
server 必填 被监测服务器地址,格式 sip://host[:port]sips://host[:port];省略端口时分别默认 5060 / 5061
transport sip:// 时默认 udpsips:// 时默认 tcp 传输层协议,合法取值 udptcpwswss
method OPTIONS 探测使用的 SIP 方法,合法取值 OPTIONSINVITEMESSAGE(大小写敏感,全大写)
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.goInit() 中确认):

  • scheme 与 transport 的合法性是强约束sip:// 只允许非安全传输(udp/tcp/ws),sips:// 只允许安全传输(tcp/wss);任何不匹配组合都会导致插件初始化失败并报错,而非静默降级。
  • tls 作为 transport 取值已被拒绝。源码注释明确说明 tls 传输已按 RFC 3261 弃用,应改用 sips:// scheme;测试用例 TestInitRejectsDeprecatedTLSTransportsip_test.go)专门验证了这一点。
  • 方法名大小写敏感TestInitInvalidMethodCasesip_test.go)验证了 optionsOpTiOnS 等写法都会报 invalid SIP method 错误。
  • 凭据字段使用 config.Secret 类型,即 usernamepassword 支持 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:发送即时消息,适合验证消息类基础设施的连通性。

测试代码(TestSIPMethodINVITETestSIPMethodMESSAGE)通过只注册对应方法的 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");无有效响应时取哨兵值 TimeoutErrorNo 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 的三段式生命周期:

  1. Init()sip.go):填充默认值、校验 server/method/transport 合法性、解析出 host+port,并把可复用的请求组件缓存下来——requestURI(含 transport URI 参数)以及 ToUser-Agent 头。User-Agent 头使用 internal.ProductToken(),即标准 Telegraf 产品标识。
  2. Start()sip.go):创建 sipgo 的 UserAgentClient。如果配置了 local_address,会以 sipgo.WithClientHostname 选项将其作为 Via 头的主机名——这一行为正是 CHANGELOG.md 中记录的 local_address 用途。
  3. Gather()sip.go):每次采集周期执行一次探测。

From 头为什么不缓存

Gather() 中每次请求都会重新构造 From 头,并追加一个 16 位随机 tag(sip.GenerateTagN(16)),源码注释解释了原因:From tag 每次请求必须动态生成,无法像其他头那样在 Init() 阶段缓存。这也是 SIP 协议避免事务冲突的常规做法。

摘要认证:两轮请求机制

当配置了 username/password 且服务器返回 401407 时,插件走 SIP 摘要认证流程(sip.go):

  1. 第一次请求不携带认证信息,服务器返回 401/407 挑战(含 WWW-Authenticate 头与 nonce);
  2. 插件取出凭据(config.SecretGet() 取值后显式 Destroy() 释放),调用 sipgo 的 DoDigestAuth 携带 Digest 凭据重发同一请求。

由于 SIP 摘要认证必须先拿到服务器挑战中的 nonce 才能计算响应,首次请求无法预认证——源码注释对此有明确说明。测试 TestSIPAuthenticationSuccesssip_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 行为TestTLSConfigurationTestTLSServerNameTestSecureProtocolWithoutTLSConfig 验证 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。

因此设计告警规则时,建议把 200404 都视为"服务器存活",把 Timeout/Error/No Response 以及 503 等视为异常。

集成步骤小结

将插件纳入现有 Telegraf 部署只需三步:

  1. 在 Telegraf 配置文件中添加 [[inputs.sip]] 段,按上文参数表设置 server(必填)与按需的 methodtimeout、认证与 TLS 项;
  2. telegraf --testtelegraf --config <你的配置> 试运行,确认 sip 指标按预期输出(可对照上文的示例输出);
  3. 在输出端配置告警,关注 result 字段(Timeout/Error/No Response 为异常哨兵值)与 response_time_s 的趋势变化。

该插件的演进记录可在 CHANGELOG.md 中追溯:插件本身由上游 PR #18183 引入,后续 PR #18569 补充了 local_address 对 Via 头主机名的支持。若需了解其他输入/输出插件的通用配置(标签、字段过滤、插件顺序等),参见 docs/CONFIGURATION.md

登录后查看全文
热门项目推荐
相关项目推荐