Skip to content

Instantly share code, notes, and snippets.

@giehlman
Last active July 18, 2019 19:34
Show Gist options
  • Save giehlman/1e1989cff4ec7c7bc4edf8ef519c18ec to your computer and use it in GitHub Desktop.
Save giehlman/1e1989cff4ec7c7bc4edf8ef519c18ec to your computer and use it in GitHub Desktop.
Creates cloudwatch log filter, metric and alarm
#!/usr/bin/env bash
#title : setup-cloudwatch.sh
#description : Creates cloudwatch log filter, metric and alarm
#author : Christian-André Giehl <christian@emailbrief.de>
#date : 20190718
#version : 1.1
#usage : sh setup-cloudwatch.sh <keyword-list> <lambda-function-name>
#==============================================================================
# Exits in case the supplied state is != 0. State is typically supplied via $?
exitOnError() {
state=$1
msg=$2
if [ $state -ne 0 ]; then
echo "!!! ${msg}"
echo "### Exiting."
exit $state
fi
}
confirmPrompt() {
if [ ! -z "${HEADLESS}" ]; then
echo "Headless! Auto-confirmed!"
return 0
fi
read -p "-----> DO YOU WANT TO ${1}? [Yy]es " -n 1 -r </dev/tty
if [[ $REPLY =~ ^[Yy]$ ]]
then
return 0
fi
return 1
}
escapePattern() {
echo ${1}|sed 's/[^a-zA-Z0-9]/_/g'|cut -c1-20
}
printUsage() {
echo "!!! Please specify exactly 2 args! !!!"
echo " Usage: sh setup-cloudwatch.sh <keyword-list> <lambda-function-name>"
echo " with:"
echo " <keyword-list> a text-only file with one search string per line (don't forget the newline at EOF!)"
echo " <lambda-function-name> name of your lambda function to be used as metric/filter naming"
}
if [ $# -ne 2 ]; then
printUsage
exit 1
fi
#
# 0. Input vars
#
command -v aws
exitOnError $? "AWS CLI not found or not accessible!"
INPUT_FILE=$1
LAMBDA_NAME=$2
LOG_GROUP_NAME=/aws/lambda/${LAMBDA_NAME}
METRIC_NAMESPACE=EbMetrics
while read p; do
# Skip empty lines
if [ -z "${p}" ]; then
echo "Skipping '${p}' because it is empty!"
continue
fi
# Skip commented lines
if [[ "${p}" == \#* ]]; then
echo "Skipping '${p}' because it is commented out!"
continue
fi
FILTER_PATTERN=${p}
FILTER_PATTERN_ESCAPED=$(escapePattern "${FILTER_PATTERN}")
METRIC_NAME=${LAMBDA_NAME}-${FILTER_PATTERN_ESCAPED}-metric
FILTER_NAME=${LAMBDA_NAME}-${FILTER_PATTERN_ESCAPED}-filter
ALARM_NAME=${LAMBDA_NAME}-${FILTER_PATTERN_ESCAPED}-alarm
#
# 1. Log current situation
#
cmd="aws logs describe-metric-filters \
--log-group-name ${LOG_GROUP_NAME}"
# Storing the cmd and using eval here may look complicated but it simplifies calling the cmd more than once
eval "${cmd}"
TRY_FILTER=$(eval "${cmd}"|grep -c "\"filterName\": \"${FILTER_NAME}\"")
if [ ${TRY_FILTER} -eq 1 ]; then
echo "Filter '${FILTER_NAME}' already exists! Skipping..."
continue
fi
aws cloudwatch describe-alarms-for-metric \
--metric-name ${METRIC_NAME} \
--namespace ${METRIC_NAMESPACE}
#
# 2. Create metric filter
#
confirmPrompt "create metric filter '${FILTER_NAME}'"
exitOnError $? "!!! ABORTED !!!"
aws logs put-metric-filter \
--log-group-name ${LOG_GROUP_NAME} \
--filter-name ${FILTER_NAME} \
--filter-pattern "${FILTER_PATTERN}" \
--metric-transformations \
metricName=${METRIC_NAME},metricNamespace=${METRIC_NAMESPACE},metricValue=1,defaultValue=0
#
# 3. Create alarm
#
confirmPrompt "create alarm '${ALARM_NAME}'"
exitOnError $? "!!! ABORTED !!!"
aws cloudwatch put-metric-alarm \
--alarm-name ${ALARM_NAME} \
--metric-name ${METRIC_NAME} \
--namespace ${METRIC_NAMESPACE} \
--alarm-description "TODO" \
--actions-enabled \
--alarm-actions "arn:aws:sns:eu-central-1:216518302536:cwAlarmList" \
--statistic "Sum" \
--period 900 \
--evaluation-periods 1 \
--threshold 0 \
--comparison-operator "GreaterThanThreshold" \
--treat-missing-data "notBreaching"
# --generate-cli-skeleton
done < ${INPUT_FILE}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment