如何美化AWS日志流JSON?解决sed+jq命令报错问题
美化AWS Lambda日志流的正确方法
问题描述
原始AWS Lambda日志格式:
2022-09-07T17:14:35.987000+00:00 2022/09/07/[$LATEST]58f517bs4ebcsae033sd953bs734224 {"cold_start":true,"function_memory_size":512,"function_request_id":"a2cfdd5d-4b0b-4cfa-97c2-4af9ba6a1056","level":"ERROR","message":"Unexpected","sampling_rate":1,"timestamp":"2022-09-07T17:14:35.987Z","xray_trace_id":"1-6318d178-0e96c13a1399a74b4f353edd","extra":"{\"error\":\"AccessDeniedException: User: arn:aws:sts::\",\"stack\":\"AccessDeniedException: User: arn:aws:sts::\"}"}
期望格式化后的格式:
2022-09-07T17:14:35.987000+00:00 2022/09/07/[$LATEST]58f51004277b4ebcae033d953b734224 { "cold_start": true, "function_memory_size": 512, "function_request_id": "a2cfdd5d-4b0b-4cfa-97c2-4af9ba6a1056", "level": "ERROR", "message": "Unexpected", "sampling_rate": 1, "timestamp": "2022-09-07T17:14:35.987Z", "xray_trace_id": "1-6318d178-0e96c13a1399a74b4f353edd", "extra": '{"error":"AccessDeniedException: User: arn:aws:sts::","stack":"AccessDeniedException: User: arn:aws:sts::"}', }
使用以下命令时触发错误:
aws logs tail /aws/lambda/lambda-name | sed -u -e "s/\({.*}\)/$(echo \'\\1\' | jq)/"
错误信息:
parse error: Invalid numeric literal at line 2, column 0
错误原因
你使用的sed命令中,$(echo \'\\1\' | jq)会在sed启动前被Shell提前解析执行,而非针对每行的匹配结果动态处理。这导致jq接收到的不是每行的JSON内容,而是无效的字符串,从而触发解析错误。
正确解决方案
使用awk结合jq实现逐行处理,分割日志头与JSON部分,格式化JSON的同时将extra字段转为单引号包裹的字符串:
aws logs tail /aws/lambda/lambda-name | awk '{ n = index($0, "{"); if (n > 0) { # 分割日志头和JSON内容 header = substr($0, 1, n-1); json_str = substr($0, n); # 调用jq格式化JSON,并用@sh将extra字段转为单引号包裹的字符串 cmd = "echo \"" json_str "\" | jq \'.extra |= @sh\'"; cmd | getline formatted_json; close(cmd); print header formatted_json; } else { # 非JSON格式的日志直接输出 print $0; } }'
命令说明
aws logs tail:实时拉取指定Lambda的日志流awk:index($0, "{"):定位每行中JSON内容的起始位置substr:将日志分割为前缀(时间、版本信息)和JSON字符串两部分getline:调用jq处理JSON内容
jq:.extra |= @sh:将extra字段的嵌套JSON转为单引号包裹的字符串,自动处理内部引号转义,同时格式化整个JSON结构
内容的提问来源于stack exchange,提问作者rxyz
相关产品推荐
相关产品推荐

