OpenTSDB 输出插件详解:Telegraf 指标写入 Telnet 与 HTTP 双通道实战指南
2026/9/14 9:53:46 网站建设 项目流程

OpenTSDB 输出插件详解:Telegraf 指标写入 Telnet 与 HTTP 双通道实战指南

【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf

导读

OpenTSDB 输出插件是 Telegraf 内置的时序数据输出插件之一,负责将采集到的指标写入 OpenTSDB 实例,支持 Telnet 与 HTTP 两种传输协议(HTTP API 自 OpenTSDB 2.0 起被官方推荐)。读完本文,你将掌握该插件的完整配置参数语义、两种协议的底层实现原理、指标名与标签的清洗规则、批量发送与调试手段,并能够针对自建 OpenTSDB 或反向代理场景快速落地一套可运行的写入方案。


一、插件定位与适用场景

该插件在plugins/outputs目录下注册,属于输出端(datastore 类别),支持全平台运行(💻 all),自 Telegraf v0.1.9 起即已提供。其核心能力是:

  • 把 Telegraf 采集到的指标(measurement + field)映射为 OpenTSDB 数据点;
  • 支持Telnet API(TCP 直连、行协议写入)与HTTP API(JSON + gzip、批量 POST)两种模式;
  • 通过host参数的 URL scheme 自动选择协议:tcp://或裸主机名走 Telnet,http:///https://走 HTTP API。

从插件注册源码可见,init()中通过outputs.Add("opentsdb", ...)注册,并设置了两个默认值:HTTPPath = "/api/put"Separator = "_"(见 opentsdb.go)。因此即使配置中省略这两项,插件也能以合理的默认行为运行。


二、完整配置与参数解析

2.1 最小可用配置

[[outputs.opentsdb]] host = "opentsdb.example.com" port = 4242

host不带 scheme 时,Connect()会自动为其补上tcp://前缀(见 opentsdb.go),因此默认走 Telnet 协议。

2.2 全部配置项详解

以下是插件官方示例配置(与 sample.conf 完全一致):

# Configuration for OpenTSDB server to send metrics to [[outputs.opentsdb]] ## prefix for metrics keys prefix = "my.specific.prefix." ## DNS name of the OpenTSDB server ## Using "opentsdb.example.com" or "tcp://opentsdb.example.com" will use the ## telnet API. "http://opentsdb.example.com" will use the Http API. host = "opentsdb.example.com" ## Port of the OpenTSDB server port = 4242 ## Number of data points to send to OpenTSDB in Http requests. ## Not used with telnet API. http_batch_size = 50 ## URI Path for Http requests to OpenTSDB. ## Used in cases where OpenTSDB is located behind a reverse proxy. http_path = "/api/put" ## Debug true - Prints OpenTSDB communication debug = false ## Separator separates measurement name from field separator = "_"

各参数含义与实现细节如下:

配置项默认值作用与实现说明
prefix指标键前缀,最终 metric 名形如prefix.measurement.field;典型用途是划分命名空间便于后续按子集查询
host必填OpenTSDB 主机名;无 scheme 或tcp://走 Telnet,http:///https://走 HTTP API。Write()依据url.Parse得到的 scheme 分支调用WriteTelnetWriteHTTP,遇到其它 scheme 会返回 "unknown scheme in host parameter"(见 opentsdb.go)
port必填服务端口,Telnet 与 HTTP 模式都会拼接为host:port使用
http_batch_size0(见下)HTTP 模式下每次请求最多携带的数据点数量,达到该数量即触发一次 flush;Telnet 模式不使用此参数
http_path/api/putHTTP 请求的 URI 路径,反向代理后部署 OpenTSDB 时改为代理前缀
debugfalsetrue时打印与 OpenTSDB 的完整通信内容(详见第五节)
separator_拼接 measurement 名与 field 名的分隔符,即最终键为prefix + measurement + separator + field

需要说明的是http_batch_size的默认行为:若未显式配置,sendDataPointmetricCounter == BatchSize时才会触发 flush,而该值默认 0 会导致每个点独立成批后由Write末尾的flush()一次性发送;官方示例建议配置为50,这与 opentsdb_test.go 中基准测试使用的 batch size 一致。

2.3 全局配置选项

与其他 Telegraf 插件一样,[[outputs.opentsdb]]也支持用于修改指标、标签、字段、创建别名以及配置插件执行顺序的全局配置项,详见 docs/CONFIGURATION.md#plugins 中关于 插件级通用配置 的说明。


三、Telnet 模式:行协议写入的完整原理

3.1 协议格式

OpenTSDB Telnet 模式期望的输入格式如下:

put <metric> <timestamp> <value> <tagk1=tagv1[ tagk2=tagv2 ...tagkN=tagvN]>

Telegraf 输出插件会为指标键添加可选前缀,从而支持按子集查询:

