😽

NerdGraph APIに入門する

2024/12/21に公開

この記事は、AEON Advent Calendar 2024New Relic Advent Calendar 2024 シリーズ2の21日目 です🎉

イオン⁠⁠⁠⁠⁠⁠⁠スマートテクノロジー DevSecOps Div SREチームの齋藤( @hikkie13 )です。

本記事では、イオンスマートテクノロジーでの活用事例を通じてNerdGraph APIに入門していきたいと思います。

NerdGraph API とは

https://docs.newrelic.com/jp/docs/apis/nerdgraph/get-started/introduction-new-relic-nerdgraph/

New Relicのデータの参照や各種機能の設定を行うための、GraphQL形式のAPIです。

利用シーンとしては

  • NRDB内の情報を取得するクエリの実行。
  • アカウント、アラート、ダッシュボード等の設定
    などが挙げられます。

使うための準備:APIキー

NerdGraphを実行するためには、User API Keyが必要です。
下記のページを参考発行しましょう。
https://docs.newrelic.com/jp/docs/apis/intro-apis/new-relic-api-keys/#user-api-key

このNerdGraph APIを通じて実現できることは多いのですが
イメージをより具体的にするために、有用だった活用事例をいくつか列挙していきます。

活用例(1): 最終アクセスがn週間より前のユーザをFull Platform UserからBasicに降格させる

New Relicの利用企業ならいつも頭を悩ませるポイントが、Full Platform Userのライセンス数!
定期的に棚卸しをしないといけないですが、定期的にヒアリングするのもトイルですよね。
そんな時、人類は最終アクセスがn週間より前のユーザを定期的に問答無用でbasicに降格したくなるものです。

それ、NerdGraph APIを利用すればできそうです。
「最終アクセス日の取得」と「ユーザータイプの変更」の2stepが必要ですがどちらもNerdGraph APIでできます。

  • 最終アクセス日の取得

https://docs.newrelic.com/jp/docs/apis/nerdgraph/examples/nerdgraph-manage-users/#user-type

  • ユーザータイプの変更

https://docs.newrelic.com/jp/docs/apis/nerdgraph/examples/nerdgraph-manage-users/#update-users

これらをスクリプト化して定期的に実行するようにすれば完璧ではないでしょうか!?

活用例(2):Alert Policyの設定内容をまとめて一覧化したい

Terraformで管理しているとはいえ、サクッとAlert Policyを一覧で確認したい。
年末商戦を控えたこの時期、そう思うことはないでしょうか!?(諸説あり)

そんな時に NerdGraph APIです。

https://docs.newrelic.com/jp/docs/apis/nerdgraph/examples/nerdgraph-api-alerts-policies

NerdGraph APIを使えば

  • ポリシーの一覧表示とフィルタリング
  • ポリシーの作成、更新、削除
    が可能です。

例えば、Alert Policyに設定されたincidentPreference の値をまとめて確認したいときは↓を利用してみましょう。
https://docs.newrelic.com/jp/docs/apis/nerdgraph/examples/nerdgraph-api-alerts-policies/#list-all-policies

こんな感じで取得できます。

活用例(3): アプリからはデータを送ってしまっているが、New Relic Platformへの保管をさせたくない

New Relicの利用企業ならいつも頭を悩ませるもう一つの要素がデータingest量!
意図せずに余計なデータをNew Relicに送ってしまったことなどありませんでしょうか!(個人情報はダメですよ!)

New Relicにデータを送らないように修正したいけど、様々な事情でアプリケーションのリリースに時間を要する状況などあると思います。

そんな時にNerdGraph APIです。

https://docs.newrelic.com/jp/docs/data-apis/manage-data/drop-data-using-nerdgraph/

この機能を利用すれば、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祭りでお話する機会を頂いたの資料を添えておきます。

https://nrug.connpass.com/event/334268/

最後に

以上、NerdGraph APIの概要と嬉しみポイントについて、一部それを活用したスクリプトを交えてお話しさせて頂きました。
皆さんもNerdGraph APIと共にHappy New Relic Lifeを!

イオングループで、一緒に働きませんか?

イオングループでは、エンジニアを積極採用中です。少しでもご興味もった方は、キャリア登録やカジュアル面談登録などもしていただけると嬉しいです。
皆さまとお話できるのを楽しみにしています!

AEON TECH HUB

Discussion