OCI VM(Windows)のディスク使用率を.NETを使って監視

# 概要
[Oracle Cloud Infrastructure（OCI）](https://www.oracle.com/jp/cloud/)上に作成したVM(Windows)のディスク使用率をカスタムメトリックを使って監視します

Pythonを使った例は以下に記載しております

https://qiita.com/tktk2712/items/f1c9002ff5fb20040e0a#web%E3%82%B5%E3%83%BC%E3%83%90-disk%E4%BD%BF%E7%94%A8%E7%8E%87

今回は以下の前提で作成しています
- WindowsサーバーのCドライブを監視
- .NETを使用
- 資格情報はインスタンスプリンシパルを使用

# 準備
## OCI
インスタンスで認証するためのインスタンスプリンシパルを設定します
- 動的グループ作成
  OCIコンソールのナビゲーションメニューからアイデンティティとセキュリティ>>ドメイン(Default)>>動的グループを選択して「動的グループの作成」を押下
    - 名前：任意の名前を設定
    - 一致ルール：
    - コンパートメント配下インスタンスを動的グループとして指定
    - "下で定義したいずれかのルールに一致"を選択してルールを記述
```
instance.compartment.id = '【コンパートメントOCID ocid1.compartment.oc1..】resource.compartment.id = '【コンパートメントOCID ocid1.compartment.oc1..】
```
参考
[動的グループを定義するための一致ルールの記述](https://docs.oracle.com/ja-jp/iaas/Content/Identity/dynamicgroups/Writing_Matching_Rules_to_Define_Dynamic_Groups.htm)

- ポリシー作成
OCIコンソールのナビゲーションメニューからアイデンティティとセキュリティ>>ポリシーを選択して「ポリシーの作成」を押下
    - ルールを記述
```
Allow dynamic-group 【動的グループ】 to use metrics in compartment 【コンパートメント】
```
参考
[ポリシーリファレンス モニタリングの詳細](https://docs.oracle.com/ja-jp/iaas/Content/Identity/Reference/monitoringpolicyreference.htm)

## Windows
Disk使用率を定期的にカスタムメトリックにPostする仕組みを作成します
- Windows Serverに.NET SDKをインストール
  [.NET のダウンロード](https://dotnet.microsoft.com/ja-jp/download)

- バージョン確認
```
C:\path\to> dotnet --version
9.0.300
```
- フォルダ作成
diskcheck_dotnet_cを作成しました

- C# .NETコンソール・アプリケーションを作成します
```
C:\path\to> cd diskcheck_dotnet_c
C:\path\to\diskcheck_dotnet_c> dotnet new console
テンプレート "コンソール アプリ" が正常に作成されました。

作成後の操作を処理しています...
C:\path\to\diskcheck_dotnet_c\diskcheck_dotnet_c.csproj を復元しています:
正常に復元されました。
```
- OCI SDKパッケージを追加します
```
C:\path\to\diskcheck_dotnet_c> dotnet add package OCI.DotNetSDK.Common
C:\path\to\diskcheck_dotnet_c> dotnet add package OCI.DotNetSDK.Monitoring
```
- Program.csのコードを置き換え作成
以下は環境に合わせてください
    - DriveInfo("C"): Dドライブを監視する場合はDに変更
    - .[CompartmentOCID]:コンパートメントOCID
    - .[ServerID]:Serverの名前
    - https ://telemetry-ingestion.ap-tokyo-1.oraclecloud.com :osakaはap-osaka-1

```
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Oci.MonitoringService;
using Oci.Common;
using Oci.Common.Auth;

namespace Oci.Sdk.DotNet.Example.Monitoring
{
    public class PostMetricDataExample
    {
        public static async Task Main()
        {
            // Get drive usage
            DriveInfo drive = new DriveInfo("C");
            double usedPercentage = Math.Round(((double)(drive.TotalSize - drive.AvailableFreeSpace) / drive.TotalSize) * 100);
            // Create a request and dependent object(s).
            var postMetricDataDetails = new Oci.MonitoringService.Models.PostMetricDataDetails
            {
                MetricData = new List<Oci.MonitoringService.Models.MetricDataDetails>
                {
                    new Oci.MonitoringService.Models.MetricDataDetails
                    {
                        Namespace = "custom_metrics",
                        CompartmentId = "[CompartmentOCID]",
                        Name = "disk_usage",
                        Dimensions = new Dictionary<string, string>()
                        {
                            {
                                "server_id", 
                                "[ServerID]"
                            }
                        },
                        Datapoints = new List<Oci.MonitoringService.Models.Datapoint>
                        {
                            new Oci.MonitoringService.Models.Datapoint
                            {
                                Timestamp = DateTime.UtcNow,
                                Value = usedPercentage,
                            }
                        }
                    }
                },
                BatchAtomicity = Oci.MonitoringService.Models.PostMetricDataDetails.BatchAtomicityEnum.Atomic
            };
            var postMetricDataRequest = new Oci.MonitoringService.Requests.PostMetricDataRequest
            {
                PostMetricDataDetails = postMetricDataDetails
            };
            // Create a Instance Principals Authentication
            var provider = new InstancePrincipalsAuthenticationDetailsProvider();
            var client = new MonitoringClient(provider, new ClientConfiguration());
            string serviceEndpoint = "https://telemetry-ingestion.ap-tokyo-1.oraclecloud.com";
            client.SetEndpoint(serviceEndpoint);
            try
            {
                // Create a service client and send the request.
                var response = await client.PostMetricData(postMetricDataRequest);
                // Retrieve value from the response.
                var failedMetricsCountValue = response.PostMetricDataResponseDetails.FailedMetricsCount;
            }
            catch
            {
                throw;
            }
        }

    }
}
```
- コマンドを実行してエラーがないことを確認します
```
C:\path\to\diskcheck_dotnet_c> dotnet run
```
- バッチ作成してタスクスケジューラで実行可能にします

```diskcheck_dotnet_c.bat
@echo off
cd /d C:\path\to\diskcheck_dotnet_c
dotnet run
```
- タスクスケジューラ作成
1時間ごとに実行するよう定期実行を設定します

タスクスケジューラ
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/2e1da860-8d10-4b29-b53d-92b6d9b2c742.png">
全般
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/3cedfe08-3aa9-4963-8e69-7c2f2fe184ce.png">
トリガー
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/e6eee415-71ee-4378-b25d-b241591ae4d9.png">
トリガー詳細
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/451341e0-973a-467e-9ee9-4d5ad532a50a.png">
操作
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/2f6ef466-9985-4562-8079-07206fabb822.png">
操作詳細
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/7c9d98dc-654c-42e9-b159-085264f24a0b.png">

# アラーム定義作成

- アラーム定義
    - OCIコンソールメニューから監視および管理>>モニタリング>>アラーム定義を選択
    - 「アラームの作成」ボタンを押下
    - アラーム名、重大度選択およびアラーム本体を設定
    - メトリック・ネームスペースはcustom_metricsを指定
    - メトリック名にdisk_usageを指定
    - 間隔時間を指定
    - 統計にMeanを指定
    - メトリック・ディメンション名はserver_id、ディメンション値で対象hostを指定します
    - トリガー・ルールでアラーム起動条件を指定。例えばディスク使用率90%超が2時間連続して発生を条件とする場合は、演算子：次より大きい、値：90、トリガー遅延分数：60を指定
    - 宛先に作成済の通知設定を選択
    - 「アラームの保存」ボタンを押下

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/adaeb804-42d6-4f93-8a19-94c807e3f52f.png">

# 参考
APIを使用したカスタム・メトリックの公開

https://docs.oracle.com/ja-jp/iaas/Content/Monitoring/Tasks/publishingcustommetrics.htm#top

API Reference and Endpoints PostMetricData

https://docs.oracle.com/en-us/iaas/api/#/en/monitoring/20180401/MetricData/PostMetricData

SDK for .NETストリーミング・クイックスタート

https://docs.oracle.com/ja-jp/iaas/Content/Streaming/Tasks/streaming-quickstart-oci-sdk-for-dotnet.htm