コマンドラインでOCIのコスト状況を把握する

## コスト分析

テナンシでのコストや使用量の状況を把握するには、OCIコンソールの「コスト分析」を使うとグラフィカルに分析することができて便利です。

コスト分析を利用すると、どのサービスでいくらかかっているのか、どのコンパートメントでどの程度のコストを消費しているのか、などを都度GUIで条件を変えながら分析していくことが可能です。

![image-20241224143102831.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524827/95e23c45-592b-508f-8422-64bd0dd43c78.png)


表示する際には、日付範囲指定での絞り込み、粒度（月次/日次/時間）、グループ化とフィルタリング（テナンシ/コンパートメント/タグ/サービス/SKU/リソースOCIDなど）の条件を自由に変更して分析することができます。また、それらをレポートとして保存することも可能です。また、コストだけでなく使用量の表示や将来の予測もできます。

![image-20241224143049693.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524827/1aa23832-b201-56a1-065a-eacaf538288a.png)




## コマンドラインでの取得

ですが、例えば取得した数値を加工して利用したい場合や定期実行したい場合などには、GUIではなくてコマンドラインから同様の結果を取得したい場合もあります。そんなときには、OCI CLIを利用すると便利です。

以下のコマンドがコスト分析のコマンドになります。

```
oci usage-api usage-summary request-summarized-usages [OPTIONS]
```

コマンドライン・リファレンスはこちら。オプションの詳細などは、コマンドヘルプやリファレンスも参考にして使っていきましょう。

https://docs.oracle.com/en-us/iaas/tools/oci-cli/3.51.0/oci_cli_docs/cmdref/usage-api/usage-summary/request-summarized-usages.html

また、以下のAPIの使用方法もパラメータの記述方法などの参考になります。

https://docs.oracle.com/ja-jp/iaas/Content/Billing/Concepts/costanalysisoverview.htm#cost_analysis_using_the_api



必ず必要な必須パラメータは以下の4つです。

```
--granularity [text]
--tenant-id [text]
--time-usage-ended [datetime]
--time-usage-started [datetime]
```

まずは、必須パラメータだけ指定して合計のコストを表示してみます。2024-01-01～2024-02-01で、粒度はMONTHLYにしました。

ここではdatetimeフォーマットをYYYY-MM-DDで指定しているので、時刻は00:00:00+00:00を指すことになります。

```
tomoko_kon@cloudshell:~ (us-ashburn-1)$ export tenant_id="ocid1.tenancy.oc1..aaaaa <略> "
tomoko_kon@cloudshell:~ (us-ashburn-1)$ oci usage-api usage-summary request-summarized-usages \
> --tenant-id $tenant_id \
> --time-usage-started "2024-01-01" \
> --time-usage-ended "2024-02-01" \
> --granularity MONTHLY 
{
  "data": {
    "group-by": null,
    "items": [
      {
        "ad": null,
        "attributed-cost": null,
        "attributed-usage": null,
        "compartment-id": null,
        "compartment-name": null,
        "compartment-path": null,
        "computed-amount": 0.0,
        "computed-quantity": 0.0,
        "currency": " ",
        "discount": null,
        "is-forecast": false,
        "list-rate": null,
        "overage": null,
        "overages-flag": null,
        "platform": null,
        "region": null,
        "resource-id": null,
        "resource-name": null,
        "service": null,
        "shape": null,
        "sku-name": null,
        "sku-part-number": null,
        "subscription-id": null,
        "tags": [
          {
            "key": null,
            "namespace": null,
            "value": null
          }
        ],
        "tenant-id": null,
        "tenant-name": null,
        "time-usage-ended": "2024-02-01T00:00:00+00:00",
        "time-usage-started": "2024-01-01T00:00:00+00:00",
        "unit": null,
        "unit-price": null,
        "weight": null
      },
      {
        "ad": null,
        "attributed-cost": null,
        "attributed-usage": null,
        "compartment-id": null,
        "compartment-name": null,
        "compartment-path": null,
        "computed-amount": 906259.1930236255,
        "computed-quantity": 615889.3735594321,
        "currency": "JPY",
        "discount": null,
        "is-forecast": false,
        "list-rate": null,
        "overage": null,
        "overages-flag": null,
        "platform": null,
        "region": null,
        "resource-id": null,
        "resource-name": null,
        "service": null,
        "shape": null,
        "sku-name": null,
        "sku-part-number": null,
        "subscription-id": null,
        "tags": [
          {
            "key": null,
            "namespace": null,
            "value": null
          }
        ],
        "tenant-id": null,
        "tenant-name": null,
        "time-usage-ended": "2024-02-01T00:00:00+00:00",
        "time-usage-started": "2024-01-01T00:00:00+00:00",
        "unit": null,
        "unit-price": null,
        "weight": null
      }
    ]
  }
}
tomoko_kon@cloudshell:~ (us-ashburn-1)$ 
```



"computed-amount"というのが計算されたコストとなっていて、 約906259円 であることがわかります。





## コマンドラインのオプションで検索条件を変更する

続いて、オプションのパラメータを利用して検索条件を変えて実行してみます。

オプションとして以下のようなパラメータがあります。

```
--compartment-depth [float]
--filter [complex type]
--forecast [complex type]
--from-json [text]
--group-by [complex type]
--group-by-tag [complex type]
--is-aggregate-by-time [boolean]
--limit [integer]
--page [text]
--query-type [text]
```

complex typeとなっているパラメーターはJSON形式で引き渡す必要があります。どのような形式のJSONを用意すればいいかわからない場合は、`--generate-param-json-input` を利用すると入力用JSONのサンプルを取得できます。

- `--filter` オプション用のJSONを表示するためのコマンド例

```
tomoko_kon@cloudshell:~ (us-ashburn-1)$ oci usage-api usage-summary request-summarized-usages --generate-param-json-input filter
{
  "dimensions": [
    {
      "key": "string",
      "value": "string"
    },
    {
      "key": "string",
      "value": "string"
    }
  ],
  "filters": [
    null,
    null
  ],
  "operator": "string",
  "tags": [
    {
      "key": "string",
      "namespace": "string",
      "value": "string"
    },
    {
      "key": "string",
      "namespace": "string",
      "value": "string"
    }
  ]
}
tomoko_kon@cloudshell:~ (us-ashburn-1)$ 
```

- filterのパラメータ用のjsonファイルを用意する

filterのパラメータは若干複雑ですが、上記のサンプルを参考にここでは以下のような形式でファイルとして用意しました。tkonishi_compartmentという名前のコンパートメントのみに絞り込むためのフィルターです。

```
tomoko_kon@cloudshell:~ (us-ashburn-1)$ cat filter.json 
{
  "operator": "AND",
  "dimensions": [
    {
      "key": "compartmentName",
      "value": "tkonishi_compartment"
    }
  ],
  "tags": [],
  "filters": null
}
tomoko_kon@cloudshell:~ (us-ashburn-1)$ 
```

- フィルター条件を付けて実行。ここでは、2024-10-01～2024-11-30の期間で、tkonishi_compartmentのコンパートメントだけに絞ってMONTHLY粒度の結果を取得します。

```
tomoko_kon@cloudshell:~ (us-ashburn-1)$ oci usage-api usage-summary request-summarized-usages \
> --tenant-id $tenant_id \
> --time-usage-started "2024-10-01" \
> --time-usage-ended "2024-11-30" \
> --granularity MONTHLY \
> --filter file://filter.json 
{
  "data": {
    "group-by": null,
    "items": [
      {
        "ad": null,
        "attributed-cost": "329.402885213552",
        "attributed-usage": "550.043889651752",
        "compartment-id": null,
        "compartment-name": null,
        "compartment-path": null,
        "computed-amount": 329.402885213552,
        "computed-quantity": 550.043889651752,
        "currency": "JPY",
        "discount": null,
        "is-forecast": false,
        "list-rate": null,
        "overage": null,
        "overages-flag": null,
        "platform": null,
        "region": null,
        "resource-id": null,
        "resource-name": null,
        "service": null,
        "shape": null,
        "sku-name": null,
        "sku-part-number": null,
        "subscription-id": null,
        "tags": [
          {
            "key": null,
            "namespace": null,
            "value": null
          }
        ],
        "tenant-id": null,
        "tenant-name": null,
        "time-usage-ended": "2024-11-01T00:00:00+00:00",
        "time-usage-started": "2024-10-01T00:00:00+00:00",
        "unit": null,
        "unit-price": null,
        "weight": null
      },
      {
        "ad": null,
        "attributed-cost": "503.25361936005",
        "attributed-usage": "521.832951135236",
        "compartment-id": null,
        "compartment-name": null,
        "compartment-path": null,
        "computed-amount": 503.25361936005,
        "computed-quantity": 521.832951135236,
        "currency": "JPY",
        "discount": null,
        "is-forecast": false,
        "list-rate": null,
        "overage": null,
        "overages-flag": null,
        "platform": null,
        "region": null,
        "resource-id": null,
        "resource-name": null,
        "service": null,
        "shape": null,
        "sku-name": null,
        "sku-part-number": null,
        "subscription-id": null,
        "tags": [
          {
            "key": null,
            "namespace": null,
            "value": null
          }
        ],
        "tenant-id": null,
        "tenant-name": null,
        "time-usage-ended": "2024-11-30T00:00:00+00:00",
        "time-usage-started": "2024-11-01T00:00:00+00:00",
        "unit": null,
        "unit-price": null,
        "weight": null
      }
    ]
  }
}
tomoko_kon@cloudshell:~ (us-ashburn-1)$ 
```

- さらにグループ化のオプション `--group-by` を利用して、サービスごとにグループ化した値を取得してみます。group-byの値もJSON形式で用意します。複数項目を指定することもできますが、今回はサービスごとのグループ化のみ行います。

```
tomoko_kon@cloudshell:~ (us-ashburn-1)$ cat groupby.json 
[
  "service"
]
tomoko_kon@cloudshell:~ (us-ashburn-1)$ oci usage-api usage-summary request-summarized-usages \
> --tenant-id $tenant_id \
> --time-usage-started "2024-10-01" \
> --time-usage-ended "2024-11-30" \
> --granularity MONTHLY \
> --filter file://filter.json \
> --group-by file://groupby.json \
> --compartment-depth 1 

{
  "data": {
    "group-by": [
      "service"
    ],
    "items": [
      {
        "ad": null,
        "attributed-cost": "308.124999999072",
        "attributed-usage": "514.516129031592",
        "compartment-id": null,
        "compartment-name": null,
        "compartment-path": null,
        "computed-amount": 308.124999999072,
        "computed-quantity": 514.516129031592,
        "currency": "JPY",
        "discount": null,
        "is-forecast": false,
        "list-rate": null,
        "overage": null,
        "overages-flag": null,
        "platform": null,
        "region": null,
        "resource-id": null,
        "resource-name": null,
        "service": "Block Storage",　←ブロック・ストレージでのコスト
        "shape": null,
        "sku-name": null,
        "sku-part-number": null,
        "subscription-id": null,
        "tags": [
          {
            "key": null,
            "namespace": null,
            "value": null
          }
        ],
        "tenant-id": null,
        "tenant-name": null,
        "time-usage-ended": "2024-11-30T00:00:00+00:00",
        "time-usage-started": "2024-11-01T00:00:00+00:00",
        "unit": null,
        "unit-price": null,
        "weight": null
      },
      {
        "ad": null,
        "attributed-cost": "0.027885214544",
        "attributed-usage": "0.043889652464",
        "compartment-id": null,
        "compartment-name": null,
        "compartment-path": null,
        "computed-amount": 0.027885214544,
        "computed-quantity": 0.043889652464,
        "currency": "JPY",
        "discount": null,
        "is-forecast": false,
        "list-rate": null,
        "overage": null,
        "overages-flag": null,
        "platform": null,
        "region": null,
        "resource-id": null,
        "resource-name": null,
        "service": "Object Storage",　←オブジェクト・ストレージでのコスト
        "shape": null,
        "sku-name": null,
        "sku-part-number": null,
        "subscription-id": null,
        "tags": [
          {
            "key": null,
            "namespace": null,
            "value": null
          }
        ],
        "tenant-id": null,
        "tenant-name": null,
        "time-usage-ended": "2024-11-01T00:00:00+00:00",
        "time-usage-started": "2024-10-01T00:00:00+00:00",
        "unit": null,
        "unit-price": null,
        "weight": null
      },
      
      ＜以下、略＞
```

無事、グループ化の条件で指定したサービスごとの値が取得できました。

<BR>


## 出力結果を絞り込む
（2025/01/20 追記）

出力結果がJSON形式のままだと見にくいので、JMESPathを使って出力を絞り込みます。
結果のJSONの構造は、以下のような形になっています。結果はitemsの下に出力されます。
```
{
  "data": {
    "group-by": [
      <<略>>
    ],
    "items": [
      {
　　　　<<略>>
      },
      {
　　　　<<略>>
      },
      {
        <<略>>
      }
    ]
  }
}
```
つまり、--queryパラメーターでJMESpath検索を行って、itemの配列の中の特定の要素を取り出したい場合は以下のようになります。
```
--query "data.items[*].[<表示したい項目>,<表示したい項目>]" 
```

- 今回はfilterとgroupbyのパラメーターを以下のように用意し、特定のコンパートメントに絞って、サービスごとの値を出力します。
```
tkonishi@cloudshell:~ (us-ashburn-1)$ cat filter.json
{
  "operator": "AND",
  "dimensions": [
    {
      "key": "compartmentName",
      "value": "tomoko.konishi"
    }
  ],
  "tags": [],
  "filters": null
}
tkonishi@cloudshell:~ (us-ashburn-1)$
tkonishi@cloudshell:~ (us-ashburn-1)$ cat groupby.json 
[
  "service"
]
tkonishi@cloudshell:~ (us-ashburn-1)$
```

- 例えば、サービス名とattributed-costの要素を取り出す場合は以下のようになります。
```
tkonishi@cloudshell:~ (us-ashburn-1)$ oci usage-api usage-summary request-summarized-usages \
> --tenant-id $tenant_id \
> --time-usage-started "2024-10-01" \
> --time-usage-ended "2024-10-30" \
> --granularity MONTHLY \
> --filter file://filter.json \
> --group-by file://groupby.json \
> --query "data.items[*].[service,\"attributed-cost\"]"
[
  [
    "Logging",
    "32.931201655992"
  ],
  [
    "Notifications",
    "0.0248"
  ],
  [
    "Functions",
    "0"
  ],
  [
    "Object Storage",
    "0"
  ],
  [
    "Block Storage",
    "1687.315874689745"
  ],
  [
    "Compute",
    "3150.795383718086"
  ],
  [
    "Load Balancer",
    "1319.453000000003"
  ],
  [
    "Telemetry",
    "0.0161696"
  ],
  [
    "Object Storage",
    "341.037613474621"
  ],
  [
    "Virtual Cloud Network",
    "0"
  ]
]
tkonishi@cloudshell:~ (us-ashburn-1)$ 
```

- さらに表形式で出力する場合は --output table オプションを使用します。かなり見やすくなりました！
```
tkonishi@cloudshell:~ (us-ashburn-1)$ oci usage-api usage-summary request-summarized-usages \
> --tenant-id $tenant_id \
> --time-usage-started "2024-10-01" \
> --time-usage-ended "2024-10-30" \
> --granularity MONTHLY \
> --filter file://filter.json \
> --group-by file://groupby.json \
> --query "data.items[*].[service,\"attributed-cost\"]" \
> --output table
+-----------------------+-------------------+
| Column1               | Column2           |
+-----------------------+-------------------+
| Logging               | 32.931201655992   |
| Notifications         | 0.0248            |
| Functions             | 0                 |
| Object Storage        | 0                 |
| Block Storage         | 1687.315874689745 |
| Compute               | 3150.795383718086 |
| Load Balancer         | 1319.453000000003 |
| Telemetry             | 0.0161696         |
| Object Storage        | 341.037613474621  |
| Virtual Cloud Network | 0                 |
+-----------------------+-------------------+
tkonishi@cloudshell:~ (us-ashburn-1)$ 
tkonishi@cloudshell:~ (us-ashburn-1)$ 
```

<BR>
<BR>

ということで、コスト分析のコンソールのUIで実施できる分析はコマンドラインでも実施可能でした。