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-logger、kafka-logger、elasticsearch-logger、file-logger 和 syslog。存在某个连接器并不代表它就是正确架构。
| 模式 | 适用场景 | 主要权衡 |
|---|---|---|
| 标准输出或文件 + 节点 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每日写入字节数 = 每日请求数 × 编码后事件平均大小使用这一写入基线分别估算各阶段。消息代理需要考虑保留窗口、压缩比和副本因子;热搜索存储需要考虑索引大小、分片副本、保留期和索引开销;归档与备份则使用各自的压缩、重复和保留规则。网络传输与查询计算只在实际产生费用的阶段添加一次,避免重复计算同一份副本成本。
采样可以降低常规成功事件的成本,但错误、安全、计费或合规事件只有在相关要求明确允许时才能采样。使用更精简的模式缩小事件体积,通常比先收集敏感字段再依赖采样更安全。
不只测试正常路径,也要测试故障路径
通过受控实验验证管道:
- 发送已知请求,确认事件模式、时间戳和关联关系。
- 在不允许的请求头和正文中放入测试凭证与类似个人信息的值,确认它们不会到达目标。
- 让收集器变慢、不可访问或提供无效证书,测量 API 延迟与网关内存。
- 填满已配置的积压队列,确认预期的丢弃行为与告警。
- 恢复收集器,测量恢复时间和写入延迟。
- 测试保留到期、归档检索、访问批准和审计轨迹。
APISIX 的 prometheus 插件暴露 apisix_batch_process_entries,用于显示日志批次中剩余条目的数量。应将其与目标端投递错误、消息代理积压、索引拒绝、存储饱和度和最新可搜索事件的时间结合;如果投递设计有要求,再加入独立的丢弃信号。
API 网关日志存储检查清单
- 每个事件是否对应文档明确的运维、安全或合规用途?
- 字段是否采用允许列表,并在传输前排除敏感值?
- 传输是否加密,目标身份是否得到验证?
- 缓冲是否有界,并明确选择丢失或背压策略?
- 管道能否承受收集器、消息代理、索引和网络故障?
- 运维数据与审计数据的访问控制是否得到适当分离?
- 每个存储层是否都有负责人、成本估算、保留规则和删除测试?
- 是否无需依赖同一条已故障管道,也能观察日志管道健康状态和写入延迟?
常见问题
API 网关应该直接写入 Elasticsearch 吗?
可以,但直接投递会让网关实例与搜索平台的可用性、凭证和模式耦合。当数据量大、有多个消费者或需要故障隔离时,通常更适合使用收集器或消息代理。
API 网关日志应该保留多久?
不存在适合所有场景的统一时长。只在事故、业务、合同、法律或法规用途要求的时间内保留每类数据,并在期限结束时测试删除。
API 访问日志与审计日志相同吗?
不同。访问日志描述请求处理,审计日志则是安全相关操作的证据,通常需要更强的来源、完整性、访问和保留控制。
后续步骤
阅读 API 网关日志与监控最佳实践,将存储管道与指标和追踪连接起来。如果集中管理的 Apache APISIX 部署需要企业级运维与治理,可以进一步了解 API7 Enterprise。
