'Fetching cloudwatch log by aws cli but it gives json output with backslash. But I want JSON output without backslash

I am using AWS cli to fetch cloudwatch log but after fetching the JSON output includes backslash with key and value. But I am checking this log from console then that is absolutely fine( there are without backslash). So now my question is that how to fetch cliudwatch log without this backslash in JSON format? Because jq cannot iterate over backslash in key name.

json current output -

{
    "events": [
        {
            "logStreamName": "xxxxx75914_CloudTrail_ap-south-1",
            "timestamp": 1648750347210,
            "message": "{\"eventVersion\":\"1.08\",\"userIdentity\":{\"type\":\"Root\",\"principalId\":\"xxxxxxxx\",\"arn\":\"arn:aws:iam::xxxxxx:root\",\"accountId\":\"xxxxxxx\",\"accessKeyId\":\"xxxxxxxxx\",\"sessionContext\":{\"attributes\":{\"creationDate\":\"2022-03-31T09:38:58Z\",\"mfaAuthenticated\":\"false\"}}},\"eventTime\":\"2022-03-31T18:07:15Z\",\"eventSource\":\"s3.amazonaws.com\",\"eventName\":\"GetObject\",\"awsRegion\":\"ap-south-1\",\"sourceIPAddress\":\"xx.xx.xx.xx\",\"userAgent\":\"[Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.84 Safari/537.36]\",\"requestParameters\":{\"X-Amz-Date\":\"20220331T180714Z\",\"bucketName\":\"s3trail-bucket\",\"X-Amz-Algorithm\":\"AWS4-HMAC-SHA256\",\"response-content-disposition\":\"attachment\",\"X-Amz-SignedHeaders\":\"host\",\"Host\":\"s3trail-bucket.s3.ap-south-1.amazonaws.com\",\"X-Amz-Expires\":\"300\",\"key\":\"folder2/remove_httpd.yml\"},\"responseElements\":null,\"additionalEventData\":{\"SignatureVersion\":\"SigV4\",\"CipherSuite\":\"ECDHE-RSA-AES128-GCM-SHA256\",\"bytesTransferredIn\":0.0,\"AuthenticationMethod\":\"QueryString\",\"x-amz-id-2\":\"sd35j39Gup5qnNv6xN464A66HdTiPZqc53k+rMN+RO0n97J3jBLTELDzX8fG9M6YgE0VvEMvQm0=\",\"bytesTransferredOut\":147.0},\"requestID\":\"GK9A2F1DF0Q6MBNF\",\"eventID\":\"2fab9c39-7e7c-4f16-ad5b-752ad5839cb7\",\"readOnly\":true,\"resources\":[{\"type\":\"AWS::S3::Object\",\"ARN\":\"arn:aws:s3:::s3trail-bucket/folder2/remove_httpd.yml\"},{\"accountId\":\"201043775914\",\"type\":\"AWS::S3::Bucket\",\"ARN\":\"arn:aws:s3:::s3trail-bucket\"}],\"eventType\":\"AwsApiCall\",\"managementEvent\":false,\"recipientAccountId\":\"201043775914\",\"eventCategory\":\"Data\",\"tlsDetails\":{\"tlsVersion\":\"TLSv1.2\",\"cipherSuite\":\"ECDHE-RSA-AES128-GCM-SHA256\",\"clientProvidedHostHeader\":\"s3trail-bucket.s3.ap-south-1.amazonaws.com\"}}",
            "ingestionTime": 1648xxxxxxxx,
            "eventId": "3676836138911xxxxxxxxxx"
        },
    ],
    "searchedLogStreams": []
}

json desired output - My cloudwatch api is -

aws logs filter-log-events --log-group-name s3_log_2 --log-stream-names Xxxxxxx_CloudTrail_ap-south-1 --start-time 1648188352000 --end-time 1648786144000 --filter-pattern ["eventName"="GetObject"]


Solution 1:[1]

You can use fromjson feature inside your jq command:

jq -r ".events[].message | fromjson"

Here is how I use it with your command:

aws logs filter-log-events --log-group-name aws-logs-cloudtrail-example --log-stream-names 0123456789_CloudTrail_ap-southeast-1 --start-time 1648809754000 --end-time 1648809854000 | jq -r ".events[].message | fromjson"

Solution 2:[2]

You can pass json to jq to unescape it.

Use function walk() can expend nested json ( require jq >= 1.6 )

PASTE_YOUR_AWS_COMMAND_HERE |./jq 'walk(if type == "string" then . as $x | try fromjson catch $x else . end)'

Reference

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Binh Nguyen
Solution 2