Windowsパフォーマンスモニタ―の値をNew Relicに送信する

## はじめに
この記事はNewRelicアドベンドカレンダーシリーズ3、12月14日目の記事です。

https://qiita.com/advent-calendar/2023/newrelic

## 経緯
担当業務でZabbixやCloudWatchなど複数のシステムでの計測をNew Relicに移行しました。その際に、Zabbixで収集していたWindowsパフォーマンスの値が、New Relic Infrastructureのエージェントをインストールしただけでは計測できませんでした。
そのため、この値をNew Relic Flexを使用して収集・計測できるようにした際の手順の記録になります。

## 前提
- 対象となるWindowsにはNew Relic Infrastructureが構築済み
- 実行したいパフォーマンスの値を取得するpowershellコマンドは下記
``` powershell
typeperf -sc 1 '\ASP.NET Applications(__Total__)\Request Execution Time'
typeperf -sc 1 '\ASP.NET Applications(__Total__)\Requests/Sec'
typeperf -sc 1 '\TCPv4\Connections Established'
typeperf -sc 1 '\ASP.NET\Requests Queued'
```

## 設定手順
1. New Relic Flexを有効にするため、```C:\Program Files\New Relic\newrelic-infra\integrations.d```内に```newrelic-infra-winpkg-config.yml```を作成します。
  設定ファイルの内容は下記になります。名称等はサンプルなのでご注意ください。
    ``` yaml
    integration_name: com.newrelic.winpkg
    
    instances:
      - name: windows_packages
        command: packages
        arguments:
            include_components: false
    
    integrations:
     - name: nri-flex
       interval: 60s
       timeout: 15s
       config:
         name: windowsPerformanceMonitor
         apis:
          - event_type: typeperfEvent
            commands:
              - run: powershell /c typeperf -sc 1 '\ASP.NET Applications(__Total__)\Request Execution Time'
                split: horizontal
                set_header: [datetime,requestExecutionTime]
                regex_match: true
                row_start: 2
                split_by: \"(.+)\",\"(.+)\"
              - run: powershell /c typeperf -sc 1 '\ASP.NET Applications(__Total__)\Requests/Sec'
                split: horizontal
                set_header: [datetime,requestsSec]
                regex_match: true
                row_start: 2
                split_by: \"(.+)\",\"(.+)\"
              - run: powershell /c typeperf -sc 1 '\TCPv4\Connections Established'
                split: horizontal
                set_header: [datetime,connectionsEstablished]
                regex_match: true
                row_start: 2
                split_by: \"(.+)\",\"(.+)\"
              - run: powershell /c typeperf -sc 1 '\ASP.NET\Requests Queued'
                split: horizontal
                set_header: [datetime,requestsQueued]
                regex_match: true
                row_start: 2
                split_by: \"(.+)\",\"(.+)\"
    ```
    integrations内は実行するコマンドによって変更が必要です。詳細については後述します。
1. ```newrelic-infra```のサービスを再起動します。

1. ```C:\Users\UserName\.newrelic\newrelic-cli.log```を確認し、正常にサービスが起動していることを確認します。
  ymlの記述に問題がある場合、logファイルにエラーが出力されます。
1. NewRelicのコンソールからQueryを選択し、下記クエリをそれぞれ実行して送信された値が取得できることを確認します。
   SELECT句にはset_headerの2つ目の値、FROM句にはevent_typeの値をそれぞれ指定します。
    ``` sql
    SELECT requestExecutionTime FROM typeperfEvent SINCE 1 hours ago LIMIT MAX
    SELECT requestsSec FROM typeperfEvent SINCE 1 hours ago LIMIT MAX
    SELECT connectionsEstablished FROM typeperfEvent SINCE 1 hours ago LIMIT MAX
    SELECT requestsQueued FROM typeperfEvent SINCE 1 hours ago LIMIT MAX
    ```
    クエリを実行したがレコードが存在しない場合、New Relicにデータが送信できていません。
    また、送信された値が空の場合、ymlで定義したconfigの値が正しくない可能性があります。

## ymlファイルの設定について
ここではymlの設定についてポイントとなる部分を説明します。

#### integrations.interval
計測値を取得する間隔です。
コマンドの実行そのものに時間がかかる場合、それよりも短いと正しく値が取れなくなる可能性があります。

#### apis.event_type
Queryで確認する時、FROM句に指定する値になります。

#### commands.run
New Relic Flexで定期実行されるコマンドです。
今回サンプルに記載したコマンドは全てCSV形式で結果が出力されるため注意が必要です。
実際に試す前に、必ずコマンドプロンプト上で実行した結果を確認しましょう。

#### commands.set_header
Queryで確認する時、SELECT句に指定する値になります。

#### commands.row_start
```commands.run```の実行結果から先頭の指定行数をスキップして送信する際に設定します。
今回サンプルに使用したコマンドの場合、1行目が空行、2行目がヘッダ、3行目が計測値になるため、設定すべき値は2になります。

#### commands.split_by
```commands.run```の実行結果をNew Relicに送信する値に分割するための正規表現です。
今回サンプルに使用したコマンドの場合、下記のような計測値が返ります。
``` bash
"12/12/2023 19:44:37.946","0.000000"
```
そのため、それぞれダブルクォートとカンマを除去し、実際に値が入る箇所を括弧で囲んだ正規表現を使用します。
```
\"(.+)\",\"(.+)\"
```

## 参考
https://newrelic.com/jp/blog/how-to-relic/how-to-use-new-relic-flex
https://learn.microsoft.com/ja-jp/windows-server/administration/windows-commands/typeperf