読者です 読者をやめる 読者になる 読者になる

UZABASE Tech Blog

株式会社ユーザベースの技術チームブログです。 主に週次の持ち回りLTやセミナー・イベント情報について書きます。

AWS Cloudwatch LogsをNewsPicksで試してみた話

こんにちは、NewsPicks開発・運用を担当している木下です。
今回はAWS CloudWatch Logsを利用した運用周りの改善について社内LTした内容をベースにブログにまとめました!

NewsPicksはインフラを完全にAWS上で運用しています。

AWS 導入事例: 株式会社ユーザベース | アマゾン ウェブ サービス(AWS 日本語)

監視については、APIから発生したエラーはAmazon SESを使用してメールにて通知、リソース監視はCloudWatchを利用しています。
CloudWatchは任意のメトリクス(計測値)をアップロードし、それに対して閾値を設定し、AmazonSNSを利用してエラー通知をしたり、AutoScalingを利用してインスタンスを立ち上げたりといったアクションが取れます。
AWSを利用すると、標準でEC2インスタンスのCPU使用率やネットワークトラフィック、SQSのキューサイズ、などなど必要最低限のメトリクスが自動でアップロードされます。 CloudWatchはデフォルトで提供されているメトリクスの監視だけでなく、スクリプトを作成してカスタムメトリクスをアップロードすることもできます。
NewsPicksでは、ディスク使用率、メモリ使用率、サーバーサイドがJavaを使用しているためVMの情報などをCloudWatchにアップロードし、適宜アラームを設定して監視を行っています。

CloudWatchはAWSから標準で提供されているメトリクスのようなリソース監視には向いています。
ただし、システム監視は定期的に発生するリソース監視だけでは不十分です。
例えば不定期に発生するイベントの監視をするにはCloudWatchだけで提供される機能では難しく、別のログ監視のシステムを利用するのが一般的かと思います。
CloudWatchが提供しているアラーム機能は便利なため、カスタムメトリクスのアップロードスクリプトを工夫していたりもするかもしれません。

そこで、昨年サービスインし、12月からは東京リージョンでも利用可能となったAWS CloudWatch Logsを試してみました。

インストール

既存サーバーへのインストールは、下記のpythonスクリプト実行で一発完了でした。

wget https://s3.amazonaws.com/aws-cloudwatch/downloads/latest/awslogs-agent-setup.py
sudo python ./awslogs-agent-setup.py --region north-east-1

このスクリプトで、インストール、デーモン化、対話式でログアップロードの設定までできます。
chkconfigで起動時設定に入れれば、インスタンスの起動時からログがアップロードされる設定が動きます。

設定ファイル情報

対話式で設定した内容は/var/awslogs/etc/awslogs.confに格納されます。

[/var/log/nginx/access.log]
datetime_format = %Y-%m-%d %H:%M:%S
file = /var/log/nginx/access.log
buffer_duration = 5000
log_stream_name = {hostname}
initial_position = start_of_file
log_group_name = access_log

直接設定ファイルを変更して追記することもできます。
同一のLogGroup名で異なるEC2インスタンス(異なるLogStream)から情報をアップすると、LogGroup単位でフィルタリングしたりの操作ができます(後述)

対話式or設定ファイルに記載すると、しばらくするとAWS Console上でログが確認できるようになります。

f:id:uzabase:20150303013326p:plain

ログの保持期間

CloudWatchのメトリクスは保持期間が2週間でしたが、CloudWatch LogsではLog Groupsの保持期間として1日〜10年、または有効期限なしが設定可能になりました。
やはりログをアップロードするとなると、長く保持できるのは助かります。
(ただし、後述するFilterによってアップロードされるメトリクスの保持期間は選べません)

f:id:uzabase:20150303013441p:plain

Filterの設定

このアップロードされたログからFilterを作成すると、CloudWatchにメトリクスとしてアップロードされます。

設定例1) ログからERRORを抜き出す
ログから単純に文言をgrepするようなFilterです。

f:id:uzabase:20150303014218p:plain

設定例2) HTTPステータスが200で、応答時間が1秒以上のログを抜き出す
スペース区切りのログについては、パターン指定して値を抜き出すこともできます。

f:id:uzabase:20150303014457p:plain

上記のようなFilterを作成し、右下のTest Patternボタンを押すとどのログがヒットするかも事前にテストできるので、操作はとても簡単でした。
このFilterの結果をCloudWatchメトリクスとしてアップロードすることができます。
単純なgrepの場合は、事象が発生すると1とカウントされますが、パターン指定した場合はマッチしたパターンをメトリクスとすることもできるようです。
(◯◯秒以上かかった処理時間のみをメトリクスとして記録、のような)
メトリクスからアラームを作成する部分は、通常のCloudWatchと同様です。

まとめ

ログから事象を発生ベースでメトリクスとして記録する部分がかなり簡易化されました。
今まで定常的なリソース監視に使用していたCloudWatchを、不定期に発生するイベントの監視としても使いやすくなりました。
設定、操作もかなり簡単なので、今まで手作りのスクリプトで監視していた部分を一部移行できそうです。
今後の改善要望としては、ログを時間でしか検索できない部分や、Filterがスペース区切りにしか対応していない部分(正規表現で後方参照したい・・・)などが改善されるとさらに使いやすくなると思います。

NewsPicksではエンジニアを募集しています!
各種AWSサービスを利用しながら、安定したサービス提供のための開発・運用を日々おこなっています。
興味のある方はぜひご応募待っています!