Telegraf HTTP Output 插件深度解析:配置选项、多类认证机制与底层实现原理
【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf
本文以 Telegraf 仓库中的 HTTP Output 插件文档(plugins/outputs/http/README.md)为核心,完整覆盖该插件的全部配置项与认证方式,并结合 plugins/outputs/http/http.go 等源码说明批量/逐条发送、Gzip 压缩、AWS 签名、状态码重试等关键行为的底层实现。读完本文,你可以把任意指标数据格式通过 HTTP 投递到自建网关、Cloud Run 函数或 API Gateway,并正确配置 Basic Auth、OAuth2、Google ID Token 与 Cookie 四类认证。
插件定位与工作机制
HTTP Output 插件将采集到的指标序列化后,通过一次(或多次)HTTP 请求写入任意 HTTP 端点,支持 Telegraf 提供的所有 输出数据格式。自 Telegraf v1.7.0 引入,适用于所有平台。
从源码结构看,插件的核心行为集中在 Write 方法:
- 批量格式(默认):
use_batch_format = true时,整个 metric 批次通过serializer.SerializeBatch(metrics)序列化为一个请求体,一次性发出,网络开销与序列化开销都最低; - 逐条格式:设为
false后,每条 metric 独立序列化并独立发起一次请求。仅在下游端点必须逐条消费行格式数据时才需要这样配置。
插件通过 init 函数 以名称http注册到输出插件注册表(outputs.Add("http", ...)),默认值为:
| 配置项 | 默认值 | 来源 |
|---|---|---|
url | http://127.0.0.1:8080/telegraf | http.go 常量defaultURL |
method | POST | 常量defaultMethod |
use_batch_format | true | 常量defaultUseBatchFormat |
timeout | 5s(timeout为 0 时兜底) | config.go |
注意method只允许POST、PUT、PATCH三种取值,Connect 方法 会将其统一转为大写并校验,非法方法会在插件连接阶段直接报错;http_test.go 中的TestInvalidMethod与TestMethod测试用例验证了 GET 方法被拒绝、默认方法为 POST 的行为。
完整配置示例
以下是插件官方示例配置(plugins/outputs/http/sample.conf)的完整内容,可直接复制进 telegraf 配置文件使用:
# A plugin that can transmit metrics over HTTP [[outputs.http]] ## URL is the address to send metrics to url = "http://127.0.0.1:8080/telegraf" ## HTTP method, one of: "POST" or "PUT" or "PATCH" # method = "POST" ## HTTP Basic Auth credentials # username = "username" # password = "pa$$word" ## Google API Auth # google_application_credentials = "/etc/telegraf/example_secret.json" ## Amount of time allowed to complete the HTTP request # timeout = "5s" ## HTTP connection settings # idle_conn_timeout = "0s" # max_idle_conn = 0 # max_idle_conn_per_host = 0 # response_timeout = "0s" ## Use the local address for connecting, assigned by the OS by default # local_address = "" ## Optional proxy settings # use_system_proxy = false # http_proxy_url = "" ## Optional TLS settings ## 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 ## See https://pkg.go.dev/crypto/tls#pkg-constants for supported values. ## 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 ## OAuth2 Client Credentials. The options 'client_id', 'client_secret', and 'token_url' are required to use OAuth2. # client_id = "clientid" # client_secret = "secret" # token_url = "https://indentityprovider/oauth2/v1/token" # audience = "" # scopes = ["urn:opc:idm:__myscopes__"] ## Optional Cookie authentication # cookie_auth_url = "https://localhost/authMe" # cookie_auth_method = "POST" # cookie_auth_username = "username" # cookie_auth_password = "pa$$word" # cookie_auth_headers = { Content-Type = "application/json", X-MY-HEADER = "hello" } # cookie_auth_body = '{"username": "user", "password": "pa$$word", "authenticate": "me"}' ## cookie_auth_renewal not set or set to "0" will auth once and never renew the cookie # cookie_auth_renewal = "0s" ## Data format to output. ## Each data format has it's 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" ## Use batch serialization format (default) instead of line based format. ## Batch format is more efficient and should be used unless line based ## format is really needed. # use_batch_format = true ## HTTP Content-Encoding for write request body, can be set to "gzip" to ## compress body or "identity" to apply no encoding. # content_encoding = "identity" ## Amazon Region #region = "us-east-1" ## Amazon Credentials ## Amazon Credentials are not built unless the following aws_service ## setting is set to a non-empty string. It may need to match the name of ## the service output to as well #aws_service = "execute-api" ## Credentials are loaded in the following order ## 1) Web identity provider credentials via STS if role_arn and web_identity_token_file are specified ## 2) Assumed credentials via STS if role_arn is specified ## 3) explicit credentials from 'access_key' and 'secret_key' ## 4) shared profile from 'profile' ## 5) environment variables ## 6) shared credentials file ## 7) EC2 Instance Profile #access_key = "" #secret_key = "" #token = "" #role_arn = "" #web_identity_token_file = "" #role_session_name = "" #profile = "" #shared_credential_file = "" ## Optional list of statuscodes (<200 or >300) upon which requests should not be retried # non_retryable_statuscodes = [409, 413] ## NOTE: Due to the way TOML is parsed, tables must be at the END of the ## plugin definition, otherwise additional config options are read as part of ## the table ## Additional HTTP headers # [outputs.http.headers] # ## Should be set manually to "application/json" for json data_format # Content-Type = "text/plain; charset=utf-8"核心配置项解析
url、method 与请求基础行为
url:指标投递目标地址,唯一必填项(虽然不填也会走默认值http://127.0.0.1:8080/telegraf,实际使用务必显式配置)。method:请求方法,仅接受POST/PUT/PATCH(大小写不敏感,源码会strings.ToUpper归一化后校验)。timeout:单次 HTTP 请求允许完成的总时长,未设置时为 5 秒,由公共客户端配置逻辑 HTTPClientConfig.CreateClient 统一兜底。
data_format 与 use_batch_format
data_format决定序列化方式,各格式还有各自的专属配置段(如 JSON 的缩进/时间戳选项等),完整列表见 DATA_FORMATS_OUTPUT.md。序列化器由 Agent 在启动时通过SetSerializer注入插件(见 http.go)。
use_batch_format默认true,对支持批量序列化的格式(如 influx、json)一次请求发送整个批次,显著降低 QPS 与带宽消耗;只有在下游真的需要“一行一条”的流式格式时才关闭它。
content_encoding:Gzip 压缩
设置content_encoding = "gzip"时,writeMetric 会用internal.CompressWithGzip对请求体做透明压缩,并自动添加Content-Encoding: gzip请求头;默认identity不编码。对于大批量指标写入带宽敏感链路时建议开启。
自定义请求头 headers
[outputs.http.headers]表用于追加任意 HTTP 头,例如data_format = "json"时应手动将Content-Type设为application/json(默认是text/plain; charset=utf-8,见 http.go 常量)。两个源码级细节值得注意:
- 表头必须放在插件定义的最后,否则 TOML 解析会把后续配置项误读入该表(官方示例配置中也有 NOTE 强调);
- 头值以
config.Secret类型存储(见 HTTP 结构体),支持从 secret store 读取,用后销毁,避免明文凭据驻留内存;其中特殊的host键会被设置到请求的 Host 字段而非普通请求头(http.go)。
四类认证机制详解
Basic Auth
配置username与password即可启用。源码中两个字段均为config.Secret类型,writeMetric 在每次请求时取值、req.SetBasicAuth后立即Destroy(),实现最小化凭据暴露窗口。
Google API Auth
google_application_credentials指向 Google 服务账号的 JSON key 文件,用于向 Google Cloud API(如部署在 Cloud Run 上的指标代理)发送带身份的请求。从源码看(getAccessToken):
- 使用
google.golang.org/api/idtoken库,以目标 URL 作为 audience换取 ID Token; - 获取到的
oauth2.Token会缓存在插件实例中,token 有效期间(oauth2Token.Valid()为真)直接复用,不做重复换取; - 请求上通过
token.SetAuthHeader(req)附加 Bearer 认证头。
文档给出的典型用例是投递到 Cloud Run 的 metrics proxy,此时服务账号需要被授予调用该函数的权限(run.routes.invoke)。
OAuth2 Client Credentials
需同时配置client_id、client_secret、token_url三项才会启用;audience与scopes为可选,audience会以表单参数形式附加到 token 端点请求中。底层实现位于 plugins/common/oauth/config.go,基于golang.org/x/oauth2/clientcredentials,由公共 HTTP 客户端配置在创建 client 时包装注入,因此 token 的获取与刷新对该插件完全透明。
Cookie Authentication
针对不提供 OAuth/Basic Auth 的服务(如 Tesla Powerwall 的家庭监控 API,其通过 Cookie Auth Body 换取授权 cookie),插件支持在连接建立时向授权端点请求 cookie,并在后续 API 请求中自动携带。相关字段定义在 plugins/common/cookie/cookie.go:
| 配置项 | 说明 |
|---|---|
cookie_auth_url | 授权端点地址 |
cookie_auth_method | 授权请求方法,默认 POST |
cookie_auth_username/cookie_auth_password | 对授权请求附加 Basic Auth |
cookie_auth_headers | 授权请求的额外头(支持 secret store) |
cookie_auth_body | 授权请求体,如{"username": "user", "password": "..."} |
cookie_auth_renewal | 续期间隔;不设置或为0表示只认证一次、永不再续 |
从源码结构看其工作方式(cookie.go):Start阶段先执行一次auth(),若renewal > 0则启动后台 goroutine 按 ticker 周期重新认证,续期失败会写 Error 日志而不中断插件;每次认证前会重建空的 cookiejar,确保旧 cookie 不会被用于重新认证流程本身;认证响应状态码非 2xx 时返回错误。由于 cookie 保存在共享http.Client的 Jar 中,后续由 CreateClient 创建的写请求 client 天然携带该 cookie。
连接、TLS 与代理
上述连接相关选项(timeout、idle_conn_timeout、max_idle_conn、max_idle_conn_per_host、response_timeout、local_address、use_system_proxy、http_proxy_url以及全部tls_*项)来自公共结构common_http.HTTPClientConfig,完整字段定义见 plugins/common/http/config.go,对应的传输层默认配置与客户端默认配置分别收录于 transport.conf 与 client.conf。要点:
tls_enable显式设为 true/false 可强制启用/禁用 TLS;不设置时,仅当其他 TLS 选项(证书、SNI、密码套件等)任一被指定时才启用 TLS;local_address用于绑定本机出口 IP,源码通过自定义net.Dialer实现(config.go);- 该客户端还注册了
http+unix/https+unix传输协议(config.go),意味着从源码结构看,url理论上可指向 Unix domain socket 端点,配合本地 sidecar 网关可绕过 TCP 网络栈。
AWS SigV4 签名
当目标端点是 AWS API Gateway 等要求 SigV4 签名的服务时,配置aws_service(如execute-api)与region即可启用。注意:只有aws_service非空时 AWS 凭据链路才会构建,否则即使配置了access_key等字段也不会生效。
凭据加载顺序(与配置注释一致,实现位于 plugins/common/aws/credentials.go):
- Web identity provider 凭据(
role_arn+web_identity_token_file,经 STS) - STS 假定的角色凭据(仅
role_arn) - 显式
access_key/secret_key profile指定的共享 profile- 环境变量
- 共享凭据文件
- EC2 实例 Profile
签名流程在 writeMetric 中实现:先缓冲完整请求体并计算 SHA-256 十六进制摘要作为 payload hash,再用aws_signer.SignHTTP对请求做签名。之所以要先整体缓冲(而非流式传输),是因为签名方案要求对请求体求 sha256——这意味着启用 AWS 签名时,gzip 流式路径会被物化为内存缓冲。
错误处理与重试语义
writeMetric 对响应的判定逻辑是理解重试行为的关键:
- 状态码
<200或>=300视为失败,错误信息包含 URL、状态码及响应体第一行(通过io.LimitReader限制为 1024 字节,见常量maxErrMsgLen),随后return err——错误会上抛给 Agent 层,由输出缓冲/重试机制处理; - 若状态码命中
non_retryable_statuscodes列表(示例为[409, 413]),插件记录一条 "Received non-retryable status ... Metrics are lost." 的 Error 日志并返回 nil,即主动放弃这批数据、不再触发重试。适用于业务上确定重试也无意义的响应,例如 413(请求体过大); - 成功路径会读完响应体(
io.ReadAll)再关闭连接,保证连接可被正常回收复用。
Secret Store 支持
该插件对username、password、headers、cookie_auth_headers四个选项支持从 secret store 取值,语法形如username = "@secretstore_name/key",使用方式见 CONFIGURATION.md 的 secret store 章节。这一机制让敏感凭据不落盘到配置文件,与上文提到的config.Secret内存管理共同构成完整的凭据安全链路。
最小可用配置与验证路径
一个最小可运行配置只有两项:
[[outputs.http]] url = "https://example.com/ingest/metrics" data_format = "json" headers = { "Content-Type" = "application/json" }注意两点实操细节:data_format = "json"时必须手动设置Content-Type头(插件不会按格式自动推断);表头表[outputs.http.headers]若写成独立表段,需置于插件段末尾。功能正确性可参考 http_test.go 中的测试用例——其中用httptest服务器验证了默认 POST 方法、逐条/批量两种序列化路径以及 gzip 编码行为,是理解各配置项实际效果的最佳参照。
小结
HTTP Output 是 Telegraf 最通用的“兜底”输出插件:它把任何支持的数据格式变成一次标准 HTTP 请求,配合 Basic Auth、OAuth2、Google ID Token、Cookie 认证与 AWS SigV4 签名,几乎可以对接任意自建网关或云厂商 API。理解其默认行为(POST + 批量格式 + 5 秒超时 + identity 编码)、状态码重试语义与non_retryable_statuscodes的取舍,是正确使用该插件的核心。
【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考