Skip to content

Instantly share code, notes, and snippets.

@yusukemurayama
Last active January 7, 2016 04:13
Show Gist options
  • Save yusukemurayama/0d0a81cad039cc68964b to your computer and use it in GitHub Desktop.
Save yusukemurayama/0d0a81cad039cc68964b to your computer and use it in GitHub Desktop.
PHPを使って、CloudWatch Logsからデータを取得します。
<?php
require 'aws/aws-autoloader.php';
class LogReport {
const LOG_GROUP_NAME = 'LOG_GROUP_NAME';
const FILTER_PATTERN = '[ip, dummy1, uid, timestamp, request, status_code = 4*, bytes, referer, user_agent]';
const PATH_PATTERN = '/"(?:GET|POST|HEAD) ([^ ]+) [^ ]+" \d{3}/';
const AWS_PROFILE = 'dummy_account';
const AWS_VERSION = 'latest';
const AWS_REGION = 'ap-northeast-1';
/**
* コンストラクタ
*
* @param string $output_path 出力先ファイルのパス
*/
function __construct($output_path) {
$this->output_path = $output_path;
// CloudWatch Logsに接続するためのクライアントを用意します。
$this->client = new Aws\CloudWatchLogs\CloudWatchLogsClient([
'profile' => self::AWS_PROFILE,
'version' => self::AWS_VERSION,
'region' => self::AWS_REGION
]);
}
/**
* レポートを出力します。
*
* @param string $start_date 開始日
* @param string $end_date 終了日
*/
public function output_report($start_date, $end_date) {
// 開始時刻・終了時刻をタイムスタンプ(ミリ秒)で計算します。
// 開始時刻は、start_dateで指定したyyyy-mm-ddの0時0分0秒から計算します。
// 終了時刻は、end_dateで指定したyyyy-mm-ddの翌日から、1ミリ秒弾いて計算します。
// ※面倒なので、JSTからUTCに直していません。
$start_time = strtotime($start_date) * 1000;
$end_time = strtotime('+1 day', strtotime($end_date)) * 1000 - 1;
// レポートのデータを取得します。
$data = $this->get_report_data($start_time, $end_time);
// 結果をファイルに出力します。
$fp = fopen($this->output_path, 'w') or die('Cannot open a file.');
foreach ($data as $path => $count) {
fwrite($fp, sprintf("%s: %d\n", $path, $count));
}
fclose($fp);
}
/**
* CloudWatch Logsからデータを取得し、整形します。
*
* @param int $start_time 開始時刻(タイムスタンプ, ミリ秒)
* @param int $end_time 終了時刻(タイムスタンプ, ミリ秒)
* @return array $data 4xxレポートデータ(key: パス、value: 出現回数)
*/
private function get_report_data($start_time, $end_time) {
$data = array(); // 戻り値を定義します。
// CloudWatch Logsに格納されたログの中から、規定の条件に一致したものを取得します。
$result = $this->client->filterLogEvents([
'logGroupName' => self::LOG_GROUP_NAME,
'filterPattern' => self::FILTER_PATTERN,
'startTime' => $start_time,
'endTime' => $end_time
]);
$events = $result->get('events');
foreach ($events as $row) {
$message = $row['message']; // ログ1行を取り出します。
if (preg_match(self::PATH_PATTERN, $message, $m)) {
$path = $m[1]; // パスを取得します。
if (!array_key_exists($path, $data)) {
// 初めて出現したパスの場合は、key: パス, value: 1で$dataに追加します。
$data[$path] = 1;
} else {
// 出現回数を増やします。
$data[$path]++;
}
}
}
arsort($data); // Value(出現回数)の降順でソートします。
return $data;
}
}
$output_path = './log_report.txt';
$i = new LogReport($output_path);
// 開始日と終了日を決定します。
$start_date = date('Y-m-d', strtotime('-8 day'));
$end_date = date('Y-m-d', strtotime('-1 day'));
// 4xx系のレポートを出力します。
$i->output_report($start_date, $end_date);
<?php
require 'aws/aws-autoloader.php';
// CloudWatch Logsに接続するためのクライアントを用意します。
$client = new Aws\CloudWatchLogs\CloudWatchLogsClient([
'profile' => 'dummy_account',
'version' => 'latest',
'region' => 'ap-northeast-1'
]);
// CloudWatch Logsからログを取得します。
$result = $client->filterLogEvents([
'logGroupName' => 'LOG_GROUP_NAME'
]);
$events = $result->get('events');
// ログの1行1行を出力します。
foreach ($events as $row) {
print('message: ' . $row['message'] . "\n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment