Skip to content

CloudWatch Insights Examples

Updated: at 12:12 AM

Table of Contents

Open Table of Contents

Basic Query

fields @timestamp, ip, resourcePath, status, errorMessage
| filter status~= /4\d\d/
| sort @timestamp desc
| limit 80

Filter

Boolean

fields f1, f2, f3 | filter (duration>2000)

And & Or & Not

filter @message ~= 'MIDDLEWARE' and @message not like 'iOS'
filter statusCode in [300,400,500]
filter statusCode not in [200,300]
fields @timestamp, @message
| filter @message like /(?i)error|(?i)exception/

Header Lookups

fields @timestamp, @message, `headers.X-Forwarded-For` as ip, `requestContext.identity.sourceIp` as sourceIP, `headers.User-Agent` as ua, `headers.CloudFront-Viewer-Country` as loc
| filter @message like /httpMethod: 'POST'/ 
| filter @message not like /localhost:3000/
| parse ua /(?<os>(Windows|Mac|Linux|iPhone|Android|iPad))/
| display sourceIP, ip, loc, os, @timestamp, @message
| limit 400

Average

parse @message "user=*, method:*, latency := *" as @user, @method, @latency
| stats avg(@latency) by @method, @user

LogLevel

aws logs filter-log-events
--log-group-name /aws/lambda/directory-service-worker-update-user-product \
--filter-pattern '[timestamp,logId,logLevel=ERROR,msg]' \
--start-time 1604658473982 \
--end-time 1604658533982  # 1 min from start time

Remove Null Records

fields ispresent(`headers.X-User-Id`) as exists
| filter exists != 0

Group By

fields @timestamp, deviceInfo.thingName as thingName, @message, @logStream
| filter @message like 'ERROR'
| sort @timestamp desc
| stats count (*) by thingName

Starts With

filter `headers.X-User-Id` =~ 'ab7'

Contains

filter @message like /ab735336-fad7-4df9-9576-48143cb0d6da/
# OR
filter @message ~= 'ab735336-fad7-4df9-9576-48143cb0d6da'

Exact Match

filter `headers.X-User-Id` = 'ab735336-fad7-4df9-9576-48143cb0d6da'

Finding Text or ERROR

fields @timestamp, `context.userAgent` as `User-Agent`, @message, @logStream
| filter @message like 'ERROR' | sort @timestamp desc

Specific Services

LAMBDA

@timestamp, @logStream, @message, @requestId, @duration, @billedDuration, @type, @maxMemoryUsed, @memorySize

Latency

fields @timestamp, @message, @duration as duration | filter duration > 1000

Process Exited

filter @message like /Process exited/
| stats count() by bin(30m)

Lambda Timeout Count

filter @message like /Task timed out/
| stats count() by bin(30m)

Memory!

filter @type = "REPORT"
| stats max(@memorySize / 1024 / 1024) as provisonedMemoryMB,
    min(@maxMemoryUsed / 1024 / 1024) as smallestMemoryRequestMB,
    avg(@maxMemoryUsed / 1024 / 1024) as avgMemoryUsedMB,
    max(@maxMemoryUsed / 1024 / 1024) as maxMemoryUsedMB,
    provisonedMemoryMB - maxMemoryUsedMB as overProvisionedMB

ROUT53

@timestamp, @logStream, @message, edgeLocation, hostZoneId, protocol, queryName, queryTimestamp, queryType, resolverIp, responseCode, version

Other log types

@timestamp, @ingestionTime, @logStream, @message, @log.

Parse

Extracts data from a log field and creates one or more ephemeral fields

Using this single log line as an example:

25 May 2019 10:24:39,474 [ERROR] {foo=2, bar=data} The error was: DataIntegrityException

level has a value of ERROR, config has a value of {foo=2, bar=data}, and exception has a value of DataIntegrityException.

fields @message
| parse @message "[*] * The error was: *" as level, config, exception

Stats & Report

Latency Report Per Hour

filter @type = "REPORT"
| stats avg(@duration), max(@duration), min(@duration) by bin(60m)

Exception Per Hour

Get a list of the number of exceptions per hour.

filter @message like /Exception/
| stats count(*) as exceptionCount by bin(1h)
| sort exceptionCount desc

Lambda Duration

filter @type = "REPORT"
| stats
    avg(@billedDuration) as Average,
    percentile(@billedDuration, 99) as NinetyNinth,
    percentile(@billedDuration, 95) as NinetyFifth,
    percentile(@billedDuration, 90) as Ninetieth
    by bin(30m)

Duration Report for Timeout

filter @type = "REPORT" |
stats avg(@duration), max(@duration), min(@duration) by bin(5m)
| filter @duration >  5900

Mix

fields @message
| parse @message "* [*] *" as loggingTime, loggingType, loggingMessage
| filter loggingType IN ["ERROR", "INFO"]
| display loggingMessage, loggingType = "ERROR" as isError
If you enjoy the content, please consider supporting work