Access data in an array

0

I need to access a value within an array provided in Amazon CloudWatch Logs Insights, as an example:

...
    "trace": {
        "timestamp": 1746475850.679,
        "principal": null,
        "session": null,
        "request": {
            "method": "GET",
            "uri": "[ Truncated information ]",
            "headers": {
                "X-Username": [
                    "userAbc"
                ],
                "x-datadog-sampling-priority": [
                    "2"
                ],
                "nmIdSessao": [
                    "[ Truncated information ]"
                ],
                "User-Agent": [
                    "python-requests/2.31.0"
                ],
...

I need to extract all the logs containing the user “userAbc”, present in trace.request.headers.X-Username.

Because it uses a special character (hyphen in X-Username), when I put it in single or double quotes, I get error messages (invalid token).

I used the two syntaxes below, without success.

fields @timestamp, @message, @logStream, @log
| filter trace.request.headers.X-Username = "userAbc"
| sort @timestamp desc
| limit 1000

and

fields @timestamp, @message, @logStream, @log
| filter trace.request.headers."X-Username"[0] = "userAbc"
| sort @timestamp desc
| limit 1000

How can I access this information so that all the logs (log groups) are used during the query?

2 Answers
0

You can use the following query to extract and filter the logs containing "userAbc" from the X-Username header:

parse @message "{'trace': *}" as trace
| filter ispresent(trace.request.headers."X-Username"[0])
    and trace.request.headers."X-Username"[0] = "userAbc"
| fields @timestamp, @message, @logStream, @log
| sort @timestamp desc
| limit 1000

This query does the following:

  1. It uses the parse command to extract the JSON content from the @message field, creating a new field called "trace".
  2. The filter command checks if the X-Username field exists and if its first (and likely only) element matches "userAbc".
  3. We then select the fields we want to display, sort by timestamp in descending order, and limit the results to 1000.

This approach should work even with the hyphen in "X-Username" because we're using dot notation within quotes to access the field.

If you're dealing with flattened JSON where the field names might include dots, you can try using the following alternative syntax:

parse @message "{'trace': *}" as trace
| filter ispresent(get_field(trace, "request.headers.X-Username[0]"))
    and get_field(trace, "request.headers.X-Username[0]") = "userAbc"
| fields @timestamp, @message, @logStream, @log
| sort @timestamp desc
| limit 1000

This uses the get_field() function to access nested fields, which can be helpful when dealing with complex JSON structures or field names with special characters.

Remember that the exact structure of your logs may vary, so you might need to adjust the JSON path slightly based on your specific log format.

Sources
parse - Amazon CloudWatch Logs

profile picture
answered 13 days ago
0

Hello.

Have you tried enclosing it in backticks as described in the documentation below?
https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax-Guidelines.html

If a field contains non-alphanumeric characters other than the @ symbol or the period (.), you must surround the field with backtick characters (). For example, the log field foo-bar must be enclosed in backticks (foo-bar`) because it contains a non-alphanumeric character, the hyphen (-).

I don't have the same logs as you so I can't test your query, but if it's a special character you might be able to escape it with a backslash.
https://stackoverflow.com/questions/58464092/handling-single-quote-in-aws-cloudwatch-logs-insights/58473817

fields @timestamp, @message, @logStream, @log
| filter trace.request.headers.X\-Username = "userAbc"
| sort @timestamp desc
| limit 1000
profile picture
EXPERT
answered 13 days ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions