OCI の Linuxファイルシステム使用率 を OCI CLI とシェルでカスタム・メトリックとして取得する(Oracle Cloud Infrastructure)

OCI は OCI Monitoring という監視の仕組みを備えているのですが、標準のメトリックにファイルシステム使用率が含まれていません。
本記事では OCI CLI と シェルスクリプト でファイルシステム使用率をカスタム・メトリックとして取得してみますやで。
彡(ﾟ)(ﾟ)

同様の事をやっている記事は既に幾つか有るのですが、当方 Python には疎いのと複数マウント・ポイントに対応したかったため本記事を執筆しました。使用する OS は Oracle Linux 8 となります。

# 1. OCI CLI のインストール
本記事では詳細は省きます。OCI CLI のインストール方法は幾つかありますが、下記マニュアルの dnfコマンド でインストールしました。

> クイックスタート - CLIのインストール - Oracle Linux 8
> https://docs.oracle.com/ja-jp/iaas/Content/API/SDKDocs/cliinstall.htm#InstallingCLI__oraclelinux8

```shell
sudo dnf -y install oraclelinux-developer-release-el8
sudo dnf install python36-oci-cli
```

# 2. OCI CLI のポリシー(実行権限付与)
本記事では詳細は省きます。OCI CLI の実行権限付与はインスタンス・プリンシパルで実施しました。
下記の動的グループとポリシー(実行権限付与)を行っています。

```shell
-- 動的グループ ayu-dynamic-group02
All {instance.compartment.id = 'ocid1.compartment.oc1..xxxxxxxx'}
```

```shell
-- ポリシー ayu-policy-custommetric
Allow dynamic-group ayu-dynamic-group02 to manage metrics in compartment ayu-compartment01
```

下記マニュアルも参照して下さい。

> インスタンスからのサービスのコール
> https://docs.oracle.com/ja-jp/iaas/Content/Identity/Tasks/callingservicesfrominstances.htm

# 3. シェルスクリプトの配置

opcユーザー(※)のホームディレクトリ配下にディレクトリを作成してスクリプトを配置します。今回は scripts というディレクトリを作成しました。
※今回は opcユーザーを選択していますが OCI CLI を実行できれば OSユーザーは何でも良いです。

```shell
cd
mkdir scripts
cd scripts
(scp や vi 等でファイルを配置)
```


