Autonomous Databaseに自身のメトリックデータをCSV形式でObject Storageに出力させる

# はじめに

Autonomous Databaseで利用可能なPL/SQL SDKを使用して、Autonomous DatabaseからOCI MonitoringにアクセスしてAutonomous Database自身のメトリック・データを取得し、CSV形式でのObject Storageに出力することができるか検証してみました。

:::note warn
注意
こちらの記事の内容はあくまで個人の実験メモ的な内容のため、こちらの内容を利用した場合のトラブルには一切責任を負いません。
また、こちらの記事の内容を元にしたOracleサポートへの問い合わせはご遠慮ください。
:::
# 1. 事前準備

メトリック・データの出力先となるOCI Object Storageのバケットを作成します。
ここでは、bucket_testという名前のバケットを作成しました。

![スクリーンショット 2025-03-05 13.00.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/8ec99813-cf1d-4f38-b79e-ad8939accebc.png)

# 2. リソース・プリンシパルの有効化
リソース・プリンシパルを使用すると、Autonomous Databaseに対して、OCIリソースに対するアクセスを許可することができます。
リソース・プリンシパルを使用する手順は、以下の通りです。

1.対象となるAutonomous Databaseを含む動的グループを作成
2.動的グループに対して、OCIリソースへのアクセスを許可するポリシーを作成
3.adminユーザとしてAutonomous Databaseに接続し、リソース・プリンシパルを有効化

まずはじめに、使用するAutonomous Databaseを含む動的グループを作成します。
ここでは、「ADB-dg」という名前の動的グループを作成しました。
一致ルールには、単一のAutonomous Databaseにマッチするルールを以下のように設定しました
```
All {resource.id = 'Autonomous DatabaseのOCID'}
```
![スクリーンショット 2025-02-26 9.38.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/0ec8ca2d-5931-47f4-ab79-736ce8346e16.png)

![スクリーンショット 2025-02-26 9.39.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/94cee7b2-4ce5-4eb3-aef2-2a3a9ffd90ad.png)


次に、作成した動的グループに対してOCI Monitoringの使用を許可するポリシーを作成します。
ここでは、テナンシ内の全てのストリームの利用を許可するポリシー「ADB-use-Monitoring」をrootコンパートメントに作成しました。
ポリシー・ステートメントは、以下のように設定しました。
```
allow dynamic-group ADB-dg to read metrics in tenancy
```

最後に、adminユーザとしてAutonomous Databaseに接続し、DBMS_CLOUD_ADMIN.ENABLE_RESOURCE_PRINCIPALプロシージャを実行して、リソース・プリンシパルを有効化します。

```
EXEC DBMS_CLOUD_ADMIN.ENABLE_RESOURCE_PRINCIPAL();
```

```
SQL> EXEC DBMS_CLOUD_ADMIN.ENABLE_RESOURCE_PRINCIPAL();

PL/SQL procedure successfully completed.

SQL>
```
adminユーザ以外にリソース・プリンシパルの使用を許可する場合には、リソース・プリンシパルを有効化したあとに、以下のようにユーザ名を指定してDBMS_CLOUD_ADMIN.ENABLE_RESOURCE_PRINCIPALプロシージャを実行します。
```
EXEC DBMS_CLOUD_ADMIN.ENABLE_RESOURCE_PRINCIPAL(username => 'ADBユーザ名');
```

```
SQL> EXEC DBMS_CLOUD_ADMIN.ENABLE_RESOURCE_PRINCIPAL(username => 'adbuser');

PL/SQL procedure successfully completed.

SQL>
```

# 3. メトリック・データを取得してObject Storageに書き出すPL/SQLプロシージャの作成

メトリックのデータポイントを検索する際に使用する時間範囲（開始時間、終了時間）をパラメータに指定して実行すると、OCI Monitoringから指定された時間範囲のメトリック・データ（ここではCPU使用率）を取得し、CSV形式でObject Storageに書き出すプロシージャ「export_metric」を作成します。

各部の処理内容は、ソース内のコメントを参照してください。

::: note info
取得するメトリックの指定
この例では
**CpuUtilization[1m]{resourceId = "'||adb_ocid||'"}.max()**
の部分で、MQLで1分ごとのCPU使用率の最大値を取得するように指定しています。
**CpuUtilization[1m]** の部分を変更することで取得するメトリックと間隔を、**max()** の部分でどのような値を返すかを指定します。
例えば、max()の部分をmean()に変更することで平均値を取得することができます。
:::

```sql:export_metricプロシージャ
CREATE OR REPLACE PROCEDURE export_metric( start_time IN TIMESTAMP WITH TIME ZONE, end_time IN TIMESTAMP WITH TIME ZONE )
IS
    adb_region            VARCHAR2(255);
    adb_ocid              VARCHAR2(255);
    adb_compartment_ocid  VARCHAR2(255);

    summarize_metrics_data_detail    dbms_cloud_oci_monitoring_summarize_metrics_data_details_t := dbms_cloud_oci_monitoring_summarize_metrics_data_details_t();
    summarize_metrics_data_res       dbms_cloud_oci_mn_monitoring_summarize_metrics_data_response_t;
    summarize_metrics_data_res_body  dbms_cloud_oci_monitoring_metric_data_t;

    l_timestamp  TIMESTAMP WITH TIME ZONE;
    l_value      NUMBER;
    l_output     CLOB;

BEGIN
-- ADBのあるリージョン、ADBのコンパートメントのOCID、ADBのOCIDを取得
    SELECT JSON_VALUE(cloud_identity, '$.REGION'), LOWER(JSON_VALUE(cloud_identity, '$.COMPARTMENT_OCID')), LOWER(JSON_VALUE(cloud_identity, '$.DATABASE_OCID'))
      INTO adb_region, adb_compartment_ocid, adb_ocid FROM v$pdbs;

-- メトリックデータ（CPU利用率）を取得するためのパラメータをセット
    summarize_metrics_data_detail.namespace  := 'oci_autonomous_database';
    summarize_metrics_data_detail.query      := 'CpuUtilization[1m]{resourceId = "'||adb_ocid||'"}.max()';
    summarize_metrics_data_detail.start_time := start_time;
    summarize_metrics_data_detail.end_time   := end_time;

-- メトリックデータの取得
    summarize_metrics_data_res := DBMS_CLOUD_OCI_MN_MONITORING.SUMMARIZE_METRICS_DATA(
                                      compartment_id => adb_compartment_ocid,
                                      summarize_metrics_data_details => summarize_metrics_data_detail,
                                      region => adb_region,
                                      credential_name => 'OCI$RESOURCE_PRINCIPAL'
                                  );
    summarize_metrics_data_res_body := summarize_metrics_data_res.response_body(1);

-- 取得したメトリックデータのデータポイントの数だけループし、各データポイントのタイムスタンプと値を変数l_outputに追記
    FOR i IN summarize_metrics_data_res_body.aggregated_datapoints.first..summarize_metrics_data_res_body.aggregated_datapoints.last LOOP
	    l_timestamp   := summarize_metrics_data_res_body.aggregated_datapoints(i).l_timestamp;
		l_value       := summarize_metrics_data_res_body.aggregated_datapoints(i).value;
        DBMS_OUTPUT.PUT_LINE(FROM_TZ(l_timestamp,'+0:00') AT TIME ZONE '+9:00'||'  '||TO_CHAR(l_value,'90.999999999999999999'));
		l_output      := l_output||TO_CHAR(FROM_TZ(l_timestamp,'+0:00') AT TIME ZONE '+9:00')||','||TO_CHAR(l_value,'90.999999999999999999')||CHR(13)||CHR(10);
    END LOOP;

-- 変数outputの内容をオブジェクト・ストレージに出力
    DBMS_CLOUD.PUT_OBJECT(
        credential_name => 'OCI$RESOURCE_PRINCIPAL',
        object_uri => 'https://＜ネームスペース＞.objectstorage.ap-osaka-1.oci.customer-oci.com/n/＜ネームスペース＞/b/bucket_test/o/cpu_util.csv',
        contents => APEX_UTIL.CLOB_TO_BLOB( p_clob => l_output, p_charset => 'AL32UTF8' )
    ); 
END;
/
```

