New Relic FlexでPowerShellの結果をCustom Eventに連携する

記事タイトルとURLをコピーする

こんにちはマネージドサービス部 大城です。 私は普段bashぐらいしか書かない(書けない)のですが、Windows上でPowerShellの結果をNew Relicのメトリクスとして連携したい要件があり、初めてPowerShellを触ったので備忘録としてブログに残します。

New Relic Flex ってなに

New Relicインフラストラクチャーエージェント に同封されている機能です。ymlを書いたらコマンド結果をNew RelicのCustom Eventに送信してくれます。New Relicの標準メトリクスでは取れないメトリクスを手作りのスクリプトで取ることが出来ます。

docs.newrelic.com

どんなときに使うのか

例えば下のようなユースケースが考えられます。(前のブログからのコピペ)

  • DBで特定テーブルの件数を収集し、バッチ実行時間帯の容量推移を確認する
  • アプリケーションで問題となりそうなデータを抽出し件数を把握する
  • アプリケーションスレッドの生死を収集し、より細かいヘルスチェックをする

どうやって設定するのか

(個人的に一番簡単な方法として)jsonで標準出力するPowerShellを作成してymlを記載することで設定できます。別の方法としてflexでヘッダーとフィールドを定義して送る方法もあります。その他、ユースケース毎のサンプルがGithubに上がっていたので、ここからymlを拝借するもの良いと思います

github.com

やってみた

前提

New Relic Flex を使うためにはWindowsにNew Relicインフラストラクチャーエージェントをインストールする必要があります。下記リンクの「ガイド付きインストール」からPowerShellにてワンライナーでインストールできます。

インフラストラクチャエージェントをインストールします | New Relic Documentation

PowerShellの作成

まずはPowerShellを作成します。機能を確認するため最低限のコードになります

  • C:\Program Files\New Relic\newrelic-infra\script\test.ps1
$toNewRelic = New-Object -TypeName psobject
$toNewRelic | Add-Member -MemberType NoteProperty -Name "status" -Value "0" -Force
$toNewRelic | Add-Member -MemberType NoteProperty -Name "appname" -Value "app01" -Force
$toNewRelic | ConvertTo-Json

実行すると下のような出力をしてくれます。

powershell実行

Flexの設定

次にflexの設定を追加します。

  • C:\Program Files\New Relic\newrelic-infra\integrations.d\nri-flex.yml
---
integrations:
  - name: nri-flex
    interval: 60s
    config:
      name: status_check
      apis:
        - event_type: status_check
          shell: powershell
          commands:
            - run: "& \"C:/Program Files/New Relic/newrelic-infra/script/test.ps1\""

New Relicインフラストラクチャーエージェントを再起動します。

net stop newrelic-infra
net start newrelic-infra

Eventの確認

しばらく待つとNew Relicににデータが来るので、連携された Event を見てみます。Custom Eventにデータが連携されていることが分かります。

  • Query Your Data > Data explorer > Events > Event type > status_check

Events

NRQL で中身を確認します。

SELECT * FROM status_check limit 1

NRQL

[
  {
    "results": [
      {
        "events": [
          {
            "agentName": "Infrastructure",
            "agentVersion": "1.47.2",
            "appname": "app01",
            "aws.arn": "arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:instance/i-XXXXXXXXXXXXXXXXX",
            "awsAccountId": "XXXXXXXXXXXX",
            "awsAvailabilityZone": "ap-northeast-1c",
            "awsRegion": "ap-northeast-1",
            <省略>
            "status": 0,
            "systemMemoryBytes": "8482484224",
            "timestamp": 1697770995000,
            "windowsFamily": "Server",
            "windowsPlatform": "Microsoft Windows Server 2019 Datacenter",
            "windowsVersion": "10.0.17763 Build 17763"
          }
        ]
      }
    ],
    "metadata": {
      <省略>
    }
  }
]

フィールドが多くありますがPowerShellが出力した { "status": "0", "appname": "app01"} が連携されていることが分かります。

スクリプトがエラーになったとき

エラーのときの挙動を確認してみます。PowerShellの最後に「exit 1」を入れてスクリプトを保存

  • C:\Program Files\New Relic\newrelic-infra\script\test.ps1
$toNewRelic = New-Object -TypeName psobject
$toNewRelic | Add-Member -MemberType NoteProperty -Name "status" -Value "0" -Force
$toNewRelic | Add-Member -MemberType NoteProperty -Name "appname" -Value "app01" -Force
$toNewRelic | ConvertTo-Json
exit 1

しばらく動かしてNRQLで確認します。

SELECT * FROM status_check limit 1
[
  {
    "results": [
      {
        "events": [
          {
            <省略>
            "error": "exit status 1",
            "error_exec": "& \"C:/Program Files/New Relic/newrelic-infra/script/test.ps1\"",
            "error_msg": "{\r\n    \"status\":  \"0\",\r\n    \"appname\":  \"app01\"\r\n}\r\n",
            <省略>
          }
        ]
      }
    ],
    <省略>
  }
]

フィールドにエラーメッセージが記録されていました。親切!

スクリプトのパスが間違っていたとき

こちらも実際に動かしてみます。flexの設定を編集します。

  • C:\Program Files\New Relic\newrelic-infra\integrations.d\nri-flex.yml
---
integrations:
  - name: nri-flex
    interval: 60s
    config:
      name: status_check
      apis:
        - event_type: status_check
          shell: powershell
          commands:
            # エラーが出るようにパスを間違える
            - run: "& \"C:/Program Files/New Relic/newrelic-infra/script/aaaaaaatest.ps1\""

NRQLで確認します。

SELECT * FROM status_check limit 1
[
  {
    "results": [
      {
        "events": [
          {
            <省略>
            "error": "exit status 1",
            "error_exec": "& \"C:/Program Files/New Relic/newrelic-infra/script/aaaaaaatest.ps1\"",
            "error_msg": "& : �p�� 'C:/Program Files/New Relic/newrelic-infra/script/aaaaaaatest.ps1' �́A�R�}���h���b�g�A�֐��A�X�N���v�g �t�@�C\r\n���A�܂��͑����\\�ȃv���O�����̖��O�Ƃ��ĔF�������܂����B���O���������L�q�����Ă��邱�Ƃ��m�F���A�p�X���܂܂��Ă�����\r\n���͂��̃p�X�����������Ƃ��m�F���Ă����A�Ď��s���Ă��������B\r\n�����ꏊ �s:1 ����:3\r\n+ & \"C:/Program Files/New Relic/newrelic-infra/script/aaaaaaatest.ps1\"\r\n+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n    + CategoryInfo          : ObjectNotFound: (C:/Program File...aaaaaaatest.ps1:String) [], CommandNotFoundException\r\n    + FullyQualifiedErrorId : CommandNotFoundException\r\n \r\n",
            <省略>
          }
        ]
      }
    ],
    <省略>
  }
]

こちらもフィールドにエラーメッセージが記録されていました。本番環境で利用する場合は、こちらをNRQLでCondition設定することでエラー時に気づくことができます。

最後に

ここまで読んでいただきありがとうございます。この記事が誰かの役に立ったら幸いです。 最近Windows触ることも多いのでPowerShellも勉強しようかと思います!

大城 慶明 (記事一覧)

マネージドサービス部

2022年10月サーバーワークスに入社、沖縄からリモート勤務。AWSを勉強中。沖縄では大城が多いので「よっさん」と呼ばれています。AWS12冠。X @yo_ohshiro