使用 NDJSON 端点发送日志(ND-JSON 日志) - Amazon CloudWatch 日志

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用 NDJSON 端点发送日志(ND-JSON 日志)

ND-JSON 日志端点 (/ingest/bulk) 接受 NDJSON(换行符分隔 JSON)格式的日志。每行只包含一个 JSON 值,由换行符分隔。

如果您使用的是不记名令牌身份验证,请先完成中的设置步骤,设置不记名令牌身份验证然后再继续。

请求格式

每行发送一个 JSON 值,以 \n (LF) 或 \r\n (CRLF) 分隔。空行会被静默忽略。

{"timestamp":1771007942000,"message":"event one","level":"INFO"} {"timestamp":1771007943000,"message":"event two","level":"ERROR"} {"timestamp":1771007944000,"message":"event three","level":"DEBUG"}

application/jsonapplication/x-ndjson都被接受为内容类型。

接受的 JSON 值类型

根据 NDJSON 规范 (RFC 8259),每行都接受任何有效的 JSON 值。

JSON 对象(最常见):

{"timestamp":1771007942000,"message":"User logged in","service":"auth"} {"timestamp":1771007943000,"error":"Connection timeout","service":"api"}

JSON 数组(扁平化为单个事件):

[{"timestamp":1000,"message":"a"},{"timestamp":2000,"message":"b"}]

此单行生成 2 个事件。每个数组元素都变成一个单独的日志事件。

原始值:

"a plain string log message" 42 true null

每个基元都变成自己的事件,并带有服务器的当前时间戳。

混合类型:

{"timestamp":1771007942000,"message":"structured event"} "unstructured string message" 42 {"timestamp":1771007943000,"error":"something failed"}

所有 4 行都被接受为有效事件。

行内容 行为
JSON 对象 已接受,如果存在则提取时间戳
JSON 数组 扁平化 — 每个元素都变成一个单独的事件
空数组 [] 已接受,生成 0 个事件
json 字符串 已接受为活动消息
JSON 编号 已接受为活动消息
json 布尔值 已接受为活动消息
JSON 空 已接受为活动消息
JSON 无效 已跳过(已计数,处理仍在继续)
空行 已忽略(未计为已跳过)

时间戳字段

"timestamp"字段以纪元毫秒(不是秒)为单位。

格式 示例 解释为
数字(毫秒) "timestamp":1771007942000 1771007942000 ms
缺失 (没有时间戳字段) 服务器当前时间
非数字 "timestamp":"invalid" 服务器当前时间
非对象线 "hello", 42, true 服务器当前时间

无效的行

无效 JSON 的行会被静默跳过并计数。下一行继续处理。

{"message":"valid event"} this is not valid json {"message":"another valid event"}

结果:摄取 2 个事件,跳过 1 个事件。返回 HTTP 200

如果所有行都无效,则返回HTTP 400"All events were invalid"

示例请求

curl -X POST "https://logs.<region>.amazonaws.com/ingest/bulk?logGroup=MyLogGroup&logStream=MyStream" \ -H "Authorization: Bearer ACWL<token>" \ -H "Content-Type: application/x-ndjson" \ -d '{"timestamp":1771007942000,"message":"User logged in","level":"INFO"} {"timestamp":1771007943000,"message":"Query took 42ms","level":"DEBUG"} {"timestamp":1771007944000,"error":"Connection refused","level":"ERROR"}'

响应

成功(接受所有活动):

HTTP 200 OK {}

部分成功(某些事件被拒绝):

{ "partialSuccess": { "rejectedLogRecords": 5, "errorMessage": "{\"tooOldLogEventCount\": 3, \"tooNewLogEventCount\": 1, \"expiredLogEventCount\": 1}" } }

rejectedLogRecords字段是被拒绝的事件的总数。该errorMessage字段包含按拒绝原因划分的 JSON 编码细分:

  • tooOldLogEventCount— 时间戳早于保留期的事件

  • tooNewLogEventCount— 将来时间戳过远的事件

  • expiredLogEventCount— 在处理过程中过期的事件

最佳实践

对事件进行批处理

为了提高性能和效率:

  • 尽可能在单个请求中批量处理多个事件

  • 建议的批处理大小:每个请求 10—100 个事件

  • 最大请求大小:1 MB

错误处理

在应用程序中实现正确的错误处理。常见的 HTTP 状态码:

  • 200 OK— 成功提取日志

  • 400 Bad Request— 请求格式或参数无效

  • 401 Unauthorized— 不记名令牌无效或已过期

  • 403 Forbidden— 权限不足

  • 404 Not Found— 日志组或直播不存在

  • 429 Too Many Requests— 超出速率限制

  • 500 Internal Server Error— 服务错误(使用指数退避重试)

限制

  • 最大事件大小:每个事件 256 KB

  • 最大请求大小:1 MB

  • 每个请求的最大事件数:10,000

  • 日志组名称必须遵循 CloudWatch 日志命名约定

  • 如果使用不记名令牌身份验证,则必须在日志组上启用持有者令牌身份验证。