```
SQL> CREATE OR REPLACE PROCEDURE export_metric( start_time IN TIMESTAMP WITH TIME ZONE, end_time IN TIMESTAMP WITH TIME ZONE )
  2  IS
  3  	 adb_region	       VARCHAR2(255);
  4  	 adb_ocid	       VARCHAR2(255);
  5  	 adb_compartment_ocid  VARCHAR2(255);
  6  
  7  	 summarize_metrics_data_detail	  dbms_cloud_oci_monitoring_summarize_metrics_data_details_t := dbms_cloud_oci_monitoring_summarize_metrics_data_details_t();
  8  	 summarize_metrics_data_res	  dbms_cloud_oci_mn_monitoring_summarize_metrics_data_response_t;
  9  	 summarize_metrics_data_res_body  dbms_cloud_oci_monitoring_metric_data_t;
 10  
 11  	 l_timestamp  TIMESTAMP WITH TIME ZONE;
 12  	 l_value      NUMBER;
 13  	 l_output     CLOB;
 14  
 15  BEGIN
 16  
 17  	 SELECT JSON_VALUE(cloud_identity, '$.REGION'), LOWER(JSON_VALUE(cloud_identity, '$.COMPARTMENT_OCID')), LOWER(JSON_VALUE(cloud_identity, '$.DATABASE_OCID'))
 18  	   INTO adb_region, adb_compartment_ocid, adb_ocid FROM v$pdbs;
 19  
 20  	 summarize_metrics_data_detail.namespace  := 'oci_autonomous_database';
 21  	 summarize_metrics_data_detail.query	  := 'CpuUtilization[1m]{resourceId = "'||adb_ocid||'"}.max()';
 22  	 summarize_metrics_data_detail.start_time := start_time;
 23  	 summarize_metrics_data_detail.end_time   := end_time;
 24  
 25  	 summarize_metrics_data_res := DBMS_CLOUD_OCI_MN_MONITORING.SUMMARIZE_METRICS_DATA(
 26  					   compartment_id => adb_compartment_ocid,
 27  					   summarize_metrics_data_details => summarize_metrics_data_detail,
 28  					   region => adb_region,
 29  					   credential_name => 'OCI$RESOURCE_PRINCIPAL'
 30  				       );
 31  	 summarize_metrics_data_res_body := summarize_metrics_data_res.response_body(1);
 32  
 33  	 FOR i IN summarize_metrics_data_res_body.aggregated_datapoints.first..summarize_metrics_data_res_body.aggregated_datapoints.last LOOP
 34  		 l_timestamp   := summarize_metrics_data_res_body.aggregated_datapoints(i).l_timestamp;
 35  		     l_value	   := summarize_metrics_data_res_body.aggregated_datapoints(i).value;
 36  	     DBMS_OUTPUT.PUT_LINE(FROM_TZ(l_timestamp,'+0:00') AT TIME ZONE '+9:00'||'	'||TO_CHAR(l_value,'90.999999999999999999'));
 37  		     l_output	   := l_output||TO_CHAR(FROM_TZ(l_timestamp,'+0:00') AT TIME ZONE '+9:00')||','||TO_CHAR(l_value,'90.999999999999999999')||CHR(13)||CHR(10);
 38  	 END LOOP;
 39  
 40  	 DBMS_CLOUD.PUT_OBJECT(
 41  	     credential_name => 'OCI$RESOURCE_PRINCIPAL',
 42  	     object_uri => 'https://xxxxxxxx.objectstorage.ap-osaka-1.oci.customer-oci.com/n/xxxxxxxx/b/bucket_test/o/cpu_util.csv',
 43  	     contents => APEX_UTIL.CLOB_TO_BLOB( p_clob => l_output, p_charset => 'AL32UTF8' )
 44  	 );
 45  
 46  END;
 47  /

Procedure created.

SQL> 
```

PL/SQLプロシージャ「export_metric」が作成できました。

# 4. PL/SQLプロシージャの動作確認

メトリックのデータポイントを検索する際に使用する時間範囲（開始時間、終了時間）をパラメータに指定してプロシージャ「export_metric」を実行してみます。

ここでは、開始時間として「04-MAR-25 01:00.00 AM +09:00」、終了時間として「04-MAR-25 01:59.59 AM +09:00」をを指定して実行しました。

```
SQL> EXEC export_metric('04-MAR-25 01:00.00 AM +09:00','04-MAR-25 01:59.59 AM +09:00');
04-MAR-25 01.00.00.000000000 AM +09:00	  0.043385726891683330
04-MAR-25 01.01.00.000000000 AM +09:00	  0.011924222369291866
04-MAR-25 01.02.00.000000000 AM +09:00	  0.039657341499751670
04-MAR-25 01.03.00.000000000 AM +09:00	  0.035015400410677670
04-MAR-25 01.04.00.000000000 AM +09:00	  0.012186000330961433
04-MAR-25 01.05.00.000000000 AM +09:00	  0.035091290198025336
04-MAR-25 01.06.00.000000000 AM +09:00	  0.011695354739048867
04-MAR-25 01.07.00.000000000 AM +09:00	  2.079555517516833400
04-MAR-25 01.08.00.000000000 AM +09:00	  0.012968172541232267
04-MAR-25 01.09.00.000000000 AM +09:00	  0.034363345470594664
04-MAR-25 01.10.00.000000000 AM +09:00	  0.013926404060465634
04-MAR-25 01.11.00.000000000 AM +09:00	  0.097125048265210330
04-MAR-25 01.12.00.000000000 AM +09:00	  0.014423142759329000
04-MAR-25 01.13.00.000000000 AM +09:00	  0.012655853470153368
04-MAR-25 01.14.00.000000000 AM +09:00	  0.033792266534282000
04-MAR-25 01.15.00.000000000 AM +09:00	  0.012097396867416734
04-MAR-25 01.16.00.000000000 AM +09:00	  0.037825281939067330
04-MAR-25 01.17.00.000000000 AM +09:00	  0.019294065740127965
04-MAR-25 01.18.00.000000000 AM +09:00	  0.012801037012521367
04-MAR-25 01.19.00.000000000 AM +09:00	  0.015361952861952867
04-MAR-25 01.20.00.000000000 AM +09:00	  0.016177005789909000
04-MAR-25 01.21.00.000000000 AM +09:00	  0.014775608661505667
04-MAR-25 01.22.00.000000000 AM +09:00	  1.833362021405716700
04-MAR-25 01.23.00.000000000 AM +09:00	  0.015393357607856133
04-MAR-25 01.24.00.000000000 AM +09:00	  0.051891778303125670
04-MAR-25 01.25.00.000000000 AM +09:00	  0.060095443010040670
04-MAR-25 01.26.00.000000000 AM +09:00	  0.015145047429958100
04-MAR-25 01.27.00.000000000 AM +09:00	  0.013211429201831333
04-MAR-25 01.28.00.000000000 AM +09:00	  0.012831479897348166
04-MAR-25 01.29.00.000000000 AM +09:00	  0.034398102173673330
04-MAR-25 01.30.00.000000000 AM +09:00	  0.012298146922567834
04-MAR-25 01.31.00.000000000 AM +09:00	  0.040237189034144330
04-MAR-25 01.32.00.000000000 AM +09:00	  0.012023060796645700
04-MAR-25 01.33.00.000000000 AM +09:00	  0.152554623766330000
04-MAR-25 01.34.00.000000000 AM +09:00	  0.015451486568481434
04-MAR-25 01.35.00.000000000 AM +09:00	  0.011620056263445300
04-MAR-25 01.36.00.000000000 AM +09:00	  0.035696237448968330
04-MAR-25 01.37.00.000000000 AM +09:00	  1.737871166997573300
04-MAR-25 01.38.00.000000000 AM +09:00	  0.020287733467945466
04-MAR-25 01.39.00.000000000 AM +09:00	  0.011145678195156933
04-MAR-25 01.40.00.000000000 AM +09:00	  0.015791395640762300
04-MAR-25 01.41.00.000000000 AM +09:00	  0.034856811786128000
04-MAR-25 01.42.00.000000000 AM +09:00	  0.018865201344130434
04-MAR-25 01.43.00.000000000 AM +09:00	  0.012458926011688166
04-MAR-25 01.44.00.000000000 AM +09:00	  0.043166280736575000
04-MAR-25 01.45.00.000000000 AM +09:00	  0.013154324154837234
04-MAR-25 01.46.00.000000000 AM +09:00	  0.012927555408534566
04-MAR-25 01.47.00.000000000 AM +09:00	  0.047049162257495670
04-MAR-25 01.48.00.000000000 AM +09:00	  0.013755651119197267
04-MAR-25 01.49.00.000000000 AM +09:00	  0.012735875947779500
04-MAR-25 01.50.00.000000000 AM +09:00	  0.012361731458505667
04-MAR-25 01.51.00.000000000 AM +09:00	  0.011334105448930067
04-MAR-25 01.52.00.000000000 AM +09:00	  1.932325671131690000
04-MAR-25 01.53.00.000000000 AM +09:00	  0.036085543199315666
04-MAR-25 01.54.00.000000000 AM +09:00	  0.034933840555739330
04-MAR-25 01.55.00.000000000 AM +09:00	  0.014431761786600500
04-MAR-25 01.56.00.000000000 AM +09:00	  0.033545113611295000
04-MAR-25 01.57.00.000000000 AM +09:00	  0.018842401190673066
04-MAR-25 01.58.00.000000000 AM +09:00	  0.012520241760748100
04-MAR-25 01.59.00.000000000 AM +09:00	  0.011698092402690466

PL/SQL procedure successfully completed.

SQL>
```
プロシージャ「export_metric」が問題なく実行できました。

バケット「bucket_test」のオブジェクトの表示をリフレッシュします。
![スクリーンショット 2025-03-05 13.01.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/390dc238-6a81-4fb3-b389-38968a44a669.png)

バケット「bucket_test」内にファイル「cpu_util.csv」が作成されていることが確認できました。
![スクリーンショット 2025-03-05 13.02.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/bfd55792-e3dc-470e-b504-e3c5c3fc3495.png)

ファイル「cpu_util.csv」をダウンロードし、テキストエディタで開いてみます。
![スクリーンショット 2025-03-05 13.03.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/3c280fca-de43-4c2d-8973-a4426d4deb5e.png)

Autonomous Databaseのメトリックデータ（CPU使用率）がCSV形式でObject Storageに出力されていることが確認できました。

# 参考情報
・[Obtain Tenancy Details](https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/adbsb/autonomous-database-support-ocid.html#GUID-C2B866BD-379D-46AA-9277-DC78F974FAD2)
・[BMS_CLOUD_OCI_MN_MONITORING.SUMMARIZE_METRICS_DATA Function](https://docs.oracle.com/en-us/iaas/Content/pl-sql-sdk/doc/dbms_cloud_oci_mn_monitoring.html#ADSDK-GUID-969FC89C-4878-47BA-851D-584F82B56B1B)
・[DBMS_CLOUD_OCI_MONITORING_SUMMARIZE_METRICS_DATA_DETAILS_T Type](https://docs.oracle.com/en-us/iaas/Content/pl-sql-sdk/doc/monitoring_t.html#ADSDK-GUID-556580A0-3D34-4F04-86FB-D8B3DA920649)
・[DBMS_CLOUD_OCI_MN_MONITORING_SUMMARIZE_METRICS_DATA_RESPONSE_T Type](https://docs.oracle.com/en-us/iaas/Content/pl-sql-sdk/doc/dbms_cloud_oci_mn_monitoring_t.html#ADSDK-GUID-9A3CBEF0-8F61-40FD-B75F-9B0F17C5C828)
・[DBMS_CLOUD_OCI_MONITORING_METRIC_DATA_TBL Type](https://docs.oracle.com/en-us/iaas/Content/pl-sql-sdk/doc/dbms_cloud_oci_mn_monitoring_t.html#ADSDK-GUID-ED095F05-E1F9-4844-80EF-5B736DEF6C9E)
・[DBMS_CLOUD_OCI_MONITORING_METRIC_DATA_T Type](https://docs.oracle.com/en-us/iaas/Content/pl-sql-sdk/doc/monitoring_t.html#ADSDK-GUID-A2F46864-3635-485E-8FD7-A945CBB0B288)
・[DBMS_CLOUD.PUT_OBJECTプロシージャ](https://docs.oracle.com/ja-jp/iaas/autonomous-database/doc/dbms_cloud-objects-and-files.html#ADBOR-GUID-716F0DE7-C669-477E-8AB8-EA42E41ACB12)