PHPを使ってCloudWatch Logsからデータを取得し、4xx系のレポートを作成する方法

前回の記事で、PythonとBoto 3を使い、CloudWatch Logsからデータを取得して4xx系のレポートを作る方法を紹介しました。今回の記事ではPHPを使って、同じこと(CloudWatch Logsから習得したデータからレポートを作る)をする方法を紹介します。

出力するレポートは、昨日と同様に、ステータスコード4xxが発生したパスと、その出現回数を1行にまとめたものです。

/foo.php: 50
/bar.php: 40
/baz.php: 35

動作確認に使用したPHPのバージョンは7.0.1です。また、利用したAWSのSDKはバージョン3?になります。

CloudWatch Logsの準備

前回の記事と重複した部分もありますが、もう一度おさらいしておきます。

CloudWatch Logsの設定

CloudWatch Logsを導入してログを送信できるようにするには、AWSのドキュメントを参照するのがわかりやすいと思います。また、私の過去の記事CloudWatch Logsを使って500系のレスポンスを検知する方法も参考になれば幸いです。

Policyを追加

今回の記事ではfilter-log-eventsというコマンドを使うので、そのためのPolicyを追加しておきます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:FilterLogEvents"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

CLIで実行

設定が完了したら、サーバ上でコマンドを叩き、CloudWatch Logsのデータを習得できることを確認してみます。

$ aws logs filter-log-events --log-group-name LOG_GROUP_NAME

なお、filter-log-eventsで指定するLOG_GROUP_NAMEは、etc/awslogs/awslogs.confで定義したものを使います。

[/var/log/nginx/access.log]
...
log_group_name = LOG_GROUP_NAME

ログを習得できたらCloudWatch Logsの準備は完了です。

$ aws logs filter-log-events --log-group-name LOG_GROUP_NAME


{
    "searchedLogStreams": [
        {
            "searchedCompletely": false,
            "logStreamName": "i-xxxxxxxx"
        },
        {
            "searchedCompletely": true,
            "logStreamName": "i-xxxxxxxx"
        }
    ],
    "events": [
        {
        ...

PHPでCloudWatch Logsにアクセス

PHP用のSDKを使って、CloudWatch Logsからデータを習得してみます。

SDKを導入

まずは、AWSのSDKを、ドキュメントに従って導入してみます。私は一番簡単そうな、InstallationInstalling via Zipを従ってインストールしました。

$ mkdir aws
$ wget http://docs.aws.amazon.com/aws-sdk-php/v3/download/aws.zip
$ unzip aws.zip -d aws

これで、作成したディレクトリawsの中に、AWSの操作に必要なファイルが展開されました。

$ ls aws
Aws         JmesPath        Psr
CHANGELOG.md        LICENSE.md      README.md
GuzzleHttp      NOTICE.md       aws-autoloader.php

SDKを利用してログを表示

SDKを取得したら、CloudWatch Logsにアクセスしてデータを取得し、出力するサンプルを作ってみます。まずは、aws.zipが置いてあるディレクトリに、PHPファイルprint_logs.phpを作成します。

$ touch print_logs.php

PHPファイルを作成したら、まずはSDKのファイルを読み込みます。私の場合はInstall via Zipで取得したので、以下のようになります。

<?php
require 'aws/aws-autoloader.php';

必要なファイルを読み込んだら、以下のようにCloudWatch Logsに接続するクライアントを作成します。

// CloudWatch Logsに接続するためのクライアントを用意します。
$client = new Aws\CloudWatchLogs\CloudWatchLogsClient([
    'profile' => 'dummy_account',
    'version' => 'latest',
    'region'  => 'ap-northeast-1'
]);

ちなみに、上記profileで指定しているdummy_accountは、~/.aws/credentialsに以下のように定義しました。

$ cat ~/.aws/credentials
...

[dummy_account]
aws_access_key_id = AWS_ACCESS_KEY
aws_secret_access_key = AWS_SECRET_KEY

クライアントを作成したら、filterLogEventsメソッドを使ってデータを取得できるようになります。

// CloudWatch Logsからログを習得します。
$result = $client->filterLogEvents([
    'logGroupName' => 'LOG_GROUP_NAME'
]);
$events = $result->get('events');

// ログの1行1行を出力します。
foreach ($events as $row) {
    print('message: ' . $row['message'] . "\n");
}

このPHPファイルを実行し、ログが画面に表示されればデータ取得成功になります。

PHPのコード全体は以下のようになります。

4xx系レポートを作成するコード

これらをふまえて、CloudWatch Logsからデータを取得し、4xx系のレポートを作成するコードを書いてみます。

このコードではファイルに書き出していますが、実際の運用ではメール送信するようにして、crontabに仕込んだ方がいいと思います。また、出力対象は404だけに絞ったり、目的に応じてカスタマイズするのもいいと思います。

この記事が役に立った場合、シェアしていただけると励みになります!!