【问题标题】:Amazon Cloudwatch Logs Insights with JSON fields带有 JSON 字段的 Amazon Cloudwatch 日志见解
【发布时间】:2018-12-11 13:26:56
【问题描述】:

我正在尝试将 Logs Insights 与其中一个字段中包含 JSON 的数据一起使用,并解析 JSON 字段

当我使用入门代码将数据放入见解中时,我的数据如下所示

fields @timestamp, @message
| sort @timestamp desc
| limit 25

如何轻松提取嵌套 JSON 中的 path 变量以对其执行聚合?通过查看一些文档,我认为@message.path 会起作用,但似乎并非如此。有没有人在 Insights 中成功解释过 JSON 日志

编辑:我的数据样例

#
@timestamp
@message
1
2018-12-19 23:42:52.000
I, [2018-12-19T23:42:52.629855 #23447] INFO -- : [2ce588f1-c27d-4a55-ac05-62a75b39e762] {"method":"GET","path":"/api/v1/professionals/ID","format":"json","controller":"API::V1::Public::ProfessionalsController","action":"show","status":200,"duration":285.27,"view":222.36,"time":"2018-12-19T23:42:52.344+00:00","params":{"include":"user,tags,promotions,company_sector,similar_professionals.tags,similar_professionals.user","format":"json","compress":false,"id":"ID"},"@timestamp":"2018-12-19T23:42:52.629Z","@version":"1","message":"[200] GET /api/v1/professionals/ID (API::V1::Public::ProfessionalsController#show)"}
@logStream  i-05d1d61ab853517a0
@message  I, [2018-12-19T23:42:52.629855 #23447] INFO -- : [2ce588f1-c27d-4a55-ac05-62a75b39e762] {"method":"GET","path":"/api/v1/professionals/ID","format":"json","controller":"API::V1::Public::ProfessionalsController","action":"show","status":200,"duration":285.27,"view":222.36,"time":"2018-12-19T23:42:52.344+00:00","params":{"include":"xxx","format":"json","compress":false,"id":"ID"},"@timestamp":"2018-12-19T23:42:52.629Z","@version":"1","message":"[200] GET /api/v1/professionals/ID (API::V1::Public::ProfessionalsController#show)"}
@timestamp  1545262972000
2
2018-12-19 23:42:16.000
I, [2018-12-19T23:42:16.723472 #851] INFO -- : [ea712503-eb86-4a6e-ab38-ddbcd6c2b4d0] {"method":"GET","path":"/api/v1/heartbeats/new","format":"json","controller":"API::V1::Public::HeartbeatsController","action":"new","status":201,"duration":9.97,"view":3.2,"time":"2018-12-19T23:42:16.712+00:00","params":{"format":"json","compress":false},"@timestamp":"2018-12-19T23:42:16.722Z","@version":"1","message":"[201] GET /api/v1/heartbeats/new (API::V1::Public::HeartbeatsController#new)"}

【问题讨论】:

    标签: json amazon-cloudwatch amazon-cloudwatchlogs


    【解决方案1】:

    CloudWatch Insights Logs 自动发现以下日志类型的字段:

    Lambda 日志

    CloudWatch Logs Insights 自动发现 Lambda 日志中的日志字段,但仅针对每个日志事件中的第一个嵌入式 JSON 片段(注意:强调我的)。如果 Lambda 日志事件包含多个 JSON 片段,您可以使用 parse 命令解析并提取日志字段。有关详细信息,请参阅 JSON 日志中的字段。

    CloudTrail 日志

    fields in JSON logs

    来源: Supported Logs and Discovered Fields

    如果@messageI, [2018-12-11T13:20:27] INFO -- : {"method":"GET"}

    然后您可以像这样选择和过滤字段:

    fields @timestamp, @message, method
    | filter method = "GET"
    | sort @timestamp desc
    

    它也适用于嵌套字段,即params.format = "json"results.0.firstName = "Paul"

    【讨论】:

    • 嗨,这似乎不起作用。我将编辑我的问题以包含使用默认代码可以看到的示例。也许我错过了什么?你的方法是什么jsonresult?它是否记录在某处?我的数据中确实有额外的 ID 内容,就在 -- : 之后
    • 抱歉,jsonresult 是我没有清理的字段。我删除了它。您的示例现在格式不正确。我的数据最后有 JSON 对象,但这似乎并不重要。 JSON 字段是使用自动完成显示还是在右侧的发现部分显示?
    • @pyb 我的 JSON 也没有被自动发现,只有三个默认的 @s 你能发布一个你的 @message 的例子,这样我就可以弄清楚为什么你的解析 JSON 和我的(假设西里尔也是)不是
    • @GusGold 好的。我的@message 只是一个以句子为前缀的有效 JSON:Something something JSON: { "url": "https://red.act.ed", "foo": null, "results": [ { "first_name": "Homer", "last_name": "Simpson" }, { "first_name": "Stack", "last_name": "Overflow" } ], "another_array": [ { "foo": "bar", "barbaz": 0.2 } ]}
    • 我的应用通过安装在 Amazon Linux 2 上的 awslogs 代理同步的日志。
    【解决方案2】:

    您可以使用parse 命令提取字段。

    如果@message

    I, [2018-12-11T13:20:27] INFO -- : {"method":"GET"}
    

    然后你像这样提取字段:

    fields @timestamp, @message
    | parse "I, [*T*] INFO -- : {"method":"*"}" as @date, @time, @method
    | filter method=GET
    | sort @timestamp desc
    | limit 20
    

    文档现在相当简单。我可以通过将通配符* 替换为正则表达式来获得结果,但随后解析失败。

    【讨论】:

    • 所以基本上回到原始字符串解析吧......我必须使用的实际查询是parse 'I, [*T*] * -- : * {*"method":"*",*}' as date, time, severity, id, json_before, method, json_after,因为 * 是贪婪的(你也忘了使用简单的引号来解析表达式)。如果 JSON 键的顺序并不总是相同,它也会完全失败。我希望 AWS 尽快增加对解析 JSON 的支持 =_=
    • @CyrilDuchon-Doris 我尝试将 CloudWatch Logs syntax 与 parse 结合起来,如下所示:| parse "$.method" as @method 但它不起作用。也许这是可能的,但我不知道更好的方法。由于是最新产品(不到一个月),此功能可能会在以后添加。
    【解决方案3】:

    @pyb insights 的基础上,我能够使用parse @message '"path":"*"' as path@message 的任何位置提取路径。

    您可以继续通过管道传递另一个 parse @message '"method":"*"' as method 来获取您的方法,而无需担心订购,因为它是在 @message 上的第二次全局纯文本搜索

    如果您的@message 是:

    I, [2018-12-19T23:42:52.629855 #23447] INFO -- : [2ce588f1-c27d-4a55-ac05-62a75b39e762] {"method":"GET","path":"/api/v1/professionals/ID","format":"json","controller":"API::V1::Public::ProfessionalsController","action":"show","status":200,"duration":285.27,"view":222.36,"time":"2018-12-19T23:42:52.344+00:00","params":{"include":"xxx","format":"json","compress":false,"id":"ID"},"@timestamp":"2018-12-19T23:42:52.629Z","@version":"1","message":"[200] GET /api/v1/professionals/ID (API::V1::Public::ProfessionalsController#show)"}
    

    使用:

    parse @message '"path":"*"' as path | parse @message '"method":"*"' as method
    

    将产生以下字段:path = '/api/v1/professionals/ID'method = 'GET'

    请注意,这仍然是简单的字符串解析,因此,它没有嵌套键的概念,例如 params.format 不会找到 json,但是只要没有另一个 @ 就可以使用 format 987654335@ 字符串在您的@message 中的任何位置。

    另请注意,这是针对 Insights 未在消息中发现您的 JSON 的情况。我相信这就是@pyb 在this answer 中所指的情况。使用以下格式也没有发现我的日志

    info - Request: {"method":"POST","path":"/auth/login/","body":{"login":{"email":"email@example.com","password":"********"}},"uuid":"36d76df2-aec4-4549-8b73-f237e8f14e23","ip":"*.*.*.*"}
    

    【讨论】:

      【解决方案4】:

      另一个parse 借助正则表达式

      假设您的@message 是:

      I, [2018-12-19T23:42:52.629855 #23447] INFO -- : [2ce588f1-c27d-4a55-ac05-62a75b39e762] {"method":"GET","path":"/api/v1/professionals/"}
      

      您可以通过以下方式提取方法

      fields @timestamp, @message
      | parse @message /\"method\":\"(?<method_type>.*?)\"/
      

      【讨论】:

      • 这可行,但您不需要这样做 - 答案“CloudWatch Insights Logs 自动发现以下日志类型的字段:”是更好的方法,因为发现是自动的。
      【解决方案5】:

      parse 命令中的这个正则表达式查询对您有帮助吗?

      filter @message like / \"path\":\"/
      | parse @message /(?<@endpt>((\/[a-zA-Z0-9_{}()-?]+){1,}))/
      

      祝你好运!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-20
        • 2020-07-12
        • 1970-01-01
        • 1970-01-01
        • 2017-11-05
        • 1970-01-01
        • 1970-01-01
        • 2016-11-27
        相关资源
        最近更新 更多