put <[prefix.]metric> <timestamp> <value> <tagk1=tagv1[ tagk2=tagv2 ...tagkN=tagvN]>

3.2 真实数据样例

以下是从systemmemioping等输入插件采集后写入的典型行:

put nine.telegraf.system_load1 1441910356 0.430000 dc=homeoffice host=irimame scope=green put nine.telegraf.system_load5 1441910356 0.580000 dc=homeoffice host=irimame scope=green put nine.telegraf.system_load15 1441910356 0.730000 dc=homeoffice host=irimame scope=green put nine.telegraf.system_uptime 1441910356 3655970.000000 dc=homeoffice host=irimame scope=green put nine.telegraf.system_uptime_format 1441910356 dc=homeoffice host=irimame scope=green put nine.telegraf.mem_total 1441910356 4145426432 dc=homeoffice host=irimame scope=green ... put nine.telegraf.io_write_bytes 1441910366 0 dc=homeoffice host=irimame name=vda2 scope=green put nine.telegraf.io_read_time 1441910366 0 dc=homeoffice host=irimame name=vda2 scope=green put nine.telegraf.io_write_time 1441910366 0 dc=homeoffice host=irimame name=vda2 scope=green put nine.telegraf.io_io_time 1441910366 0 dc=homeoffice host=irimame name=vda2 scope=green put nine.telegraf.ping_packets_transmitted 1441910366 dc=homeoffice host=irimame scope=green url=www.google.com put nine.telegraf.ping_packets_received 1441910366 dc=homeoffice host=irimame scope=green url=www.google.com put nine.telegraf.ping_percent_packet_loss 1441910366 0.000000 dc=homeoffice host=irimame scope=green url=www.google.com put nine.telegraf.ping_average_response_ms 1441910366 24.006000 dc=homeoffice host=irimame scope=green url=www.google.com ...

注意样例中system_uptime_formatping_packets_transmitted等行在value位置为空——对应字段值为字符串类型时被插件跳过,最终只保留该测量下的数值型字段(详见第六节)。

3.3 底层实现剖析

Telnet 写入的完整逻辑位于 opentsdb.go:

  1. 建立连接:每次Write调用都会net.ResolveTCPAddr+net.DialTCP新建一条 TCP 连接,逐行写入后关闭;
  2. 时间戳换算m.Time().UnixNano() / 1000000000将纳秒时间戳转为秒;
  3. 标签排序ToLineFormat(cleanTags(m.Tags()))先把标签键值清洗、剔除空值,再按键名排序后拼接为k=v k=v空格分隔串——排序保证了同一指标的标签序列稳定(对应测试TestBuildTagsTelnet{"aaa": "bbb", "one": "two"}输出为aaa=bbb one=two,见 opentsdb_test.go);
  4. 行拼接:每行格式为put <sanitized-name> <sec> <value> <tags>\n
  5. 数值格式化buildValueint64uint64float64分别转字符串,浮点使用strconv.FormatFloat(v, 'f', 6, 64)固定 6 位小数输出(见 opentsdb.go),这解释了样例中0.4300003655970.000000的形态。

3.4 用 Go 模拟 Telnet 读取端验证写入

无需部署真实 OpenTSDB,即可用下面这段 Go 程序模拟 Telnet 服务端监听localhost:4242,把 Telegraf 写入的每一行原样打印到标准输出,用于验证插件输出格式:

// opentsdb_telnet_mode_mock.go package main import ( "io" "log" "net" "os" ) func main() { l, err := net.Listen("tcp", "localhost:4242") if err != nil { log.Fatal(err) } defer l.Close() for { conn, err := l.Accept() if err != nil { log.Fatal(err) } go func(c net.Conn) { defer c.Close() io.Copy(os.Stdout, c) }(conn) } }

运行该程序后再启动 Telegraf(将host指向localhost),即可在终端实时看到形如put ...的行协议输出。


四、HTTP 模式:JSON + gzip 批量上报

4.1 工作原理

HTTP 模式实现在 opentsdb_http.go 中,核心流程为:

  1. 数据点组装:每个数据点被封装为HTTPMetric结构体,其 JSON 序列化为{"metric": "...", "timestamp": ..., "value": ..., "tags": {...}}
  2. 批量缓冲requestBody内部使用gzip.Writer压缩 +json.Encoder编码,先写[再逐点追加,点间以逗号分隔,最终闭合为]——即一个合法的 JSON 数组;
  3. 触发发送sendDataPoint每接收一个点递增metricCounter,当达到http_batch_size时立即flush()发送并清零计数;Write结束前会再调用一次flush()冲刷剩余数据;
  4. 请求构建POSTscheme://host:port + http_path,请求头固定携带Content-Type: application/jsonContent-Encoding: gzip
  5. 响应处理:非 2xx 状态码下,4xx 被记录错误日志并主动丢弃该批指标以避免内存缓冲溢出,其余错误状态码直接返回 error 触发 Telegraf 重试;响应体被io.Copy(io.Discard, ...)消费以复用 HTTP 连接。