スクリプトは以下の通りです。[GitHub](https://github.com/gonsuke777/OCI/blob/master/OCIFileSystemUsage/OCIFileSystemUsage.sh)にもアップロードしました。


```shell:OCIFileSystemUsage.sh
#!/usr/bin/bash

# ---
# This script uploads Linux file system usage as OCI custom metric by the OCI CLI.
# It must be able to run the OCI CLI beforehand.
# Targets xfs and ext4. It's excluded for nfs etc and /boot.
# Please edit in this shell environment variables. PATH, workfile, jsonfile, etc.
# ---
# Usage Example ... $ ./OCIFileSystemUsage.sh
# Parameters    ... Not required
# Return Code
#   0 ... Successful completion.
#   1 ... abend.
# ---

# Initialize
LANG=en_US.UTF-8
PATH=/home/opc/bin:/home/opc/.local/bin:/home/opc/bin:/usr/share/Modules/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin
mypath=$(dirname "${0}")
cliLocation="/usr/bin/oci"
workfile="${mypath}/filesystemusage_work.txt"
jsonfile="${mypath}/filesystemusage_work.json"

# OCI env initialize
compartmentId=$(curl -s -L http://169.254.169.254/opc/v1/instance/ | jq -r '.compartmentId')
metricNamespace="compute_filesystem_usage"
metricResourceGroup="compute_filesystem_usage_rg"
instanceName=$(curl -s -L http://169.254.169.254/opc/v1/instance/ | jq -r '.displayName')
instanceId=$(curl -s -L http://169.254.169.254/opc/v1/instance/ | jq -r '.id')
endpointRegion=$(curl -s -L http://169.254.169.254/opc/v1/instance/ | jq -r '.canonicalRegionName')
Timestamp=$(date -u '+%Y-%m-%dT%H:%M:%SZ')

# Upload custom metric function
# $1...mountPoint
# $2...Usage
function UploadCustomMetric () {
  metricsJson=$(cat << EOF > ${jsonfile}
[
   {
      "namespace":"${metricNamespace}",
      "compartmentId":"${compartmentId}",
      "resourceGroup":"${metricResourceGroup}",
      "name":"FileSystemUsage",
      "dimensions":{
         "mountPoint":"$1",
         "instanceName":"${instanceName}"
      },
      "metadata":{
         "unit":"Percent",
         "displayName":"FilesystemUsage"
      },
      "datapoints":[
         {
            "timestamp":"${Timestamp}",
            "value":"$2"
         }
      ]
   }
]
EOF
  )
  # for debug.
  cat ${jsonfile};
  echo ${cliLocation} monitoring metric-data post --metric-data file://${jsonfile} --endpoint https://telemetry-ingestion.${endpointRegion}.oraclecloud.com --auth instance_principal
  # Upload custom metric by the OCI CLI. 
  ${cliLocation} monitoring metric-data post --metric-data file://${jsonfile} --endpoint https://telemetry-ingestion.${endpointRegion}.oraclecloud.com --auth instance_principal
}

# Output filesystem information to workfile, xfs or ext4 only, exclude /boot and header.
Timestamp=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
df --type=xfs --type=ext4 | grep -Ev "^Filesystem" > ${workfile}
if [ $? -eq 0 ]
then
  echo "no error df."; 
else
  #If error occured, dummy metric upload.
  UploadCustomMetric error -1;
  # abend.
  echo "error in df."; 
  exit 1;
fi

# Upload custom metric per mountPoint.
IFS=$'\n'
for line in $(cat ${workfile})
do
  Usage=$(echo $line | awk '{print $5}' | sed 's/%//')
  mountPoint=$(echo $line | awk '{print $6}')
  # for debug.
  echo ${Usage}
  echo ${mountPoint}
  # Call upload custom metric function.
  UploadCustomMetric "${mountPoint}" "${Usage}"
done

# Successful completion.
exit 0;
```

dfコマンドで取得したマウント・ポイントと使用率をJSONに加工して OCI CLI でアップロードしています。
xfs と ext4 を対象としています。nfs等は含んでいません。また /boot は取得対象から除外しています。
冒頭の curl ではインスタンスのメタデータを取得しています。下記マニュアルを参照して下さい。

> インスタンス・メタデータの取得
> https://docs.oracle.com/ja-jp/iaas/Content/Compute/Tasks/gettingmetadata.htm


# 4. シェルスクリプトの動作確認

シェルスクリプトに実行権限を付与して動作確認します。

```shell
chmod 750 OCIFileSystemUsage.sh
./OCIFileSystemUsage.sh
```

実行結果のサンプルは以下の通りとなります。

```shell
[opc@ays-prv-compute03 scripts]$ ./OCIFileSystemUsage.sh
no error df.
30
/
[
   {
      "namespace":"compute_filesystem_usage",
      "compartmentId":"ocid1.compartment.oc1..xxxxxxxxxx",
      "resourceGroup":"compute_filesystem_usage_rg",
      "name":"FileSystemUsage",
      "dimensions":{
         "mountPoint":"/",
         "instanceName":"ays-prv-compute03"
      },
      "metadata":{
         "unit":"Percent",
         "displayName":"FilesystemUsage"
      },
      "datapoints":[
         {
            "timestamp":"2024-02-28T14:51:49Z",
            "value":"30"
         }
      ]
   }
]
/usr/bin/oci monitoring metric-data post --metric-data file:///home/opc/scripts/filesystemusage_work.json --endpoint https://telemetry-ingestion.us-phoenix-1.oraclecloud.com --auth instance_principal
{
  "data": {
    "failed-metrics": [],
    "failed-metrics-count": 0
  }
}
3
/var/oled
[
   {
      "namespace":"compute_filesystem_usage",
      "compartmentId":"ocid1.compartment.oc1..xxxxxxxxxx",
      "resourceGroup":"compute_filesystem_usage_rg",
      "name":"FileSystemUsage",
      "dimensions":{
         "mountPoint":"/var/oled",
         "instanceName":"ays-prv-compute03"
      },
      "metadata":{
         "unit":"Percent",
         "displayName":"FilesystemUsage"
      },
      "datapoints":[
         {
            "timestamp":"2024-02-28T14:51:49Z",
            "value":"3"
         }
      ]
   }
]
/usr/bin/oci monitoring metric-data post --metric-data file:///home/opc/scripts/filesystemusage_work.json --endpoint https://telemetry-ingestion.us-phoenix-1.oraclecloud.com --auth instance_principal
{
  "data": {
    "failed-metrics": [],
    "failed-metrics-count": 0
  }
}
```

# 5. crontab による定期実行設定と実行結果確認

crontab で定期実行を設定します。下記を opcユーザー の crontab に設定して10分毎に実行しています。

```shell
0,10,20,30,40,50 * * * * /home/opc/scripts/OCIFileSystemUsage.sh > /home/opc/scripts/OCIFileSystemUsage.log 2>&1
```

定期実行が完了すると /home/opc/scripts配下に crontab の標準出力がリダイレクトされた結果が出力されています。

```shell
[opc@ays-prv-compute03 scripts]$ ls -la
total 16
drwxrwxr-x. 2 opc opc  130 Feb 28 15:02 .
drwx------. 4 opc opc  126 Feb 28 14:51 ..
-rw-rw-r--. 1 opc opc  582 Feb 28 15:00 filesystemusage_work.json
-rw-rw-r--. 1 opc opc  134 Feb 28 15:00 filesystemusage_work.txt
-rw-r--r--. 1 opc opc 1739 Feb 28 15:00 OCIFileSystemUsage.log
-rwxr-x---. 1 opc opc 3080 Feb 28 14:51 OCIFileSystemUsage.sh
```

failed-metric-count が 0 であれば実行は成功しています。

```shell
[opc@ays-prv-compute03 scripts]$ grep failed-metrics OCIFileSystemUsage.log
    "failed-metrics": [],
    "failed-metrics-count": 0
    "failed-metrics": [],
    "failed-metrics-count": 0
[opc@ays-prv-compute03 scripts]$
```

# 6. メトリック・エクスプローラーによるカスタム・メトリックの確認
しばらくした後にOCIコンソールにログインしてカスタム・メトリックを確認します。画面左上のハンバーガーメニュー ⇒ Observability＆Management ⇒ Monitoring ⇒ Metric Explorer でメトリック・エクスプローラーの画面に遷移します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110066/c7a5a966-3cbf-ecf8-2c18-9907b10a4e1e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110066/072c0dae-32c6-3576-55d5-4e6e4ceeae68.png)

以下を選択して「Update Chart」ボタンをクリックします。

|名前|プルダウン|
|--|--|
|Metric Namespace|compute_filesystem_usage|
|Resource Group|compute_filesystem_usage_rg|
|Metric name|FileSystemUsage|
|Interval|15 minutes|

結果は以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110066/16583840-981f-3427-680f-88d962f7fa45.png)

ファイルシステム使用率がメトリックとしてアップロードされている事が確認できました。
彡(^)(^)

# 7. まとめ
OCI CLI とシェルでファイルシステム使用率をカスタム・メトリックとして取得できました。
長年触った言語はやはり実装時の安定感がありますやね彡(^)(^)

# Appendix. 参考情報
シェルスクリプトは下記の記事を参考にさせて頂きました。

https://qiita.com/itokazu/items/351b153c56fd2127c768