API 网关专栏 · 第 46

API 网关日志存储:管道、保留策略、安全与成本

2026年09月07日
API 网关日志存储:管道、保留策略、安全与成本

API 网关应该生成结构化事件,并通过有界管道投递,而不应成为长期记录系统。将可搜索的运维日志存储在日志平台中;确有需要时,把旧数据转移到成本更低的归档存储;对安全审计记录则实施更严格的访问和完整性控制。

这种分离可以避免缓慢的日志目标影响请求处理,为每类数据建立明确的保留策略,并让成本透明。它还避免了一种常见错误:先收集所有请求头和请求体,等数据进入多个系统后才判断是否安全。

核心要点

  • 分离日志生成、传输、索引、归档和删除职责。
  • 优先使用字段允许列表;默认不要记录凭证、Cookie 或请求体。
  • 为投递缓冲设置硬性上限,并决定目标不可用时的处理方式。
  • 将运维访问日志与安全审计日志视为控制要求不同的两类产品。
  • 根据用途、调查窗口、法律要求和成本设置保留时间,而不是套用统一天数。
  • 监控日志管道自身,包括队列深度、丢弃条目、投递错误和写入延迟。

网关是日志生产者,而不是归档系统

网关适合记录每个请求的路由、已认证身份上下文、上游结果和耗时,却不适合保留数月数据:本地磁盘有限,网关实例会被替换,而且存储故障不能耗尽全部内存或阻塞 API 流量。

生产管道通常划分为五个阶段:

1flowchart LR
2    A[API 网关\n结构化事件] --> B[有界批处理或缓冲]
3    B --> C[收集器或消息代理]
4    C --> D[热数据可搜索存储]
5    D --> E[低成本归档]
6    E --> F[到期或删除]
7    C --> G[安全分析]

有界缓冲可以吸收短暂中断。收集器或消息代理负责规范化投递,并解耦网关可用性与存储后端。热存储支持近期故障排查和仪表盘。归档存储是可选项,只应存放有明确未来用途的数据。到期删除是设计的一部分,不是事后补救。

本文聚焦存储和投递。如需综合选择日志、指标和追踪,请参阅 API 网关日志与监控最佳实践

有意识地选择投递模式

Apache APISIX 为多种投递模式提供日志插件,包括 http-loggerkafka-loggerelasticsearch-loggerfile-loggersyslog。存在某个连接器并不代表它就是正确架构。

模式适用场景主要权衡
标准输出或文件 + 节点 Agent已有成熟收集器的容器或虚拟机平台依赖本地轮换、磁盘限制和 Agent 健康状态
HTTP(S) 收集器组件较少的简单集中式采集收集器容量和 TLS 配置成为关键因素
Kafka 或其他持久化消息代理高流量、多个消费者或需要重放增加一套需要运维的系统及端到端延迟
直接投递到搜索存储小型受控环境让网关与索引可用性及模式变更耦合更紧

对于大多数分布式部署,相比让每个网关实例直接连接搜索集群,本地收集器或持久化消息代理可以建立更清晰的故障边界。规模不大且团队已测试故障行为时,直接投递也可能合理。

设计最小可用模式

从事故响应人员和安全团队真正需要回答的问题出发。实用的访问事件通常包含:

字段组示例设计说明
关联时间戳、请求 ID、Trace ID在各服务间使用稳定标识符
路由路由 ID、服务 ID、方法、路由模板优先使用模板,避免包含标识符或查询字符串的原始 URI
身份调用方或租户假名、凭证类型不要记录凭证本身
结果网关状态、上游状态、发送字节数区分网关拒绝与上游失败
耗时总延迟、上游延迟和网关延迟使用一致的单位和定义
网络可信客户端地址或区域记录转发地址前先定义代理信任关系

默认不要记录 Authorization、API Key、会话 Cookie、查询字符串中的密钥,或请求与响应正文。OWASP 日志记录速查表建议清理事件数据,并在传输和存储期间保护日志。即使看似无害的字段,组合后也可能成为个人信息或机密数据,因此要记录整个事件的用途和访问权限。

当网关与服务日志共用一条管道时,OpenTelemetry 的日志数据模型有助于统一时间戳、严重级别、资源属性、追踪关联和事件正文。采用该模型并不会消除脱敏或保留规则的需要。

配置有界 APISIX HTTP 日志管道

下面的 APISIX 3.18 配置片段为 http-logger 定义全局字段允许列表格式和最大待处理条目积压量。插件元数据是全局的,会影响使用该插件的每个 Route 和 Service,因此更改前要审查现有使用方。

1curl "http://127.0.0.1:9180/apisix/admin/plugin_metadata/http-logger" \
2  -X PUT \
3  -H "X-API-KEY: ${admin_key}" \
4  -d '{
5    "log_format": {
6      "timestamp": "$time_iso8601",
7      "request_id": "$apisix_request_id",
8      "route_id": "$route_id",
9      "service_id": "$service_id",
10      "method": "$request_method",
11      "status": "$status",
12      "request_time": "$request_time",
13      "upstream_response_time": "$upstream_response_time",
14      "bytes_sent": "$bytes_sent"
15    },
16    "max_pending_entries": 8192
17  }'

接下来,启用向内部 HTTPS 收集器的投递。由于当前 http-logger 默认不启用证书验证,示例显式打开该选项。示例特意省略认证值;如果收集器要求认证,应使用平台的密钥管理机制,而不是在 Route 中嵌入真实密钥。