4.2 反向代理场景

当 OpenTSDB 部署在反向代理(如 Nginx)之后时,只需调整http_path指向代理的挂载路径,例如:

[[outputs.opentsdb]] host = "http://internal-opentsdb" port = 80 http_path = "/opentsdb/api/put"

4.3 特殊值与类型过滤

HTTP 与 Telnet 两种模式共享同一套字段类型过滤逻辑(见 opentsdb.go):

  • 仅接受int64uint64float64三种数值类型;
  • float64NaN±Inf时直接跳过(JSON 无法表示这些特殊值);
  • 其它类型(字符串、布尔等)记录 Debug 日志后跳过。

五、debug 模式:抓取通信细节

debug = true时,HTTP 模式会额外执行:

  1. 请求 URL 追加?details查询参数,让 OpenTSDB 返回详细的处理结果;
  2. 发送前用httputil.DumpRequestOut打印请求头,并输出未压缩的原始 body;
  3. 接收后用httputil.DumpResponse打印完整响应(含 body)。

调试完毕后建议关闭该选项,避免在日志中泄露敏感信息与产生大量冗余输出。Telnet 模式不受debug影响,可结合 3.4 节的模拟服务端查看写入内容。


六、指标名与标签的清洗规则

6.1 sanitize 规则

OpenTSDB 对指标名与标签值有字符限制,插件通过sanitize()(见 opentsdb.go)统一处理,规则如下:

输入字符处理方式
@*%#$替换为-(连字符)
其它非法字符(非a-zA-Z0-9、非-_./、非 Unicode 字母)替换为_(下划线)
Unicode 字母(如μnicodε_letters保留
空格、emoji 等替换为_

对应测试TestSanitize验证了这些行为:"ascii 123""ascii_123""@*%#$!""-----_""“☢”""___"(见 opentsdb_test.go)。

6.2 标签清洗(cleanTags)

cleanTags(见 opentsdb.go)会:

  • 对标签键与标签值分别执行sanitize
  • 剔除清洗后为空字符串的标签(空值标签对 OpenTSDB 无意义且会导致写入失败)。

测试TestCleanTags覆盖了特殊字符、Unicode 字母、emoji 与空 map 等用例。


七、Connect 校验与注册机制

Connect()(见 opentsdb.go)在 Telegraf 启动时执行一次连接预检:先为无 scheme 的 host 补tcp://,随后url.ParseResolveTCPAddrDialTCP建立临时连接,成功即关闭。这意味着若 OpenTSDB 地址不可达,Telegraf 会在启动阶段即报错退出,属于"快速失败"设计。

插件通过 plugins/outputs/all/opentsdb.go 在默认构建中注册;使用自定义构建(custom build)时,该文件的构建标签!custom || outputs || outputs.opentsdb允许按需裁剪插件集合。


八、可接受的指标值类型

官方文档明确指出:OpenTSDB 仅允许整数(integers)与浮点数(floats)作为数据点值。结合插件实现,具体映射为:

Telegraf 字段类型处理方式
int64直接写入,十进制整数格式
uint64直接写入,十进制整数格式
float64写入,Telnet 模式固定 6 位小数;NaN/Inf 跳过
其它(string/bool 等)记录 Debug 日志并跳过该字段

TestWriteIntegration(见 opentsdb_test.go)中的正反例验证了 float、int、uint 可正常写入,而字符串类型 "Lorem Ipsum" 会被跳过,同时验证了带特殊字符的指标名也能通过清洗后写入。


九、实践建议汇总

  1. 协议选择:OpenTSDB 2.0+ 推荐 HTTP API(host = "http://..."),单请求批量发送吞吐更高且自带 gzip 压缩;老版本或最小化部署可用 Telnet;
  2. 合理设置http_batch_size:建议 50~500 之间,过小增加请求次数,过大占用内存并延迟上报;
  3. 善用prefix:用prefix = "dc1.host."之类的前缀区分机房/业务命名空间,便于按前缀筛选数据;
  4. 配置debug = true排查问题:确认键名、标签与时间戳是否符合预期后再关闭;
  5. 避免特殊字符:指标与标签中尽量使用字母、数字、-_./,减少清洗带来的命名偏差;
  6. 检查时间戳精度:插件统一输出秒级时间戳,跨时区场景无需额外处理。

延伸阅读

  • 插件完整源码:plugins/outputs/opentsdb/opentsdb.go、plugins/outputs/opentsdb/opentsdb_http.go
  • 示例配置:plugins/outputs/opentsdb/sample.conf
  • 单元测试与集成测试:plugins/outputs/opentsdb/opentsdb_test.go
  • 插件注册入口:plugins/outputs/all/opentsdb.go
  • Telegraf 全局与插件级配置说明: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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询