Telegraf HTTP Listener v2 输入插件完全指南:从配置到源码级原理
【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf
导读
http_listener_v2是 Telegraf 提供的一个 Service Input 输入插件,用于通过 HTTP 协议接收任意被支持的数据格式(如 InfluxDB Line Protocol、JSON 等)并将其解析为指标,是搭建自定义指标采集端点、构建 HTTP 数据写入网关的首选方案。本文将以官方插件文档为主体,结合插件源码(http_listener_v2.go)与测试用例(http_listener_v2_test.go),系统讲解该插件的完整配置项、请求处理流程、TLS/认证安全机制、数据源采集方式与排障方法,帮助你快速上手并深入理解其底层实现。
一、插件定位与适用场景
http_listener_v2是一个「通用 HTTP 写入监听器」(Generic HTTP write listener),它启动一个 HTTP 服务,等待外部客户端将指标数据通过 HTTP 请求发送进来,然后按照配置的data_format解析请求体或查询参数,最终将解析出的指标写入 Telegraf 的 Accumulator 管道,供后续处理器(processors)、聚合器(aggregators)和输出(outputs)消费。
该插件支持任意 Telegraf 支持的数据输入格式,完整的格式清单与各格式独立配置选项参见 docs/DATA_FORMATS_INPUT.md。
注意(官方提示):如果你的需求是将 Telegraf 作为 InfluxDB v1 或 v2 的代理 / 中继(proxy/relay),官方建议改用 influxdb_listener 或 influxdb_v2_listener 插件,而非本插件。
插件元信息:
- ⭐ 引入版本:Telegraf v1.9.0
- 🏷️ 插件类型:server(服务型)
- 💻 支持平台:all(全平台)
插件通过 plugins/inputs/all/http_listener_v2.go 注册到默认构建中,其构建标签为//go:build !custom || inputs || inputs.http_listener_v2。
二、Service Input 特性说明
本插件是一个service input(服务型输入)。与普通插件按照全局或插件级interval定时采集不同,服务型插件会启动一个常驻服务,持续监听并等待指标或事件的到来。官方文档明确指出服务型插件与普通插件的两个关键差异(详见 docs/includes/service_input.md):
- 全局或插件专属的
interval设置可能不生效:http_listener_v2的指标到达节奏完全由外部 HTTP 请求驱动,而不是由定时器驱动; - CLI 选项
--test、--test-wait、--once可能不会为它产生输出:因为这些模式依赖一次性采集完成,而监听类插件需要等待外部数据。
对应到源码,插件的Gather方法是一个空实现(返回nil),真正的数据获取全部发生在Start()启动的 HTTP server 及其ServeHTTP处理函数中,这正是"服务型"语义在代码层面的体现。
三、完整配置说明(逐参数详解)
以下为官方sample.conf(即 plugins/inputs/http_listener_v2/sample.conf,由 README 通过@sample.conf指令内嵌)的完整配置:
# Generic HTTP write listener [[inputs.http_listener_v2]] ## Address to host HTTP listener on ## can be prefixed by protocol tcp, or unix if not provided defaults to tcp ## if unix network type provided it should be followed by absolute path for unix socket service_address = "tcp://:8080" ## service_address = "tcp://:8443" ## service_address = "unix:///tmp/telegraf.sock" ## Permission for unix sockets (only available for unix sockets) ## This setting may not be respected by some platforms. To safely restrict ## permissions it is recommended to place the socket into a previously ## created directory with the desired permissions. ## ex: socket_mode = "777" # socket_mode = "" ## Paths to listen to. # paths = ["/telegraf"] ## Save path as http_listener_v2_path tag if set to true # path_tag = false ## HTTP methods to accept. # methods = ["POST", "PUT"] ## Optional HTTP headers ## These headers are applied to the server that is listening for HTTP ## requests and included in responses. # http_headers = {"HTTP_HEADER" = "TAG_NAME"} ## HTTP Return Success Code ## This is the HTTP code that will be returned on success # http_success_code = 204 ## maximum duration before timing out read of the request # read_timeout = "10s" ## maximum duration before timing out write of the response # write_timeout = "10s" ## Maximum allowed http request body size in bytes. ## 0 means to use the default of 524,288,000 bytes (500 mebibytes) # max_body_size = "500MB" ## Part of the request to consume. Available options are "body" and ## "query". # data_source = "body" ## Set one or more allowed client CA certificate file names to ## enable mutually authenticated TLS connections # tls_allowed_cacerts = ["/etc/telegraf/clientca.pem"] ## Add service certificate and key # tls_cert = "/etc/telegraf/cert.pem" # tls_key = "/etc/telegraf/key.pem" ## Minimal TLS version accepted by the server # tls_min_version = "TLS12" ## Optional username and password to accept for HTTP basic authentication. ## You probably want to make sure you have TLS configured above for this. # basic_username = "foobar" # basic_password = "barfoo" ## Optional setting to map http headers into tags ## If the http header is not present on the request, no corresponding tag will be added ## If multiple instances of the http header are present, only the first value will be used # http_header_tags = {"HTTP_HEADER" = "TAG_NAME"} ## Data format to consume. ## 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_INPUT.md data_format = "influx"3.1 监听地址与传输协议
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
service_address | string | :8080(源码默认值) | HTTP 监听地址,可带tcp://或unix://协议前缀;不带前缀时默认按tcp处理;unix协议须后跟 unix socket 的绝对路径 |
socket_mode | string | ""(空) | unix socket 的文件权限,仅对 unix socket 生效,例如"777" |
从源码(http_listener_v2.go)可以看到,Init()中通过正则\w://判断地址是否带协议前缀,若无则自动补上tcp://,随后用url.Parse解析出 scheme 与 host。Start()中再根据 scheme 分支:
tcp:直接net.Listen("tcp", address);unix:先用filepath.FromSlash(u.Path)提取 socket 路径(Windows 下会特殊处理盘符前缀),若旧 socket 文件存在则先移除,再net.Listen("unix", path),随后按socket_mode的八进制字符串(如"777")解析为os.FileMode并os.Chmod应用到 socket 文件。
官方文档还提示:socket_mode在某些平台上可能不被完全尊重,若想严格限制权限,建议把 socket 放在一个预先创建好、具有期望权限的目录中。
3.2 路由与请求匹配
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
paths | []string | ["/telegraf"](源码默认值) | 允许接收请求的 URL 路径列表,请求路径不在列表中则返回 404 |
methods | []string | ["POST", "PUT"](源码默认值) | 允许接收的 HTTP 方法,不在列表中返回 405 |
path_tag | bool | false | 为true时,把请求路径作为名为http_listener_v2_path的 tag 附加到每条指标 |
源码中ServeHTTP首先用choice.Contains(req.URL.Path, h.Paths)判断路径是否在允许列表内,不在则走http.NotFound(返回 404);serveWrite内则遍历h.Methods判断请求方法是否被允许,否则返回 405(见methodNotAllowed)。测试 TestReceive404ForInvalidEndpoint 验证了访问未注册路径/foobar返回 404 的行为;TestWriteHTTPWithMultiplePaths 验证了多个路径同时可用,且path_tag会如实记录每个请求的实际路径。
3.3 请求体与超时限制
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
read_timeout | duration | 10s | 读取请求的最大超时时间 |
write_timeout | duration | 10s | 写出响应的最大超时时间 |
max_body_size | size | 500MB(524,288,000 字节) | HTTP 请求体的最大字节数,超限返回 413;设为0表示使用默认值 |
http_success_code | int | 204 | 解析成功时返回给客户端的 HTTP 状态码 |
源码中,read_timeout与write_timeout被注入http.Server{ReadTimeout, WriteTimeout};若配置值小于 1 秒,会被强制提升为 10 秒(http_listener_v2.go)。MaxBodySize默认常量defaultMaxBodySize = 500 * 1024 * 1024,请求的ContentLength超过该值时,通过http.MaxBytesReader与tooLarge返回 HTTP 413 及 JSON 错误体{"error":"http: request body too large"}。测试 TestWriteHTTP 使用 testdata 中的超长指标(约 71 KB)验证了 413 行为,TestWriteHTTPExactMaxBodySize 则验证了恰好等于上限时仍可成功(204)。
http_success_code若未配置或为 0,源码会在Init()中回退为http.StatusNoContent(204);TestWriteHTTPWithReturnCode 验证了配置为 200 时返回 200。
3.4 数据来源:body 与 query
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
data_source | string | "body" | 从请求的哪一部分消费数据,可选"body"(请求体)或"query"(URL 查询参数) |
当data_source = "query"时,源码collectQuery会对req.URL.RawQuery做url.QueryUnescape解码,把解码后的查询串整体作为待解析内容;否则走collectBody读取请求体。搭配form_urlencoded解析器,可以直接把?tagKey=tagValue&fieldKey=42这类查询参数解析成指标——测试 TestWriteHTTPQueryParams 与 TestWriteHTTPFormData 分别验证了 query 与 form 表单两种来源的解析结果。
3.5 请求体压缩支持(源码级补充)
虽然 README 未展开说明,但从源码可见collectBody会根据请求头Content-Encoding自动解压:
gzip:用gzip.NewReader包装请求体,配合http.MaxBytesReader限制解压后大小;snappy:由于 snappy 块格式不支持 stream reader,源码先io.ReadAll整体读取,再用snappy.Decode解码;- 其他/未设置:直接读取原始字节。
对应测试 TestWriteHTTPGzippedData(读取 testdata/testmsgs.gz)与 TestWriteHTTPSnappyData 验证了两种压缩编码均能正确还原并解析指标。
3.6 TLS 服务端配置
| 参数 | 类型 | 说明 |
|---|---|---|
tls_allowed_cacerts | []string | 允许的客户端 CA 证书文件列表,配置后启用双向 TLS(mTLS),强制要求并校验客户端证书 |
tls_cert | string | 服务端证书文件路径 |
tls_key | string | 服务端私钥文件路径 |
tls_min_version | string | 服务端接受的最低 TLS 版本,如"TLS12" |
插件内嵌了通用的服务端 TLS 配置结构common_tls.ServerConfig(定义于 plugins/common/tls/server.go)。从该结构体可以看到,除文档列出的参数外还支持tls_key_pwd(私钥密码)、tls_cipher_suites(密码套件)、tls_max_version、tls_allowed_dns_names(客户端证书允许的 DNS 名称列表,配合 mTLS 做证书域名校验)等进阶选项。
TLS 的启用逻辑在ServerConfig.TLSConfig()中:当tls_cert、tls_key、tls_allowed_cacerts全为空时返回nil,表示不启用 TLS;只要配置了证书,Start()就会改用tls.Listen启动 HTTPS 服务。配置了tls_allowed_cacerts时,ClientAuth被设为tls.RequireAndVerifyClientCert,即强制双向认证。测试 TestWriteHTTPSNoClientAuth 与 TestWriteHTTPSWithClientAuth(使用 testutil/pki 中的测试证书)分别覆盖了纯服务端 TLS 与 mTLS 两种场景。
3.7 HTTP Basic 认证
| 参数 | 类型 | 说明 |
|---|---|---|
basic_username | string | Basic 认证用户名 |
basic_password | string | Basic 认证密码 |
源码authenticateIfSet中:仅当用户名与密码同时非空时才启用认证,通过req.BasicAuth()取出请求凭据,并使用crypto/subtle的ConstantTimeCompare做常数时间比较,以降低时序侧信道风险;认证失败返回401 Unauthorized。由于 Basic 认证的凭据以明文(Base64)随请求传输,官方文档明确建议务必配合上文的 TLS 配置一起使用。对应测试见 TestWriteHTTPBasicAuth。
3.8 请求头映射与响应头
| 参数 | 类型 | 说明 |
|---|---|---|
http_headers | map[string]string | 附加到 HTTP 响应中的响应头键值对 |
http_header_tags | map[string]string | 把请求头值映射为指标的 tag,格式为{"HTTP_HEADER" = "TAG_NAME"} |
两个参数语义不同,注意区分:
http_headers是服务端响应头:在ServeHTTP中通过res.Header().Set(key, value)写入每个响应,TestServerHeaders 验证了响应头会原样返回;http_header_tags是指标 tag 映射:在解析出指标后,从req.Header.Get(headerName)取值并m.AddTag(measurementName, headerValues)写入每条指标。官方文档特别说明:若请求中不存在该头部,则不添加对应 tag;若存在多个同名头部,只取第一个值。测试 TestWriteHTTPTransformHeaderValuesToTagsSingleWrite 与 TestWriteHTTPTransformHeaderValuesToTagsBulkWrite 验证了缺失头部不产生 tag、已有头部正确写入 tag 的行为。
3.9 数据格式
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
data_format | string | "influx" | 接收数据的输入格式,决定如何解析请求体/查询参数 |
插件实现了telegraf.Parser接口(SetParser注入解析器),data_format支持 Telegraf 全部输入数据格式,各格式有各自的专属配置选项,完整说明参见 docs/DATA_FORMATS_INPUT.md。
四、全局配置选项
与其他插件一样,http_listener_v2也支持 Telegraf 的通用插件配置能力,例如在指标上修改名称、tag、field,创建别名,以及配置插件执行顺序等,详见 docs/CONFIGURATION.md 中关于插件全局配置的说明(该部分由 docs/includes/plugin_config.md 统一提供)。
五、Metrics:指标是如何产生的
官方文档对 Metrics 的说明非常精炼:指标来自data_source参数指定的请求部分,并按data_format的值进行解析。结合源码可以还原完整的指标产生链路:
- 请求到达后先经过路径检查(404)与方法检查(405);
- 按
data_source读取请求体或查询参数,期间处理 gzip/snappy 解压与max_body_size限制(413); - 调用配置的
Parser.Parse(bytes)将字节解析为指标切片;解析失败返回 400{"error":"http: bad request"}; - 若解析结果为空,插件会以 debug 级别记录
No metrics created提示(internal.NoMetricsCreatedMsg); - 对每条指标依次应用
http_header_tags映射与path_tag(若启用),然后通过acc.AddMetric(m)写入 Accumulator; - 全部成功后写入
http_success_code(默认 204)。
关于指标名称、标签与字段的基本约定,可参考 docs/METRICS.md。若需要为生成的指标补充额外信息,可以在插件之后串联 processors 对指标做进一步加工。
六、实战:用 curl 快速验证
发送 Line Protocol(InfluxDB 行协议)
curl -i -XPOST 'http://localhost:8080/telegraf' --data-binary 'cpu_load_short,host=server01,region=us-west value=0.64 1434055562000000000'请求会返回HTTP/1.1 204 No Content,同时插件解析出测量名cpu_load_short、taghost=server01、region=us-west、fieldvalue=0.64及时间戳1434055562000000000的指标。
发送 JSON
curl -i -XPOST 'http://localhost:8080/telegraf' --data-binary '{"value1": 42, "value2": 42}'前提是把data_format配置为json(默认influx无法解析裸 JSON)。JSON 解析器的详细行为(如json_query、tag_keys、json_string_fields等选项)见 docs/DATA_FORMATS_INPUT.md。
发送查询参数
curl -i -XGET 'http://localhost:8080/telegraf?host=server01&value=0.42'前提是把data_source配置为"query",并搭配form_urlencoded解析器(参考测试 TestWriteHTTPQueryParams)。
未命中路径时的返回
curl -i -XPOST 'http://localhost:8080/not-exist' --data-binary 'cpu_load_short,host=server01 value=0.64'将返回 404,因为not-exist不在paths白名单中。
七、Troubleshooting 排查指南
结合源码与测试用例,可归纳出以下常见返回码与排查方向:
| 返回码 | 含义 | 触发条件与排查方向 |
|---|---|---|
204 / 200(或配置的http_success_code) | 成功 | 指标已解析并写入 Accumulator |
| 400 | Bad Request | 数据无法按data_format解析(如默认 influx 解析器收到非法行协议),检查请求体格式;gzip/snappy 解压失败也会返回 400 |
| 404 | Not Found | 请求路径不在paths列表内,检查 URL 路径与paths配置 |
| 405 | Method Not Allowed | HTTP 方法不在methods列表内,检查请求方法 |
| 413 | Request Entity Too Large | 请求体超过max_body_size,增大上限或分批发送 |
| 401 | Unauthorized | Basic 认证失败,检查basic_username/basic_password与请求凭据 |
另外两点提示:
- 因为本插件是 service input,
telegraf --test、--test-wait、--once等模式可能不会输出该插件的指标,验证时建议直接用curl发送真实请求,或配合 debug 日志观察; - 若解析得到 0 条指标,插件仅以 debug 级别记录
No metrics created,可通过日志级别查看(相关消息常量定义于 internal/internal.go,用法见 http_listener_v2.go)。
八、性能与并发特性(源码级佐证)
从源码结构看,插件具备良好的并发处理能力:
- 每个 HTTP 请求由 Go 标准库
http.Server在独立 goroutine 中并发处理,HTTPListenerV2结构体通过sync.WaitGroup管理服务生命周期,Stop()会先关闭 listener 再等待所有处理协程退出; - 测试 TestWriteHTTPHighTraffic 用 10 个并发 writer、每个发送 500 次、每次携带 5 条指标(合计 25,000 条)的压力场景验证了插件的并发吞吐能力,最终断言
acc.NMetrics() == 25000。
九、与 influxdb_listener 系列插件的选型
官方文档特别提示:如需让 Telegraf 充当 InfluxDB v1 / v2 的写入代理或中继,请使用 influxdb_listener 或 influxdb_v2_listener。两者的差异在于:
influxdb_listener/influxdb_v2_listener专门针对 InfluxDB 写入协议(Line Protocol)做了深度优化,支持更多 InfluxDB 专有语义(如数据库/存储桶相关行为、保留策略、批量写入语义等);http_listener_v2是通用HTTP 写入端点,data_format可切换为任意格式,适合对接非 InfluxDB 的客户端或自研采集端。
十、总结
http_listener_v2以极简的配置对外提供通用 HTTP 指标写入能力:监听地址(TCP/Unix socket)、路径与方法白名单、双数据来源(body/query)、请求体大小与超时限制、gzip/snappy 自动解压、服务端 TLS 与 mTLS、Basic 认证、请求头/路径映射为 tag,以及可插拔的data_format解析器,构成了一个完整、健壮、可安全暴露的指标采集端点。结合 sample.conf 与 http_listener_v2_test.go 中的用例,你可以快速验证每种配置的实际行为,并将其稳定地集成进自己的采集架构中。
更深入地,你可以继续阅读 docs/CONFIGURATION.md 了解插件通用配置,阅读 docs/DATA_FORMATS_INPUT.md 掌握所有可用的
data_format选项,或阅读 docs/PROCESSORS.md 学习如何对接收到的指标做进一步处理。
【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考