1curl "http://127.0.0.1:9180/apisix/admin/routes/orders-read" \
2  -X PUT \
3  -H "X-API-KEY: ${admin_key}" \
4  -d '{
5    "uri": "/orders/*",
6    "methods": ["GET"],
7    "plugins": {
8      "request-id": {},
9      "http-logger": {
10        "uri": "https://logs.internal.example/v1/events",
11        "ssl_verify": true,
12        "include_req_body": false,
13        "include_resp_body": false
14      }
15    },
16    "upstream": {
17      "type": "roundrobin",
18      "nodes": {
19        "orders.internal:8080": 1
20      }
21    }
22  }'

APISIX 3.15 及更高版本通过 $apisix_request_id 暴露网关当前请求 ID。启用 request-id 后,它就是插件生成或接受并通过配置的响应头返回的值。由于插件可以接受客户端提供的非空 ID,不能只把它作为安全证据:应验证格式,在其他字段中保存已认证身份;如果信任模型有要求,还应生成由服务端控制的关联标识符。

根据当前 APISIX 文档,http-logger 会批量发送记录,其元数据中的 max_pending_entries 默认值为 8,192。积压超过配置上限后,新条目将被丢弃,避免不可访问的日志服务无限增加工作进程内存。这是一项有意识的可用性权衡,并非持久化投递。

如果访问事件不可丢失,应在中心存储前部署可从本地访问的持久化传输,并验证磁盘和背压行为。不能把一个网关日志插件描述成不可篡改的审计系统。

区分运维日志与审计记录

运维访问日志用于回答“哪个路由变慢了”或“哪个上游返回了 503”;安全审计记录则回答“谁修改了这项策略”或“谁访问了受保护数据”。两者可以共享一部分基础设施,但来源与控制要求不同。

审计设计可能要求:

  • 经过认证的操作者和管理操作详情;
  • 仅追加或可检测篡改的存储;
  • 读取者与管理员的职责分离;
  • 文档化的证据保全和删除流程;
  • 对审计存储的访问、导出或策略变更发出告警。

网关请求日志无法证明它从未观察到的管理事件。当调查同时需要两种数据时,应组合数据面访问事件、控制面配置事件和身份提供商审计事件。

按数据类别设置保留与成本

不存在统一且安全的保留期限。应从事故响应、客户承诺、法规、诉讼保留和删除义务反向确定时间。

一种简单的分层模式是:

  • **热数据:**近期已索引数据,用于交互式搜索和告警调查。
  • **温数据:**较旧数据,查询更慢或成本更低。
  • **归档:**为明确的恢复或证据需求保留的压缩对象。
  • **过期数据:**根据策略以密码学或物理方式删除,并在需要时包含衍生副本。

选择存储前先估算每日数据量:

1每日写入字节数 = 每日请求数 × 编码后事件平均大小

使用这一写入基线分别估算各阶段。消息代理需要考虑保留窗口、压缩比和副本因子;热搜索存储需要考虑索引大小、分片副本、保留期和索引开销;归档与备份则使用各自的压缩、重复和保留规则。网络传输与查询计算只在实际产生费用的阶段添加一次,避免重复计算同一份副本成本。

采样可以降低常规成功事件的成本,但错误、安全、计费或合规事件只有在相关要求明确允许时才能采样。使用更精简的模式缩小事件体积,通常比先收集敏感字段再依赖采样更安全。

不只测试正常路径,也要测试故障路径

通过受控实验验证管道:

  1. 发送已知请求,确认事件模式、时间戳和关联关系。
  2. 在不允许的请求头和正文中放入测试凭证与类似个人信息的值,确认它们不会到达目标。
  3. 让收集器变慢、不可访问或提供无效证书,测量 API 延迟与网关内存。
  4. 填满已配置的积压队列,确认预期的丢弃行为与告警。
  5. 恢复收集器,测量恢复时间和写入延迟。
  6. 测试保留到期、归档检索、访问批准和审计轨迹。

APISIX 的 prometheus 插件暴露 apisix_batch_process_entries,用于显示日志批次中剩余条目的数量。应将其与目标端投递错误、消息代理积压、索引拒绝、存储饱和度和最新可搜索事件的时间结合;如果投递设计有要求,再加入独立的丢弃信号。

API 网关日志存储检查清单

  • 每个事件是否对应文档明确的运维、安全或合规用途?
  • 字段是否采用允许列表,并在传输前排除敏感值?
  • 传输是否加密,目标身份是否得到验证?
  • 缓冲是否有界,并明确选择丢失或背压策略?
  • 管道能否承受收集器、消息代理、索引和网络故障?
  • 运维数据与审计数据的访问控制是否得到适当分离?
  • 每个存储层是否都有负责人、成本估算、保留规则和删除测试?
  • 是否无需依赖同一条已故障管道,也能观察日志管道健康状态和写入延迟?

常见问题

API 网关应该直接写入 Elasticsearch 吗?

可以,但直接投递会让网关实例与搜索平台的可用性、凭证和模式耦合。当数据量大、有多个消费者或需要故障隔离时,通常更适合使用收集器或消息代理。

API 网关日志应该保留多久?

不存在适合所有场景的统一时长。只在事故、业务、合同、法律或法规用途要求的时间内保留每类数据,并在期限结束时测试删除。

API 访问日志与审计日志相同吗?

不同。访问日志描述请求处理,审计日志则是安全相关操作的证据,通常需要更强的来源、完整性、访问和保留控制。

后续步骤

阅读 API 网关日志与监控最佳实践,将存储管道与指标和追踪连接起来。如果集中管理的 Apache APISIX 部署需要企业级运维与治理,可以进一步了解 API7 Enterprise

获取方案