2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CloudWatchメトリクスを定期的に取得するログ監視システムの構築

Posted at

CloudWatchのログって3ヶ月くらいで消えるらしいので。。
後々グラフ化とかして活用していきたいのでメモ。

(1) aws-cliの環境を整える。

後々jqコマンドも使用するのでインストールしておく。

$ pip install awscli 

$ aws configure
AWS Access Key ID [NONE]: ********************
AWS Secret Access Key [NONE]: ********************
Default region name [NONE]: ap-northeast-1
Default output format [NONE]: json

$ brew install jq

設定は$ aws configure listで確認できる。

(2) get-metric-statisticsを使ってみる。

まずはローカルで試す。get-metric-statisticsの結果を変数に格納。

RESULT=`aws cloudwatch get-metric-statistics \
--namespace AWS/ApiGateway \
--metric-name Count \
--start-time 2019-07-14T00:00:00Z \
--end-time 2019-07-15T00:00:00Z \
--period 300 \
--statistics Sum`

namespaceには暗黙の了解でAWS/をつける。
取得したいmetric-nameと取得したい期間を指定する。
periodはどの単位でデータを集計するか(ここでは300秒を指定)、集計方法は何か(Sum、Averageなど)。

なお、指定の仕方(特に大文字小文字)を失敗するとデータポイントが空のリストとなって返ってくる。

失敗時
{
    "Label": "count",
    "Datapoints": []
}

(3) 整形してファイルに書き込む。

ファイルを作成し、RESULTを書き込む。

touch tmp_log.txt
touch log.csv

echo $RESULT > tmp_log.txt

cat tmp_log.txt | jq -c -r '.Datapoints[] | [.Timestamp, .Sum, .Unit] | @csv' | sort -t , -k 1  > log.csv

jqはJSONデータを加工・整形するためのツール。
.Datapoints[]→Datapointsに対応する値の配列を外す。
| [.Timestamp, .Sum, .Unit]→フィルタ(パイプ)を用いて再整形。
| @csv→csv形式を指定

jqコマンドのオプション

  • -c(--compact-output):インデントをつけた表示をしない。
  • -r(--raw-output):ダブルクオートを外して表示。

jqの詳細はこの記事を参照した。

なお、get-metric-statisticsで返されるデータはタイムスタンプ順にはなっていないのでソートする必要がある。

sortコマンドのオプション
-t→区切り文字を指定。
-k→何列目の値を元にソートするかの指定。

(4) S3へアップ。

S3の指定のバケットへコピーする。
S3に適当なバケットを用意する。

aws s3 cp ./log.csv s3://test-bucket

(5) ある程度機能するようになったのでEC2に配置してみたい。

$ chmod 777 fuga.sh
$ ssh -i ~/.ssh/hoge_key.pem ec2-user@***.***.***.***
Last login: Tue Jul 30 01:09:31 2019 from kd106180011244.au-net.ne.jp

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
$ scp -i ~/.ssh/hoge_key.pem ~/fuga.sh ec2-user@***.***.***.***:/home/ec2-user/test/
fuga.sh                                  100%  416     2.8KB/s   00:00    

転送するファイルのアクセス権によってはPermdission deniedとなり失敗する。送るファイルと送り先の両方の権限に注意する。なお、間違ってもec2-userの権限を777にしないこと。インスタンスに二度と接続できなくなり死亡する。

なお、ec2においてもaws configureの設定とjqのインストールをしておく必要がある。

$ sudo yum install jq

(6) メトリクスの日時・時刻を自動で反映。ファイル名にも。

TODAY=`date "+%Y%m%d"`
START_TIME=`date -v-1d "+%Y-%m-%dT00:00:00Z"`
END_TIME=`date -v-1d "+%Y-%m-%dT23:59:59Z"`

RESULT=`aws cloudwatch get-metric-statistics --namespace AWS/ApiGateway --metric-name Count --start-time ${START_TIME} --end-time ${END_TIME} --period 300 --statistics Sum`

touch tmp_log_${TODAY}.txt
touch log_${TODAY}.csv

ここで残念な問題が発生。

開発環境のMacはBSD、作成したインスタンスはGNU。。。dateコマンドのオプションが若干違うらしい??(この辺今度勉強しよう)

なので修正。

START_TIME=`date -d "1 days ago" "+%Y-%m-%dT00:00:00Z"`
END_TIME=`date -d "1 days ago" "+%Y-%m-%dT23:59:59Z"`

(7) crontabの設定。

そもそも時刻あってる?

$ date
2019年  7月 31日 水曜日 13:57:27 UTC

やっぱり違った。時刻の設定。→ここを参考に

$ sudo vi /etc/sysconfig/clock
ZONE="Japan"
UTC=true

$ sudo ln -sf /usr/share/zoneinfo/Japan /etc/localtime
$ sudo reboot

これでUTCからJSTになったので、cron設定。テストでは2時に実行で。
なお、対象のfuga.shファイルのPermissionが実行可能であることは確認しておく。

$ cd /etc/cron.d
$ sudo cp /etc/crontab /etc/cron.d/test_cron
$ sudo vi test_cron
test_cron
0 2 * * * ec2-user sh /home/ec2-user/test/fuga.sh

cronの起動

$ sudo service crond restart
$ sudo systemctl status crond.service
● crond.service - Command Scheduler
   Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
   Active: active (running) since 木 2019-08-01 01:44:53 JST; 7s ago
 Main PID: 1234 (crond)
   CGroup: /system.slice/crond.service
           └─1234 /usr/sbin/crond -n

 8月 01 01:44:53 ip-***-**-**-***.ap-northeast-1.compute.internal systemd[1]: Started Command Scheduler.
 8月 01 01:44:53 ip-***-**-**-***.ap-northeast-1.compute.internal systemd[1]: Starting Command Scheduler...
 8月 01 01:44:53 ip-***-**-**-***.ap-northeast-1.compute.internal crond[1234]: (CRON) INFO (RANDOM_DELAY will be scaled with factor 17% if used.)
 8月 01 01:44:53 ip-***-**-**-***.ap-northeast-1.compute.internal crond[1234]: (CRON) INFO (running with inotify support)
 8月 01 01:44:53 ip-***-**-**-***.ap-northeast-1.compute.internal crond[1234]: (CRON) INFO (@reboot jobs will be run at computer's startup.)

S3に正しい日付のファイルができていた。成功。
あとは、cronの実行時刻をJSTで9時に設定しなおせば0時から1日刻みでログを集められそう。(結局9時に設定するならはじめにJSTに時刻を揃えた意味が無いようだけど・・・)

コード全部

fuga.sh
#!/bin/sh

TODAY=`date "+%Y%m%d"`
START_TIME=`date -v-1d "+%Y-%m-%dT00:00:00Z"`
END_TIME=`date -v-1d "+%Y-%m-%dT23:59:59Z"`

echo ${START_TIME}
echo ${END_TIME}

RESULT=`aws cloudwatch get-metric-statistics --namespace AWS/ApiGateway --metric-name Count --start-time ${START_TIME} --end-time ${END_TIME} --period 300 --statistics Sum`

touch tmp_log_${TODAY}.txt
touch log_${TODAY}.csv

echo $RESULT
echo $RESULT > tmp_log_${TODAY}.txt

cat tmp_log_${TODAY}.txt | jq -c -r '.Datapoints[] | [.Timestamp, .Sum, .Unit] | @csv' | sort -t , -k 1  > log_${TODAY}.csv

aws s3 cp ./log_${TODAY}.csv s3://test-bucket

rm tmp_log_${TODAY}.txt
rm log_${TODAY}.csv
2
2
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
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?