ログについては、ひとまずCloudWatch logsに投げ込む運用にしています(注1
このCloudWatch logsを高速に検索できるインサイトをCLIから使う紹介です( WEBでの使い方については[ CloudWatch ]->[ インサイト ]でいろいろ試していただきたいです ) 障害調査の場合、どのみちgrepすることになるのでCLIでの手順も残しておきます。
ログ取得
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatchLogs/latest/APIReference/API_StartQuery.html
--start-time 開始時刻をunixtime
--end-time 終了時刻をunixtime
--query-string 参考 https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html
クエリ(フィルタリング)について
検索する際の方法
limit 10 とか。
このためにインサイトを使っていると言えますが正規表現
| filter @message like /access_token=/
クエリ例
参考: サンプルクエリ - Amazon CloudWatch Logs
nginxのログのみを表示する
| filter @logStream LIKE /nginx/
ロードバランサからのヘルスチェックを除外する
| filter @message NOT LIKE /ua:ELB-HealthChecker/
ステータスコードが500番台のもののみを表示する
| filter @message LIKE /status:5\d+/
ログをパースして変数にセットする
| parse @message "time:*host:*forwardedfor:*req:*status:*size:*referer:*ua:*reqtime:*cache:*runtime:*vhost:*userid:*" as time, host, forwardedfor, req, status, size, referer, ua, reqtime, cache, runtime, vhost, userid
クエリ実行( ログ検索は時間がかかるため、後で別途getする必要があります)
bash環境(dateコマンドはbrewのcoreutilsを使用)
クエリ実行
aws logs start-query --log-group-name NginxApiAccessLog --start-time $(date +%s --date "2019-02-01 00:00") --end-time $(date +%s) --query-string 'fields @timestamp, @message | sort @timestamp desc | limit 10000'
を実行すると
クエリIDが帰る。
{
"queryId": "294ef35e-f602-46f9-b63c-a3abc12135a1"
}
結果取得
–query-id に上記で得たクエリIDを渡します。
aws logs get-query-results --query-id '63c8c0bc-7c17-4d92-87b0-f4d71d6c85b5' | jq '.results[][] | select(.field == "@message") | .value'
「WebUIでクエリIDを取得したい」
クエリの試行錯誤はWebUIの方が楽だったり、チェックしやすかったので「WebUIでクエリを組み立て実行」「結果はCLIから取得、手元でgrep」の方が早く作業できる場合もあります。 この場合ですが、2019/02時点では WebUIではクエリIDを確認する方法がありませんでした。
aws logs describe-queries
で、確認できます。
WebUIでの検索
- 右上のAWSアカウントをクリック、ロールを必要に応じて変更
- https://ap-northeast-1.console.aws.amazon.com/cloudwatch/ を開く
- 左のメニューから
インサイトを選択 - ロググループをプルダウンメニューから選択( ここでは
/ecs/env25を選択しています ) - フィルタルールを追加
例えば php-fpmのエラーログを探したい 場合では
fields @timestamp, @message
| sort @timestamp desc
| filter @logStream LIKE /php-fpm/
| filter @message NOT LIKE /200$/
| limit 100
料金
https://aws.amazon.com/jp/cloudwatch/pricing/
1 GB あたり 0.0076 USD です。 ざっくりとで構いませんので期間の指定で絞ってください。
ただ各自の時給と比較すると安くなると思います(CloudWatch logsをエキスポートしてMacで検索するのは、それなりに時間がかかる)
注1) ほかの選択肢、例えばfluentdエージェントを運用してs3に転送する方法も行っていました ( 導入自体は簡単にできます https://dev.classmethod.jp/cloud/aws/fluentd-s3/ )
が、意外とアクセスが増える瞬間、あるいはfluentdのルールを複雑にするとfluetndの負荷が気になってきます。 fluentエージェントのCPU負荷を下げるためには別途、フィルタリング用のfluentdを別インスタンスで立てる必要になり…という形で、 関連する運ソースの増大が見えてきため、AWS標準のCloudWatch logsに転送するようにしています。 ( ただインスタンス数が増大するなどした場合は、この辺の共有で使う運用リソースのコストは、全体に均されていきます。 CloudWatch logsと人件費を比較しfluentd導入を再検討するのもありな状況もあります )