ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Apache APISIX tcp-logger 插件实践指南:将请求日志实时推送到 TCP 服务器

Apache APISIX tcp-logger 插件实践指南:将请求日志实时推送到 TCP 服务器 Apache APISIX tcp-logger 插件实践指南将请求日志实时推送到 TCP 服务器【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisixtcp-logger 是 Apache APISIX 提供的一个日志类插件它把每个经过网关的请求封装成 JSON 对象通过 TCP 协议推送到外部的日志收集、监控分析系统如 Logstash、Vector 等。本文将基于仓库中的官方文档 docs/en/latest/plugins/tcp-logger.md结合插件源码 apisix/plugins/tcp-logger.lua 与测试用例 t/plugin/tcp-logger.t完整讲解该插件的全部配置属性、批量发送机制、自定义日志格式含 Metadata 全局配置、启用与下线方法帮助你在真实网关环境中快速接入 TCP 日志链路。功能概述tcp-logger插件用于将请求日志数据以 JSON 格式推送到 TCP 服务器。它面向典型的日志管道场景APISIX 作为 API 网关承载流量同时把访问日志实时转交给下游的 TCP 服务例如 Logstash 输入插件、Vector 的socketsource、自研日志采集服务等从而无需改造上游业务即可获得统一的访问审计与分析数据。插件支持批量batch发送日志先进入缓冲区由批量处理器Batch Processor聚合后在满足条件时一次性推送给外部 TCP 服务器避免每条请求都建立一次 TCP 连接带来的开销。由于批量发送存在缓冲日志到达外部服务器会有一定延迟触发条件由批量处理器中的定时器控制默认每5秒刷新一次或缓冲区积压达到1000条时立即发送。从源码看插件的执行优先级为405见 apisix/plugins/tcp-logger.lua属于日志类插件中较高的优先级确保日志在请求处理链路后期可靠落盘。核心发送逻辑send_tcp_data通过ngx.socket.tcp建立连接、可选执行 TLS 握手、发送序列化后的 JSON 数据并关闭连接见 send_tcp_data。插件属性Attributes详解在 Route、Service 或 Plugin Config 中启用tcp-logger时可配置以下属性名称类型必填默认值取值范围说明hoststring是TCP 服务器的 IP 地址或主机名portinteger是[0,...]目标上游端口timeoutinteger否1000[1,...]向上游发送数据的超时时间毫秒log_formatobject否以 JSON 键值对声明的日志格式值仅支持字符串字符串以$为前缀时可引用 APISIX 或 Nginx 变量tlsboolean否false设为true时启用 TLS/SSL 加密发送tls_optionsstring否TLS 选项如verify、ssl_verify等include_req_bodyboolean否false[false, true]设为true时在日志中包含请求体include_req_body_exprarray否当include_req_body为true时的过滤表达式仅当表达式求值为true时才记录请求体语法基于 lua-resty-exprinclude_resp_bodyboolean否false[false, true]设为true时在日志中包含响应体include_resp_body_exprarray否当include_resp_body为true时的过滤表达式仅当表达式求值为true时才记录响应体以上属性与插件源码 apisix/plugins/tcp-logger.lua 中的 schema 声明一一对应host与port是唯二必填项required {host, port}timeout的最小值为 1、默认 1000 毫秒tls默认false。值得注意的是插件在check_schema中还会通过core.utils.check_tls_bool对tls做布尔类型校验见 check_schema。属性使用要点timeout控制单次 TCP 连接的超时毫秒。它同时作用于连接建立、发送等阶段sock:settimeout(conf.timeout)见 send_tcp_data在目标 TCP 服务不稳定时应适当调大避免日志线程长时间阻塞。log_format自定义日志字段。值只支持字符串类型以$开头的值会被解析为变量引用如$host、$remote_addr、$time_iso8601不带$的值按字面常量输出。可用变量包括 APISIX 内置变量如route_id、service_id、consumer_name等以及 Nginx 内置变量如$host、$remote_addr、$request_uri。tls / tls_options当目标 TCP 服务器启用了 TLS如 Logstash 的ssl输入或安全的日志管道时将tls设为true。源码中会在连接建立后执行sock:sslhandshake(true, conf.tls_options, false)见 TLS 握手逻辑tls_options可传入如verify等握手选项。include_req_body / include_req_body_expr请求体采集的上限为 512 KiBMAX_REQ_BODY 524288见 apisix/utils/log-util.lua超长请求体会被截断。include_req_body_expr基于 lua-resty-expr 编写条件表达式只有条件满足时才把请求体写入日志可避免记录大体积或敏感请求体。include_resp_body / include_resp_body_expr响应体采集同样有 512 KiB 上限MAX_RESP_BODY。插件通过body_filter阶段调用log_util.collect_body收集响应体见 body_filter若响应经过 gzip 等压缩会在解码后存入日志相关实现见 collect_body。默认日志格式未配置log_format时插件通过log_util.get_full_log见 apisix/utils/log-util.lua生成完整的默认日志结构包含请求、响应、时延、路由、上游等维度的信息形如{ response: { status: 200, headers: { server: APISIX/3.7.0, content-type: text/plain, content-length: 12, connection: close }, size: 118 }, server: { version: 3.7.0, hostname: localhost }, start_time: 1704527628474, client_ip: 127.0.0.1, service_id: , latency: 102.9999256134, apisix_latency: 100.9999256134, upstream_latency: 2, request: { headers: { connection: close, host: localhost }, size: 59, method: GET, uri: /hello, url: http://localhost:1984/hello, querystring: {} }, upstream: 127.0.0.1:1980, route_id: 1 }各字段含义如下request请求方法、URI、完整 URL、请求头、查询参数与请求大小response响应状态码、响应头与响应大小serverAPISIX 实例的版本号与主机名upstream实际命中的上游地址route_id/service_id命中的路由与关联的服务 IDclient_ip客户端真实 IP支持多层代理取真实来源地址start_time请求开始时间戳毫秒latency/apisix_latency/upstream_latency总时延、APISIX 自身处理时延与上游时延毫秒计算细节见 latency_details_in_ms。若请求或响应体被采集include_req_body/include_resp_body生效对应内容会追加到request.body与response.body字段中。批量处理器Batch Processor机制tcp-logger依赖 APISIX 的批量处理器来聚合日志、批量推送避免每条请求都触发一次 TCP 连接。批量处理器通过batch_processor_manager:wrap_schema将以下参数注入到插件 schema见 apisix/utils/batch-processor-manager.lua 与 batch-processor.lua名称类型默认值说明namestring插件名如 tcp logger批量处理器标识batch_max_sizeinteger1000每个批次最多容纳的日志条数达到上限立即推送inactive_timeoutinteger5缓冲区最大刷新间隔秒到期后无论条数多少都推送buffer_durationinteger60批次中最早一条日志的最大存活时长秒超时强制处理max_retry_countinteger0发送失败时的最大重试次数retry_delayinteger1重试前的延迟秒数发送触发逻辑是每 5 秒或缓冲区积压达到 1000 条时自动推送inactive_timeout建议小于buffer_duration以获得最优的刷新节奏。当batch_max_size设为 1 时每条日志立即发送见批量处理器文档 docs/en/latest/batch-processor.md。从源码 log 阶段 可以看到发送序列化细节batch_max_size 1时对单条日志编码为单个 JSON 对象{}否则编码为 JSON 数组[{}]随后交给send_tcp_data发送。测试用例 t/plugin/tcp-logger.t 也验证了发送失败不可达主机时错误信息failed to connect to TCP server: host[...] port[...]会写入 error log并可配合max_retry_count、retry_delay进行重试。通过 Metadata 全局配置日志格式除在插件配置中设置log_format外还可以通过**插件元数据Plugin Metadata**统一配置日志格式名称类型必填默认值说明log_formatobject否以 JSON 键值对声明的日志格式值仅支持字符串字符串以$为前缀时可引用 APISIX 或 Nginx 变量注意插件元数据是全局生效的一旦配置会作用于所有使用了tcp-logger插件的 Route 与 Service。因此适合在团队内统一日志字段规范如统一时间戳、客户端 IP、主机名字段个别路由的特殊格式则放到插件自身的log_format中覆盖。首先从conf/config.yaml中取出 Admin API 密钥并写入环境变量admin_key$(yq .deployment.admin.admin_key[0].key conf/config.yaml | sed s///g)然后通过 Admin API 配置tcp-logger的元数据curl http://127.0.0.1:9180/apisix/admin/plugin_metadata/tcp-logger -H X-API-KEY: $admin_key -X PUT -d { log_format: { host: $host, timestamp: $time_iso8601, client_ip: $remote_addr } }配置生效后推送到 TCP 服务器的日志会被格式化为如下精简结构route_id由插件自动附加{timestamp:2023-01-09T14:47:2508:00,route_id:1,host:localhost,client_ip:127.0.0.1}元数据解析逻辑位于 get_log_entry当插件配置或元数据中存在非空log_format时走get_custom_format_log生成自定义日志否则 HTTP 子系统使用get_full_log生成完整日志。字段值以$开头时通过ctx.var取变量见 gen_log_format / get_custom_format_log。测试用例 t/plugin/tcp-logger.t 还覆盖了元数据log_format类型错误应为 object会被 400 拒绝、以及元数据格式与插件内log_format的优先级行为。在 Route 上启用插件以下示例在id5的 Route 上启用tcp-logger将日志推送到127.0.0.1:5044典型 Logstash TCP 输入端口。示例中还显式设置了batch_max_size: 1让日志即时发送便于联调观察curl http://127.0.0.1:9180/apisix/admin/routes/5 -H X-API-KEY: $admin_key -X PUT -d { plugins: { tcp-logger: { host: 127.0.0.1, port: 5044, tls: false, batch_max_size: 1, name: tcp logger } }, upstream: { type: roundrobin, nodes: { 127.0.0.1:1980: 1 } }, uri: /hello }生产环境中建议去掉batch_max_size: 1采用默认批量策略每 5 秒或每 1000 条推送一次以降低 TCP 连接频率、提升吞吐。插件同样可以挂在 Service 或 Plugin Config 上实现一条配置、多路由复用。验证日志输出启用插件后向网关发起一次请求curl -i http://127.0.0.1:9080/hello此时在目标 TCP 服务器如 Logstash 或自定义 TCP 监听程序上即可收到该请求的 JSON 日志。若要快速验证可在测试环境用nc或socat监听端口观察原始报文例如nc -l 5044日志结构默认为完整格式见上文默认日志格式包含请求/响应头、时延、路由、上游等信息若配置了元数据log_format则输出自定义精简格式。测试用例 t/plugin/tcp-logger.t 进一步覆盖了tls: true的加密发送、include_req_body: true采集请求体日志中出现body:{\sample_payload\:\hello\}以及include_resp_body: true采集响应体等场景可作为接入时的行为参考。删除插件移除tcp-logger只需从 Route或 Service配置中删除对应插件配置块即可。APISIX 会自动热加载新配置无需重启网关curl http://127.0.0.1:9180/apisix/admin/routes/1 -H X-API-KEY: $admin_key -X PUT -d { methods: [GET], uri: /hello, plugins: {}, upstream: { type: roundrobin, nodes: { 127.0.0.1:1980: 1 } } }将plugins置为空对象{}后该 Route 即不再产生 TCP 日志。若此前配置了plugin_metadata/tcp-logger的全局格式可通过DELETE /apisix/admin/plugin_metadata/tcp-logger删除元数据恢复各插件自身的默认格式。典型使用场景与注意事项对接日志管道将host/port指向 LogstashTCP input、Vectorsocket source等即可把 APISIX 访问日志接入 ELK/日志平台需要加密传输时开启tls。统一日志字段利用元数据log_format收敛所有 Route 的日志格式便于下游按timestamp、client_ip等字段建索引与分析。控制日志体积默认完整格式包含全部请求/响应头数据量大可用log_format精简字段或用include_req_body_expr/include_resp_body_expr只对特定请求记录 body。可靠性发送失败时错误会记录到 error log并通过max_retry_count/retry_delay控制重试批量缓冲意味着日志存在数秒级延迟对实时性要求极高的场景可将batch_max_size调小甚至为 1。限制说明请求体与响应体采集均存在 512 KiB 上限超长内容会被截断include_resp_body依赖body_filter阶段需确认该阶段未被其他插件干扰。总结tcp-logger是 APISIX 日志生态中面向 TCP 管道的轻量级输出插件属性简洁必填仅host与port支持 TLS 加密、请求/响应体采集、自定义与全局日志格式并内置批量处理器以平衡吞吐与延迟。结合 apisix/plugins/tcp-logger.lua 的发送实现、apisix/utils/log-util.lua 的日志采集逻辑以及 t/plugin/tcp-logger.t 的行为测试你可以放心地将它接入自己的日志链路实现网关流量的低成本、高吞吐采集与分析。【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisix创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表