Telegraf Socket Writer 输出插件完全指南:通过 TCP/UDP/Unix Socket 发送指标数据
【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf
Socket Writer 是 Telegraf 中一个通用的网络输出插件,负责将采集到的指标以用户指定的数据格式(如 InfluxDB Line Protocol、JSON、Graphite 等)写入任意网络服务,支持 TCP、UDP、Unix Socket 与 vsock 等多种传输协议。读完本文,你将掌握该插件的完整配置方法、地址格式、TLS 与 keep-alive 调优、启动错误处理策略,以及它背后基于源码的连接管理与重连机制。
插件概述
根据 plugins/outputs/socket_writer/README.md 的定义,Socket Writer 插件([[outputs.socket_writer]])的功能是:
This plugin writes metrics to a network service e.g. via UDP or TCP in one of the supported data formats.
它从 Telegrafv1.3.0起可用,属于applications(应用)与network(网络)类别的插件,支持在所有平台上运行(all)。与专门面向特定服务的输出插件不同,它是一个协议无关的通用写入器——只要目标端是一个监听 TCP/UDP/Unix Socket 的服务,就可以通过它把 Telegraf 的指标送过去,非常适合自建轻量收集端、日志转发代理或自定义协议服务。
在plugins/outputs/all/socket_writer.go中可以看到该插件的注册方式,它随默认构建自动包含(!custom || outputs || outputs.socket_writer),并通过import _ "github.com/influxdata/telegraf/plugins/outputs/socket_writer"完成注册,在 socket_writer.go 中调用outputs.Add("socket_writer", ...)将插件名注册进 Telegraf 输出插件体系。
全局配置选项
与其他插件一样,outputs.socket_writer支持 Telegraf 的全局配置与插件级通用配置,例如使用namepass、namedrop、tagexclude、tagpass等过滤规则修改指标、标签和字段,通过alias创建别名,以及配置插件执行顺序(order)。详见 docs/CONFIGURATION.md#plugins。
插件还支持startup_error_behavior设置(见下文“启动错误处理策略”小节),用于指定插件在启动阶段遇到错误时的行为。
完整配置示例
以下配置直接取自该插件的官方示例文件 plugins/outputs/socket_writer/sample.conf:
# Generic socket writer capable of handling multiple socket types. [[outputs.socket_writer]] ## URL to connect to # address = "tcp://127.0.0.1:8094" # address = "tcp://example.com:http" # address = "tcp4://127.0.0.1:8094" # address = "tcp6://127.0.0.1:8094" # address = "tcp6://[2001:db8::1]:8094" # address = "udp://127.0.0.1:8094" # address = "udp4://127.0.0.1:8094" # address = "udp6://127.0.0.1:8094" # address = "unix:///tmp/telegraf.sock" # address = "unixgram:///tmp/telegraf.sock" # address = "vsock://cid:port" ## Optional TLS Config # tls_ca = "/etc/telegraf/ca.pem" # tls_cert = "/etc/telegraf/cert.pem" # tls_key = "/etc/telegraf/key.pem" ## Use TLS but skip chain & host verification # insecure_skip_verify = false ## Period between keep alive probes. ## Only applies to TCP sockets. ## 0 disables keep alive probes. ## Defaults to the OS configuration. # keep_alive_period = "5m" ## Content encoding for message payloads, can be set to "gzip" or to ## "identity" to apply no encoding. ## # content_encoding = "identity" ## Data format to generate. ## Each data format has its own unique set of configuration options, read ## more about them here: ## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_OUTPUT.md # data_format = "influx"下面逐项讲解每个配置参数的含义与底层实现。
address:目标地址格式
address是唯一必需的参数,采用scheme://host:port形式的 URL 风格字符串。从 socket_writer.go 的源码可以看到,Connect()首先通过strings.SplitN(sw.Address, "://", 2)将地址拆分为协议部分与目标部分,因此地址必须包含://分隔符,否则会返回invalid address错误。
支持的地址格式与说明如下:
| 地址格式 | 说明 | 使用场景 |
|---|---|---|
tcp://127.0.0.1:8094 | TCP 流式连接 | 常规 TCP 服务,如日志代理、自建收集端 |
tcp://example.com:http | 支持使用服务名代替端口号 | 便于记忆的命名端口 |
tcp4://127.0.0.1:8094 | 强制 IPv4 TCP | 明确约束协议栈时 |
tcp6://127.0.0.1:8094 | 强制 IPv6 TCP | IPv6 环境 |
tcp6://[2001:db8::1]:8094 | IPv6 字面量地址(需用方括号包裹) | 直接连接 IPv6 地址 |
udp://127.0.0.1:8094 | UDP 数据报 | 对丢包不敏感的指标上报 |
udp4://127.0.0.1:8094 | 强制 IPv4 UDP | IPv4 环境 |
udp6://127.0.0.1:8094 | 强制 IPv6 UDP | IPv6 环境 |
unix:///tmp/telegraf.sock | Unix 域流式套接字 | 本机进程间通信 |
unixgram:///tmp/telegraf.sock | Unix 域数据报套接字 | 本机轻量级 IPC |
vsock://cid:port | 虚拟机通信套接字(仅 Linux) | 宿主机与虚拟机之间通信 |
底层连接实现
在源码 socket_writer.go 中,Connect()对不同协议采取不同的建连路径:
- vsock:走
vsock.Dial(uint32(cid), uint32(port), nil)(来自github.com/mdlayher/vsock),并会校验 CID 与端口号必须是 32 位范围内的数字,缺少任一都会返回port and/or CID number missing错误。 - 其他协议:在未配置 TLS 时调用
net.Dial(spl[0], spl[1]);配置了 TLS 时则改用tls.Dial(spl[0], spl[1], tlsCfg)。
注意net.Dial的 scheme 参数直接取自地址前缀,因此tcp、tcp4、tcp6、udp、udp4、udp6、unix、unixgram都是 Go 标准库net包原生支持的 network 名称。
传输类型:流式 vs 数据报
从测试文件 socket_writer_test.go 可以清晰看到两种传输模型:
- 流式(stream):TCP 与 Unix Socket 走
net.Listen/Accept,写入的每条指标以换行分隔,接收端可用bufio.Scanner逐行读取(见testSocketWriterStream,L83-L108)。 - 数据报(packet):UDP 与 Unixgram 走
net.ListenPacket/ReadFrom,每条指标作为一个独立数据包发送(见testSocketWriterPacket,L110-L140)。
这也提醒使用者:UDP 是无连接、不保证送达的协议,如果要求可靠性,应使用 TCP;而对吞吐敏感的本地场景,unixgram是比 TCP 更轻量的选择。
TLS 配置
Socket Writer 内嵌了common_tls.ClientConfig(见 socket_writer.go),因此支持标准的客户端 TLS 配置:
tls_ca:CA 证书路径,用于校验服务端证书链。tls_cert/tls_key:客户端证书与私钥,用于双向 TLS(mTLS)认证。insecure_skip_verify = false:是否跳过证书链与主机名校验。默认为false(即严格校验),仅应在受信任的网络环境或自签名证书调试时设为true。
从源码可见,只要tls_ca、tls_cert、tls_key或insecure_skip_verify任一被设置并成功构建出tls.Config,Connect()就会改用tls.Dial建立加密连接(L88-L92)。也就是说,只需在配置中声明 TLS 参数即可自动启用加密传输,无需额外开关。
提示:TLS 仅对流式协议(TCP)有意义;UDP 下配置 TLS 参数不会被应用。
keep_alive_period:TCP 保活探测
keep_alive_period用于设置 TCP 连接的 keep-alive 探测间隔:
- 仅对 TCP 套接字生效(
0表示禁用保活探测); - 默认值为
nil,即保持操作系统默认配置; - 设置为
"5m"之类的间隔时,会启用 TCP keep-alive 并按指定周期发送探测。
其底层实现在 socket_writer.go 的setKeepAlive()方法中:只有当底层连接是*net.TCPConn时才会生效,否则返回“cannot set keep alive on a xxx socket”的错误(该错误仅以 Debug 级别日志记录,不会中断插件运行)。若设置为0,则调用SetKeepAlive(false)显式关闭;否则依次调用SetKeepAlive(true)与SetKeepAlivePeriod(...)。
对长连接场景(如对接云端收集网关、经过 NAT 的网络),合理的 keep-alive 配置可以及时发现半开连接,避免写数据时才发现对端已断开。
content_encoding:载荷内容编码
content_encoding决定发送给对端的数据载荷是否经过压缩编码,可选值:
"identity"(默认):不进行任何编码,直接发送原始序列化文本。"gzip":使用 gzip 压缩后再发送,可显著降低 UDP 报文大小或 TCP 传输带宽。
实现上,Connect()通过internal.NewContentEncoder(sw.ContentEncoding)构建编码器(socket_writer.go),编码器注册逻辑位于 internal/content_coding.go,支持gzip与identity(空字符串等价于identity)两种模式。若传入其他未知值,会返回错误。
测试 TestSocketWriter_udp_gzip 验证了 gzip 编码在 UDP 路径上的完整工作流。使用时需注意:接收端必须能够解压 gzip,否则会收到乱码;压缩对高冗余文本(如 JSON、Line Protocol)收益明显。
data_format:输出数据格式
data_format指定指标的序列化格式,默认"influx"(InfluxDB Line Protocol)。Socket Writer 使用 Telegraf 的通用输出序列化器体系,因此支持 docs/DATA_FORMATS_OUTPUT.md 中列出的全部标准输出格式,包括:
- InfluxDB Line Protocol(
influx) - Binary(
binary) - Carbon2(
carbon2) - CloudEvents(
cloudevents) - CSV(
csv) - Graphite(
graphite) - JSON(
json) - MessagePack(
msgpack) - Prometheus(
prometheus) - Prometheus Remote Write(
prometheusremotewrite) - ServiceNow Metrics(
nowmetric) - SplunkMetric(
splunkmetric) - Template(
template) - Wavefront(
wavefront)
每种格式都有各自专属的配置选项(如 JSON 的json_timestamp_units、Graphite 的模板等),可在对应序列化器插件的配置中查看。从源码看,插件通过SetSerializer方法注入序列化器(socket_writer.go),并在Write()中逐条调用sw.serializer.Serialize(m)完成序列化(L143-L148),因此序列化失败只影响单条指标,不会中断整体写入。
启动错误处理策略(startup_error_behavior)
与其他插件一致,outputs.socket_writer支持startup_error_behavior参数,用于控制启动阶段连接目标失败时的行为。可选值如下(见 docs/includes/startup_error_behavior.md):
error:启动失败时 Telegraf 停止并退出。这是默认行为。ignore:忽略该插件的启动错误,将其禁用,但继续处理其他插件。retry:启动失败时,插件在每个采集/写入周期都会尝试重新启动,成功前保持禁用。probe:如果可能,对插件功能进行探测,探测失败则禁用;若插件不支持探测,则按ignore处理。
Socket Writer 对启动错误的支持在源码层面有直接体现:Connect()中当建连失败时返回&internal.StartupError{Err: sockErr, Retry: true}(socket_writer.go),标记该错误可重试。测试文件中的TestStartupErrorBehaviorDefault/Error/Ignore/Retry(L220-L374)则系统验证了四种策略的实际行为,例如:
- 默认与
error策略下,目标端口未监听时model.Connect()会返回*internal.StartupError; ignore策略下错误被转换为*internal.FatalError,插件被移除;retry策略下启动不报错,写入返回internal.ErrNotConnected,直到监听端就绪后同一写入周期内自动恢复。
这组测试非常直观地展示了retry策略的价值:当目标服务可能晚于 Telegraf 启动时(如容器编排、服务依赖场景),设置startup_error_behavior = "retry"可让 Telegraf 免于退出,等待目标就绪后自动开始写入。
写入与断线重连机制
理解Write()的实现有助于判断生产环境中的重连行为。核心逻辑位于 socket_writer.go:
- 若
Conn为nil(上一次写入遇到永久性错误后连接已被关闭),会先调用Connect()重新建立连接。 - 对每条指标依次执行序列化 → 内容编码 →
Conn.Write(bs)。 - 若写入失败且错误类型为
net.Error(网络层永久错误),则关闭连接并置空Conn,返回错误,由上层在下一个写入周期重试(即自动重连)。
测试 TestSocketWriter_Write_err 验证了写入失败后Conn被置为nil;TestSocketWriter_Write_reconnect 则验证了在连接断开、目标重新监听后,下一次Write()能自动重建连接并成功送达数据。
此外,Write()注释明确标注了“Not parallel safe”(非并行安全),Telegraf 框架会保证对同一输出实例的写入调用是串行的,无需在插件内额外加锁。
典型使用场景
- 对接自建指标接收端:用一个监听
tcp://127.0.0.1:8094的轻量服务接收 Line Protocol,前端再用任何支持该格式的时序数据库消费。 - 跨宿主机转发:通过
tcp6/udp6地址格式将指标送到 IPv6 网络中的收集节点。 - 本地进程间通信:使用
unix://或unixgram://与同机运行的 Agent、日志管道高效交换数据,避免 TCP 协议栈开销。 - 宿主机 ↔ 虚拟机通信:Linux 下使用
vsock://cid:port直连虚拟机的 vsock 服务。 - 高吞吐传输:配合
content_encoding = "gzip"压缩载荷,降低带宽占用;配合data_format = "json"或"graphite"对接相应协议风格的接收端。
关键参考路径
- 插件文档:plugins/outputs/socket_writer/README.md
- 插件示例配置:plugins/outputs/socket_writer/sample.conf
- 插件核心实现:plugins/outputs/socket_writer/socket_writer.go
- 插件测试用例:plugins/outputs/socket_writer/socket_writer_test.go
- 插件注册入口:plugins/outputs/all/socket_writer.go
- 输出数据格式清单:docs/DATA_FORMATS_OUTPUT.md
- 插件通用配置与顺序控制:docs/CONFIGURATION.md#plugins
【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考