Skip to content

Instantly share code, notes, and snippets.

@kflorence
Last active February 16, 2022 18:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kflorence/517dc3d9885f0e2461882468ba7cbfc0 to your computer and use it in GitHub Desktop.
Save kflorence/517dc3d9885f0e2461882468ba7cbfc0 to your computer and use it in GitHub Desktop.
Invokes an AWS Lambda function and displays the logs for the invocation
#!/usr/bin/env bash
set -e -o pipefail
FILENAME=$0
FILENAME=$(basename "$FILENAME")
function usage {
echo "Invokes an AWS Lambda function and displays the logs for the invocation."
echo "usage: $FILENAME --function-name [--help] [--payload] [--wait] [<STDIN>]"
echo " --function-name the Lambda function name or ARN."
echo " --help display this message."
echo " --payload the JSON payload (or file://) to invoke the Lambda with. Use '-' for STDIN."
echo " --wait how long to wait before checking for logs. Defaults to 5s."
}
WAIT="5s"
# Handle arguments.
while [[ "$#" -gt 0 ]]; do
case $1 in
--function-name) FUNCTION_NAME="$2"; shift ;;
--help) usage; exit 0 ;;
--payload) PAYLOAD="$2"; shift ;;
--wait) WAIT="$2"; shift ;;
*) echo "Unknown parameter passed: $1"; exit 1 ;;
esac
shift
done
# Check for STDIN
if [ "$PAYLOAD" == "-" ]; then
PAYLOAD=$(cat | jq)
fi
if [ -z "$PAYLOAD" ]; then
echo "Missing --payload."
exit 1
fi
if [ -z "$FUNCTION_NAME" ]; then
echo "Missing --function-name."
exit 1
fi
# Invoke the Lambda and capture the response.
START_TIME=$(date +%s000)
aws --version
echo "Loading timeout configuration for function '$FUNCTION_NAME'."
TIMEOUT=$(aws lambda get-function-configuration --function-name "$FUNCTION_NAME" --query Timeout --output text)
echo "Invoking Lambda function '$FUNCTION_NAME' with a timeout of $TIMEOUT seconds and payload:"
if [ "${PAYLOAD:0:7}" == "file://" ]; then jq '.' "${PAYLOAD:7}"
else echo "$PAYLOAD" | jq -e '.'
fi
echo "..."
TEMP_FILE=$(mktemp)
aws lambda invoke \
--cli-binary-format raw-in-base64-out \
--cli-read-timeout "$TIMEOUT" \
--function-name "$FUNCTION_NAME" \
--payload "$PAYLOAD" \
"$TEMP_FILE" | jq '.'
echo "---"
jq '.' "$TEMP_FILE"
# On failure, the 'errorMessage' property will be set.
IS_FAILURE=$(jq 'has("errorMessage")' "$TEMP_FILE")
# Get the AWS request ID for the invocation. This value is provided by the "context" object provided to the Lambda
# during invocation.
#
# On error, the 'errorMessage' property is expected to be a JSON string which contains the 'requestId' property.
# On success, the value returned by the Lambda should include the 'requestId' property.
if [ "$IS_FAILURE" = "true" ]; then
REQUEST_ID=$(jq -r '.errorMessage' "$TEMP_FILE" | jq -r '.requestId')
else
REQUEST_ID=$(jq -r '.requestId' "$TEMP_FILE")
fi
rm "$TEMP_FILE"
echo "Waiting ${WAIT} for logs to catch up."
sleep "${WAIT}"
echo "Querying logs for request ID '$REQUEST_ID'."
# Display the logs for the invocation.
aws logs filter-log-events \
--log-group-name "/aws/lambda/$FUNCTION_NAME" \
--start-time "$START_TIME" \
--filter-pattern '"['"$REQUEST_ID"']"' | jq -j '.events[].message'
# Fail the build if the invocation failed.
if [ "$IS_FAILURE" = "true" ]; then
echo "Lambda invocation failed due to error."
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment