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を配置します
#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と同じディレクトリに配置しておく
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
あとはお好みでアラート設定したり出来ます