NerdGraph APIに入門する
この記事は、AEON Advent Calendar 2024とNew Relic Advent Calendar 2024 シリーズ2の21日目 です🎉
イオンスマートテクノロジー DevSecOps Div SREチームの齋藤( @hikkie13 )です。
本記事では、イオンスマートテクノロジーでの活用事例を通じてNerdGraph APIに入門していきたいと思います。
NerdGraph API とは
New Relicのデータの参照や各種機能の設定を行うための、GraphQL形式のAPIです。
利用シーンとしては
- NRDB内の情報を取得するクエリの実行。
- アカウント、アラート、ダッシュボード等の設定
などが挙げられます。
使うための準備:APIキー
NerdGraphを実行するためには、User API Keyが必要です。
下記のページを参考発行しましょう。
このNerdGraph APIを通じて実現できることは多いのですが
イメージをより具体的にするために、有用だった活用事例をいくつか列挙していきます。
活用例(1): 最終アクセスがn週間より前のユーザをFull Platform UserからBasicに降格させる
New Relicの利用企業ならいつも頭を悩ませるポイントが、Full Platform Userのライセンス数!
定期的に棚卸しをしないといけないですが、定期的にヒアリングするのもトイルですよね。
そんな時、人類は最終アクセスがn週間より前のユーザを定期的に問答無用でbasicに降格したくなるものです。
それ、NerdGraph APIを利用すればできそうです。
「最終アクセス日の取得」と「ユーザータイプの変更」の2stepが必要ですがどちらもNerdGraph APIでできます。
- 最終アクセス日の取得
- ユーザータイプの変更
これらをスクリプト化して定期的に実行するようにすれば完璧ではないでしょうか!?
活用例(2):Alert Policyの設定内容をまとめて一覧化したい
Terraformで管理しているとはいえ、サクッとAlert Policyを一覧で確認したい。
年末商戦を控えたこの時期、そう思うことはないでしょうか!?(諸説あり)
そんな時に NerdGraph APIです。
NerdGraph APIを使えば
- ポリシーの一覧表示とフィルタリング
- ポリシーの作成、更新、削除
が可能です。
例えば、Alert Policyに設定されたincidentPreference の値をまとめて確認したいときは↓を利用してみましょう。
こんな感じで取得できます。
活用例(3): アプリからはデータを送ってしまっているが、New Relic Platformへの保管をさせたくない
New Relicの利用企業ならいつも頭を悩ませるもう一つの要素がデータingest量!
意図せずに余計なデータをNew Relicに送ってしまったことなどありませんでしょうか!(個人情報はダメですよ!)
New Relicにデータを送らないように修正したいけど、様々な事情でアプリケーションのリリースに時間を要する状況などあると思います。
そんな時にNerdGraph APIです。
この機能を利用すれば、New Relicにデータを保管される手前でデータをdropすることができます。
アプリからデータを送らないように修正はしたが、保険のためにNew Relic側でもdrop設定を入れたい場合にも有効だと思います。
活用例(4):NRQLをこねくり回して何か集計したい
ダッシュボードはあるけれど、データを集計して数値としてcsvか何かに保存しておきたい。
保管期間を超えても参照できるように、データをまとめておきたい。
そんな貴方の願い、NerdGraph APIが叶えます。
弊社の例を挙げると、繁忙日に60分ごとや15分ごと、5分ごと、1分ごとのthroughputピーク値と時刻を補完しておきたい。(加えて、AppNameごとやTransactionNameごとにも分けたい)
という要望がありました。
しかし、1日のタイムスパンで1分ごとのデータをNRQLで取得することは難しいです。理由は一度に取得できる実行結果の上限が5,000となっているため、facetなどの条件によって容易く超えてしまうからです。
そんなときループさせるなり何なりとスクリプト化が必須になるので、NerdGraph APIのお世話になります。
以下はPythonのサンプルスクリプトに沿って解説します。
あくまでサンプルなので、ロジックの煩雑さやイマイチな記法、間違いがあったらご容赦ください🙏
まずはクエリに必要な情報を設定(良い子の皆さんは実際にはベタ書きはやめよう)
start_str = "yyyy-mm-dd"
url = 'https://api.newrelic.com/graphql'
api_key = 'XXXX'
account_id = 'XXX'
X分ごとのデータを集めるNRQLを発行し、データをまとめるクエリを作成してループさせる
データはDataFrameに入れて、最終的にcsvにしておく(形式などは要件次第)
def newrelic_appName(timeseries):
start = datetime.strptime(start_str, "%Y-%m-%d")
end = datetime.strptime(start_str, "%Y-%m-%d")
day_span = 1
data = []
for day in range(day_span):
for hour in range(24):
since = (start + timedelta(days=day, hours=hour, minutes=0)).isoformat()
until = (start + timedelta(days=day, hours=hour, minutes=60)).isoformat()
nrql = f"SELECT count(*) FROM Transaction WHERE (transactionType = 'Web') and appName LIKE '[条件]' FACET appName TIMESERIES {timeseries} minutes SINCE '{since}' UNTIL '{until}' WITH TIMEZONE 'Asia/Tokyo' LIMIT MAX EXTRAPOLATE"
headers = {
'Content-Type': 'application/json',
'API-Key': api_key
}
payload = {
'query': f"{{actor{{account(id:{account_id}){{nrql(query:\"{nrql}\"){{results}}}}}}}}"
}
response = requests.post(url, headers=headers, data=json.dumps(payload))
result = response.json()
if 'results' in result['data']['actor']['account']['nrql']:
for record in result['data']['actor']['account']['nrql']['results']:
facet = record['facet']
app_name = facet
count = record['count']
# Convert beginTimeSeconds to date format
begin_time = datetime.fromtimestamp(record['beginTimeSeconds'])
date_str = begin_time.strftime("%Y/%m/%d")
date_time_str = begin_time.strftime("%H:%M")
data.append({
'AppName': app_name,
'Date': date_str,
'Time': date_time_str,
'Count': count
})
# Sort data by AppName in ascending order
sorted_data = sorted(data, key=lambda x: x['AppName'])
# Convert sorted_data to a pandas DataFrame
df = pd.DataFrame(sorted_data)
# Save DataFrame to a CSV file
df.to_csv(f"access_per_{timeseries}minutes_{start_str}.csv", index=False)
もし、ピーク値をその場で表示したい場合は以下のようにcsvファイルを読んだ上でピークの値を出力するようにする
def ana(timeseries):
# Read the CSV file
df = pd.read_csv(f"access_per_{timeseries}minutes_{start_str}.csv")
# Find the row with the maximum count for each app name
max_count_rows = df.groupby('AppName')['Count'].idxmax()
# Get the corresponding Time and Count values
result = df.loc[max_count_rows, ['AppName', 'Date', 'Time', 'Count']]
# Print the result
print(f"TIMESERIES {timeseries}min")
print(result[['AppName', 'Date', 'Time', 'Count']].to_string(index=False))
定義した関数の実行(ここでは15分ごとのデータを集計してみます)
if __name__ == "__main__":
newrelic_appName(15)
ana(15)
実行すると以下のような出力が得られます。
TIMESERIES 15min
AppName Date Time Count
AppName1 2024/12/01 09:00 XXXX
AppName2 2024/12/01 16:15 XXXX
AppName3 2024/12/01 11:00 XXXX
AppName4 2024/12/01 10:00 XXXX
- 今回はAppNameで実施しましたが、エンドポイントごとにまとめるなど要件に応じて変えていくと良さそうです。
- 今回は例としてローカル実行していますが、こちらも定期実行させて何某かに通知させることで良い感じになると思います。
おまけ
本記事の公開前に、New Relic User Group Vol.12 3周年&アドカレLT祭りでお話する機会を頂いたの資料を添えておきます。
最後に
以上、NerdGraph APIの概要と嬉しみポイントについて、一部それを活用したスクリプトを交えてお話しさせて頂きました。
皆さんもNerdGraph APIと共にHappy New Relic Lifeを!
イオングループで、一緒に働きませんか?
イオングループでは、エンジニアを積極採用中です。少しでもご興味もった方は、キャリア登録やカジュアル面談登録などもしていただけると嬉しいです。
皆さまとお話できるのを楽しみにしています!
Discussion