How to send message to CloudWatch when script has an error

Azole (小賴)
2 min readApr 9, 2019

--

Getting ready

  • trapping signals

Signals are a limited form of inter-process communication (IPC), typically used in Unix, Unix-like, and other POSIX-compliant operating systems. A signal is an asynchronous notification sent to a process or to a specific thread within the same process in order to notify it of an event that occurred.

You can list all the signals by kill -l or trap -l command and it will print the signal number and name.

For example, when you press Ctrl+c , the process will receive 2)SIGINT signal.

We can trap these signals and assign the handler to it.

trap commands signals 

For example:

#!/bin/bashtrap 'echo "Receive SIGINT"' INTwhile true;
do
echo "Process ID: $$"
sleep 1
done;

Run this script and press Ctrl+C , it will showReceive SIGINT in the terminal.

When a script has an error, it will receive SIGERR and we can trap it to send alarm to CloudWatch.

  • Sending message to CloudWatch

We can send message to CloudWatch by aws cli put-log-events command.

aws logs put-log-events 
--log-group-name logGroupName
--log-stream-name logStreamName
--log-events timestamp=$timeStamp,message="message"
--sequence-token $UploadSequenceToken

Before we do this, we have to set a role to ec2 and this role has the put log permission.

Please refer to the AWS document for more details.

How to do it

main.sh

#!/bin/basherr_report() {
./cwlog.sh "Error at line $1"
}
trap 'err_report $LINENO' ERR# for example
echo foo | grep bar # This is line number 10

cwlog.sh

#!/bin/bashEC2_AVAIL_ZONE=`curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone`
EC2_REGION="`echo \"$EC2_AVAIL_ZONE\" | sed 's/[a-z]$//'`"
export AWS_DEFAULT_REGION=$EC2_REGIONMess="${1:-'Execute Error!'}"
LogGroupName="SystemOperations"
LogStreamName="test"
UploadSequenceToken=$(aws logs describe-log-streams --log-group-name "$LogGroupName" --query 'logStreams[?logStreamName==`'$LogStreamName'`].[uploadSequenceToken]' --output text)echo $UploadSequenceTokenTimeStamp=`date "+%s%N" --utc`
TimeStamp=`expr $TimeStamp / 1000000`
if [ "$UploadSequenceToken" != "None" ]
then
aws logs put-log-events --log-group-name "$LogGroupName" --log-stream-name "$LogStreamName" --log-events timestamp=$TimeStamp,message="$Mess" --sequence-token $UploadSequenceToken
else
# An upload in a newly created log stream does not require a sequence token.
aws logs put-log-events --log-group-name "$LogGroupName" --log-stream-name "$LogStreamName" --log-events timestamp=$TimeStamp,message="$Mess"
fi

Run main.sh and the message Error at line 10 will send to CloudWatch.

References

--

--

Azole (小賴)
Azole (小賴)

Written by Azole (小賴)

As a passionate software engineer and dedicated technical instructor, I have a particular fondness for container technologies and AWS.

No responses yet