Created
April 26, 2026 14:20
-
-
Save AstroTom/2266393e40b74bae9e6350013cfa9b24 to your computer and use it in GitHub Desktop.
report the top 10 most expensive lambda calls for a function (based on log group) similar to AWS console under Monitor tab
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # | |
| # Show top 10 most expensive Lambda invocations (GB-seconds) | |
| # for log group: Instance-Scheduler-default-scheduling-logs | |
| # | |
| # Requirements: | |
| # - AWS CLI v2 configured with permissions for CloudWatch Logs | |
| # - jq installed | |
| # | |
| # Usage: | |
| # ./top_lambda_gb_seconds.sh | |
| set -euo pipefail | |
| # | |
| # Update these variables | |
| # | |
| LOG_GROUP="Instance-Scheduler-default-scheduling-logs" # usually "/aws/lambda/FUNC_NAME" | |
| REGION="${AWS_REGION:-eu-west-1}" | |
| PROFILE_OPT="${AWS_PROFILE:+--profile $AWS_PROFILE}" | |
| LOOKBACK_HOURS="${1:-24}" | |
| # | |
| # End variables | |
| # | |
| # Time range for the query | |
| START_TIME="$(date -d "${LOOKBACK_HOURS} hours ago" +%s)" | |
| END_TIME="$(date +%s)" | |
| # CloudWatch Logs Insights query: | |
| # - Use Lambda REPORT lines (@type="REPORT") | |
| # - Compute GB-seconds = billedDuration(ms) * memory(MB) / 1024 / 1000 | |
| # - Aggregate by requestId | |
| read -r -d '' QUERY << 'EOF' || true | |
| filter @type = "REPORT" | |
| | stats | |
| max(@timestamp) as timestamp, | |
| max(@billedDuration) as billed_ms, | |
| max(@memorySize) as memory_mb, | |
| max(@maxMemoryUsed) as max_memory_used_mb, | |
| max(@billedDuration * @memorySize) / 1024 / 1000 as gb_seconds | |
| by @requestId | |
| | sort gb_seconds desc | |
| | limit 10 | |
| EOF | |
| echo "Running Logs Insights query on log group '${LOG_GROUP}' for the last ${LOOKBACK_HOURS} hours in region ${REGION}..." 1>&2 | |
| # Start the query | |
| QUERY_ID=$( | |
| aws logs start-query \ | |
| --log-group-name "${LOG_GROUP}" \ | |
| --start-time "${START_TIME}" \ | |
| --end-time "${END_TIME}" \ | |
| --query-string "${QUERY}" \ | |
| --region "${REGION}" \ | |
| ${PROFILE_OPT:-} \ | |
| --output text \ | |
| --query 'queryId' | |
| ) | |
| # Poll until complete | |
| STATUS="Running" | |
| while [[ "${STATUS}" == "Running" || "${STATUS}" == "Scheduled" ]]; do | |
| sleep 2 | |
| STATUS=$( | |
| aws logs get-query-results \ | |
| --query-id "${QUERY_ID}" \ | |
| --region "${REGION}" \ | |
| ${PROFILE_OPT:-} \ | |
| --output text \ | |
| --query 'status' | |
| ) | |
| done | |
| if [[ "${STATUS}" != "Complete" ]]; then | |
| echo "Query failed with status: ${STATUS}" 1>&2 | |
| exit 1 | |
| fi | |
| # Fetch results and format similar to the Lambda console "Most expensive invocations in GB-seconds" | |
| RESULTS_JSON=$( | |
| aws logs get-query-results \ | |
| --query-id "${QUERY_ID}" \ | |
| --region "${REGION}" \ | |
| ${PROFILE_OPT:-} \ | |
| --output json | |
| ) | |
| echo -e "timestamp\trequestId\tbilled_ms\tmemory_mb\tmaxMemoryUsedMB\tgb_seconds" | |
| echo "${RESULTS_JSON}" | jq -r ' | |
| .results[] | |
| | (map({( .field ): .value}) | add) as $r | |
| | "\($r.timestamp)\t\($r."@requestId")\t\($r.billed_ms)\t\($r.memory_mb)\t\($r.max_memory_used_mb)\t\($r.gb_seconds)" | |
| ' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment