New RelicのNerdGraphを用いて1分ごとにアクセス数を集計しCSV出力する

はじめに

この記事は、トラストバンク Advent Calendar 2023の15日目の記事となります!

こんにちは、4日目の記事も書かせていただいておりました、トラストバンクの@h0r4kです。

今回試したこと

今回の記事では、NewRelicのNerdGraphAPI)を用いて、1ヶ月以内の特定のエンドポイントへのアクセス数を1分間隔で集計し、CSVファイルに出力するプログラムを作成します。

今回取得目的は特にありませんが、NewRelicのNerdGraphを使用することでNRQLと組み合わせながら条件を指定しつつ、目的のデータをループ処理で取得することを目指します。

事前準備

まずは事前準備としてAPIキーを発行します。

NewRelic画面左下のアイコンをクリックし[API Keys]をクリックします。

画面遷移後、[Create a key]をクリックし、必要な項目を入力してAPIキーを発行します。※Accountを間違えないようご注意ください

APIキーが一覧に追加されたら[…]をクリック、[Copy key]をクリックしAPIキーをコピーします。

これにて準備は完了です。

NRQLを組み立ててみる

では、実際にプログラムを記述する前に、まずはデータ取得に必要なNRQLを組み立ててみましょう。

今回は下記のように絞り込み条件を含めながら、TIMESERIESを1分として設定し、1分ごとでアクセス数を集計していきます。

SELECT count(*) FROM Log WHERE 絞り込み条件 TIMESERIES 1 minute LIMIT MAX

なお、実際の取得時には、SINCEUNTILを指定しますが、こちらの期間はTIMESERIESを1分で設定するため、6時間間隔として設定いたします。(現在のNewRelicの仕様上TIMESERIESが1分の場合は6時間以上のデータ取得ができません)

コードに書き起こしてみる

では実際にコードに起こしてみましょう。

今回のコードでは、NewRelicの制約のもとに6時間毎でSINCE,UNTILを区切りながら、ループでデータを取得していきました。 (対象期間は$start_str = "2023-01-01"$end_str = "2023-01-02"として指定しています)

<?php

date_default_timezone_set('Asia/Tokyo');

$url = 'https://api.newrelic.com/graphql';
$api_key = APIキー;
$account_id = アカウントID;
$start_str = "2023-01-01";
$end_str = "2023-01-02";
$start = new DateTimeImmutable($start_str);
$end =  new DateTimeImmutable($end_str);
$day_span = ($end->getTimestamp() - $start->getTimestamp()) / 86400 + 1;

$fp = fopen("access_per_minutes_{$start_str}_{$end_str}.csv", 'a');
fputs($fp, 'タイムスタンプ,呼び出し回数' . PHP_EOL);

for ($day = 0; $day < $day_span; $day++) {
    for ($quarter = 0; $quarter < 4; $quarter++) {
        $hour1 = $day * 24 + $quarter * 6;
        $hour2 = $day * 24 + $quarter * 6 + 6;
        $since = $start->modify("+$hour1 hour")->format('Y-m-d H:i:sP');
        $until = $start->modify("+$hour2 hour")->format('Y-m-d H:i:sP');
        echo 'since: ' . $since . "\n";
        echo 'until: ' . $until . "\n\n";
        $nrql = "SELECT count(*) FROM Log WHERE 条件 TIMESERIES 1 minute SINCE '$since' UNTIL '$until' LIMIT MAX";

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['query' => "{actor{account(id:$account_id){nrql(query:\"$nrql\"){results}}}}"]));
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'API-Key: ' . $api_key,
        ]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = json_decode(curl_exec($ch), true);
        curl_close($ch);
        foreach($result['data']['actor']['account']['nrql']['results'] as $record) {
            $row = $record['beginTimeSeconds'] . ',' . $record['count'] . PHP_EOL;
            fputs($fp, $row);
        }
    }
}

fclose($fp);

実行します。

$ php newrelic_api.php
since: 2023-01-01 00:00:00+09:00
until: 2023-01-01 06:00:00+09:00
...
since: 2023-01-02 18:00:00+09:00
until: 2023-01-03 00:00:00+09:00

CSVにも無事結果が出力されました🙆🏻‍♂️ (期間も48時間分取得できました)

タイムスタンプ,呼び出し回数
1672498800,370
1672498860,173
...
1672671360,122
1672671420,114

成功です!

終わりに

今回の記事では、New RelicのNerdGraphを用いて1分ごとのアクセス数集計を行いました。

ただし今回の実装では、NRQLを利用する前提でNewRelicのNerdGraphを脳筋コールしただけなので、今後はもう少しNerdGraph本来の力を引き出せるような使用方法をご紹介できればなと思います。

最後までご覧いただきありがとうございました!

エンジニア募集

弊社では絶賛エンジニア募集中ですので、気になった方は是非ご連絡ください!

www.wantedly.com