2
1

More than 1 year has passed since last update.

Cloudwatch logs insight のクエリ結果でアラーム設定する

Posted at

Cloudwatch logs insightは、クエリ的にログ検索ができるが、検索結果をそのままメトリクス化して監視やアラーム設定することができない。同じくCloudwatchのロググループにメトリクスフィルタを設定することでメトリクス化できるが、Cloudwatch logs insightほど複雑なフィルタ条件は設定できない。

前提条件

Cloudwatchを使ったログ収集をしていること
AWS CLIが実行できる環境があること
jqが実行できる環境があること

Cloudwatch logs insightの結果をメトリクス化する

一定時間毎にCloudwatch logs insightにクエリした結果を、メトリクス化する。
shell scriptで、AWS CLIを使ってCloudwatch logs insightの情報を取得し、さらにCloudwatchのメトリクス として設定します。

AWS CLIを使ったscriptの準備

AWS CLIを使ってCloudwatch logs insightの情報を取得し、ヒット件数をCloudwatchのメトリクス として設定します。AWS CLIが実行できる環境にshell scriptを配置します

insight_to_metrics.sh
#CLI environment 各自の環境に合わせて設定してください
PROFILE=XXXXXXXX #AWS PROFILE名を設定
AWS_CLI=/usr/bin/XXXXXXXXX #AWS CLIのパスを設定
JQ=/XXX/XXX/jq # jqのパスを設定
C_PASS=/home/XXXXXX #本スクリプトファイルのディレクトリを設定

#Cloudwatch insight
#query time
STARTTIME=`date --date '-30 minute' +%s`
ENDTIME=`date +%s`
#query log name
LOG_GROUP_NAME="XXXXXXXXXX" #クエリ対象のロググループを指定

#Cloudwatch metrics
NAME_SPACE="CWinsight" #メトリクスのNAME SPACEを指定
METRIC_NAME="recordsMatched_COUNT" #メトリクス名を指定

#tmp files
QUERY_FILE=$C_PASS/query.txt
TMP_FILE=$C_PASS/tmp_query_id.txt

#start query
while read line
do
   QUERY=$line
   echo $LOG_GROUP_NAME $QUERY
   QUERY_ID=`$AWS_CLI logs start-query \
   --log-group-name $LOG_GROUP_NAME \
   --start-time $STARTTIME \
   --end-time $ENDTIME \
   --output text \
   --query-string "$QUERY"
   `
   echo $QUERY_ID >> $TMP_FILE
   DIMENSHON=`echo $QUERY | awk '{print substr($0, index($0, "#")+1)}'`
   echo $DIMENSHON >> $TMP_FILE
done < $QUERY_FILE

#wait for query finish
sleep 20s #クエリ時間によって調整すること

#output result
while read line
do
   QUERY_ID=$line
   RESULT=`$AWS_CLI logs get-query-results --query-id $QUERY_ID --output json`
   STATUS=`echo $RESULT | $JQ '.status'`
   # check query status
   if [ $STATUS != \"Complete\" ] ; then
      echo "[ERROR] exit Script" $QUERY_ID $STATUS
      rm -f $TMP_FILE
      exit 1
   fi
   COUNT=`echo $RESULT | $JQ '.statistics.recordsMatched'`
   read line
   echo $line " / query status = "$STATUS " matched count = "$COUNT
   # put Metric data of CloudWatch
   aws  cloudwatch put-metric-data --metric-name $METRIC_NAME --namespace $NAME_SPACE --unit Count --value $COUNT --dimensions insight_script=$line
done < $TMP_FILE

#END script
rm -f $TMP_FILE

query条件の設定

query条件は、変更しやすいように別ファイルで記載、クエリの表記方法はCloudwatch logs insightをGUIで使う時と同じ
shell scriptと同じディレクトリに配置しておく

query.txt
stats count(@message) | filter @message like "hoge" | filter @message not like "fuga" #hogefuga_count
stats count(@message) | filter @message like "peke" | filter @message not like "poko" #pekepoko_count

実行

cronで定期実行するようにします
上記の例だと、過去30分のログを対象にqueryしているため、cronも30分毎に設定します
間隔は要件に合わせて設定してください

15,45 * * * * /home/XXXXXX/insight_to_metrics.sh

注意点

クエリ対象のログ量が大きい場合、コスト(と実行時間)が増えるので、コストに見合うか判断して利用しましょう
参考 AWS料金

結果

CloudwatchのCustom namespacesにメトリクスとして値が入っていればOK
あとはお好みでアラート設定したり出来ます
スクリーンショット 2022-02-24 15.47.20.png

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1