

# データソースへのカスタムコネクタの作成
<a name="CloudWatch_MultiDataSources-Connect-Custom"></a>

 このトピックでは、カスタムデータソースを CloudWatch に接続する方法について説明します。カスタムデータソースは、次の 2 つの方法で CloudWatch に接続できます。
+  CloudWatch に用意されているサンプルのテンプレートを使用します。このテンプレートでは、JavaScript または Python のいずれかを使用できます。テンプレートには、Lambda 関数を作成するときに役立つサンプルの Lambda コードが含まれています。次に、カスタムデータソースに接続するようにテンプレートの Lambda 関数を変更できます。
+  CloudWatch で使用するデータソースコネクタ、データクエリ、時系列の準備を実装する AWS Lambda 関数をゼロから作成します。具体的には、データポイントを必要に応じて事前集約またはマージし、CloudWatch との互換性が確保されるように期間とタイムスタンプを調整するという関数にします。

**Contents**
+ [テンプレートの使用](#CloudWatch_MultiDataSources-Connect-Custom-template)
+ [ゼロからのカスタムデータソースの作成](#CloudWatch_MultiDataSources-Connect-Custom-Lambda)
  + [ステップ 1: 関数を作成する](#MultiDataSources-Connect-Custom-Lambda-Function)
    + [GetMetricData イベント](#MultiDataSources-GetMetricData)
    + [DescribeGetMetricData イベント](#MultiDataSources-DescribeGetMetricData)
    + [CloudWatch アラームに関する重要な考慮事項](#MultiDataSources-Connect-Custom-Lambda-Alarms)
    + [(オプション) AWS Secrets Manager を使用した認証情報の保存](#MultiDataSources-Connect-Custom-Lambda-Secrets)
    + [(オプション) VPC のデータソースへの接続](#MultiDataSources-Connect-Custom-Lambda-VPC)
  + [ステップ 2: Lambda アクセス許可ポリシーを作成する](#MultiDataSources-Connect-Custom-Lambda-Permissions)
  + [ステップ 3: シークレットリソースを Lambda 関数にアタッチする](#MultiDataSources-Connect-Custom-Lambda-tags)

## テンプレートの使用
<a name="CloudWatch_MultiDataSources-Connect-Custom-template"></a>

テンプレートを使用すると、サンプルの Lambda 関数が作成されるので、カスタムコネクタをすばやく構築できます。こうしたサンプル関数には、カスタムコネクタの構築でよくあるシナリオに対応したサンプルコードが用意されています。テンプレートを使用してコネクタを作成したら、Lambda コードを開き、そのコネクタをデータソースへの接続に使用するようにコードを変更できます。

また、テンプレートを使用した場合、CloudWatch が Lambda アクセス許可ポリシーの作成と Lambda 関数へのリソースタグのアタッチを行います。

**テンプレートを使用してカスタムデータソースへのコネクタを作成するには**

1. CloudWatch コンソールの [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/) を開いてください。

1. ナビゲーションペインで **[設定]** を選択します。

1. **[メトリクスのデータソース]** タブを選択します。

1. **[データソースを作成]** を選択します。

1. **[カスタム - 入門ガイドテンプレート]** のラジオボタンを選択し、**[次へ]** を選択します。

1. データソースの名前を入力します。

1. リストされているテンプレートのいずれかを選択します。

1. Node.js または Python を選択します。

1. **[データソースを作成]** を選択します。

   先ほど追加した新しいカスタムソースは、CloudFormation スタックでの作成が完了するまで表示されません。進行状況を確認するには、**[CloudFormation スタックのステータスを見る]** を選択します。あるいは、更新アイコンを選択して、このリストを更新することもできます。

   新しいデータソースがこのリストに表示されたら、コンソールでテストして変更できます。

1. (オプション) コンソールでこのソースのテストデータをクエリする場合は、「[別のデータソースにあるメトリクスのグラフ化](graph_a_metric.md#create-metric-graph-multidatasource)」の手順に従ってください。

1. 必要に応じて Lambda 関数を変更します。

   1. ナビゲーションペインで **[設定]** を選択します。

   1. **[メトリクスのデータソース]** タブを選択します。

   1. 変更するソースに対して **[Lambda コンソールで表示]** を選択します。

   これで、データソースにアクセスするように関数を変更できます。詳細については、「[ステップ 1: 関数を作成する](#MultiDataSources-Connect-Custom-Lambda-Function)」を参照してください。
**注記**  
テンプレートを使用すると、Lambda 関数を記述する際に「[ステップ 2: Lambda アクセス許可ポリシーを作成する](#MultiDataSources-Connect-Custom-Lambda-Permissions)」や「[ステップ 3: シークレットリソースを Lambda 関数にアタッチする](#MultiDataSources-Connect-Custom-Lambda-tags)」の手順に従う必要がありません。テンプレートを使用したため、そのいずれのステップも CloudWatch によって実行されるからです。

## ゼロからのカスタムデータソースの作成
<a name="CloudWatch_MultiDataSources-Connect-Custom-Lambda"></a>

このセクションのステップに従って、CloudWatch をデータソースに接続する Lambda 関数を作成します。

### ステップ 1: 関数を作成する
<a name="MultiDataSources-Connect-Custom-Lambda-Function"></a>

カスタムデータソースコネクタは、CloudWatch の `GetMetricData` イベントをサポートする必要があります。必要に応じて、`DescribeGetMetricData` イベントを実装して、CloudWatch コンソールでユーザーにコネクタの使用方法に関するドキュメントを提供することもできます。また、`DescribeGetMetricData` レスポンスを使用して、CloudWatch カスタムクエリビルダーに使用されるデフォルトを設定することもできます。

CloudWatch には、最初の一歩に役立つサンプルとしてコードスニペットが用意されています。詳細については、[https://github.com/aws-samples/cloudwatch-data-source-samples](https://github.com/aws-samples/cloudwatch-data-source-samples) でサンプルリポジトリを参照してください。

**制約**
+ Lambda からのレスポンスは 6 MB 未満でなければなりません。レスポンスが 6 MB を超える場合、`GetMetricData` レスポンスは Lambda 関数を `InternalError` としてマークし、データは返されません。
+ Lambda 関数は、可視化とダッシュボードの用途では 10 秒以内に、アラームの用途では 4.5 秒以内に実行を完了する必要があります。実行時間がその時間を超えた場合、`GetMetricData` レスポンスは Lambda 関数を `InternalError` としてマークし、データは返されません。
+ Lambda 関数は、エポックタイムスタンプを秒単位で使用して、その出力を送信する必要があります。
+ Lambda 関数がデータを再サンプリングするのではなく CloudWatch ユーザーがリクエストした開始時間と期間の長さに対応しないデータを返した場合、CloudWatch ではそのデータは無視されます。こうした余分なデータは、いずれの可視化やアラームからも破棄されます。開始時刻から終了時刻までの範囲内にないデータも破棄されます。

  例えば、ユーザーが 10:00 から 11:00 まで 5 分間隔でデータを要求した場合、「10:00:00 から 10:04:59 まで」と「10:05:00 から 10:09:59 まで」は有効な時間範囲としてデータが返されます。`10:00 value1`、`10:05 value2` といった時系列を返す必要があります。例えば、関数から `10:03 valueX` が返された場合、10:03 はリクエストされた開始時間と期間に対応していないため、関数はドロップされます。
+ CloudWatch データソースコネクタでは、複数行にわたるクエリはサポートされていません。そうしたクエリを実行するか、そうしたクエリでアラームやダッシュボードウィジェットを作成すると、すべてのラインフィードがスペースに置き換えられます。場合によっては、クエリが無効になることもあります。

#### GetMetricData イベント
<a name="MultiDataSources-GetMetricData"></a>

**リクエストペイロード**

次に、Lambda 関数への入力として送信される `GetMetricData` リクエストペイロードの例を示します。

```
{
  "EventType": "GetMetricData",
  "GetMetricDataRequest": {
    "StartTime": 1697060700,
    "EndTime": 1697061600,
    "Period": 300,
    "Arguments": ["serviceregistry_external_http_requests{host_cluster!=\"prod\"}"] 
  }
}
```
+ **StartTime** - 返されるデータの中で最も古いデータであることを指定するタイムスタンプです。**Type** は、タイムスタンプエポック秒です。
+ **EndTime** - 返されるデータの中で最も新しいデータであることを指定するタイムスタンプです。**Type** は、タイムスタンプエポック秒です。
+ **Period** — メトリクスデータの各集計が表す秒数です。最小値は 60 秒です。**Type** は秒です。
+ **Arguments** - Lambda メトリクス数式に渡す一連の引数です。引数を渡す方法の詳細については、「[Lambda 関数に引数を渡す方法](CloudWatch_MultiDataSources-Custom-Use.md#MultiDataSources-Connect-Custom-Lambda-arguments)」を参照してください。

**レスポンスペイロード**

次に、Lambda 関数から返される `GetMetricData` レスポンスペイロードの例を示します。

```
{
   "MetricDataResults": [
      {
         "StatusCode": "Complete",
         "Label": "CPUUtilization",
         "Timestamps": [ 1697060700, 1697061000, 1697061300 ],
         "Values": [ 15000, 14000, 16000 ]
      }
   ]
}
```

レスポンスペイロードには、`MetricDataResults` フィールドまたは `Error` フィールドのいずれかが含まれ、両方が含まれることはありません。

`MetricDataResults` フィールドは、タイプ `MetricDataResult` の時系列フィールドのリストです。こうした時系列フィールドごとに、以下のフィールドを含めることができます。
+ **StatusCode** - (オプション) `Complete` は、リクエストした時間範囲内のデータポイントがすべて返されたことを示します。`PartialData` は、データポイントが一部不足した状態で返されたことを示します。これを省略した場合、デフォルトは `Complete` です。

  有効な値: `Complete` \$1 `InternalError` \$1 `PartialData` \$1 `Forbidden`
+ **Messages** - オプションのメッセージリストです。どのようなデータが返されたかに関する情報が追加で含まれています。

  Type: `Code` と `Value` の文字列が含まれている [MessageData](https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_MessageData.html) オブジェクトの配列です。
+ **Label** - データに関連付けられている判読可能なラベルです。

  タイプ: 文字列
+ **Timestamps** - エポック時間でフォーマットされた、データポイントのタイムスタンプです。タイムスタンプの数は常に値の数に一致し、`Timestamps[x]` の値は `Values[x`] です。

  Type: タイムスタンプの配列
+ **Values** - メトリクスのデータポイントで、`Timestamps` に対応しています。値の数は常にタイムスタンプの数に一致し、`Timestamps[x]` の値は `Values[x`] です。

  Type: 倍精度の配列

`Error` オブジェクトの詳細については、以下のセクションを参照してください。

**エラーレスポンス形式**

必要に応じて、エラーレスポンスを使用してエラーの詳しい情報を提供できます。パラメータの欠落やパラメータの型の誤りなど検証エラーが発生した場合には、コード検証を使用してエラーを返すことをお勧めします。

次に、Lambda 関数で `GetMetricData` 検証例外が発生した場合のレスポンスの例を示します。

```
{
   "Error": {
      "Code": "Validation",
      "Value": "Invalid Prometheus cluster"
   }
}
```

次に、アクセスの問題があるために Lambda 関数がデータを返すことができない場合のレスポンスの例を示します。レスポンスは単一の時系列に変換され、`Forbidden` というステータスコードが返されます。

```
{
   "Error": {
      "Code": "Forbidden",
      "Value": "Unable to access ..."
   }
}
```

次に、Lambda 関数で全体的な `InternalError` 例外が発生した場合のレスポンスの例を示します。レスポンスは単一の時系列に変換され、`InternalError` というステータスコードとメッセージが返されます。エラーコードに `Validation` や `Forbidden` 以外の値があるたびに、CloudWatch では汎用的な内部エラーが発生したと見なされます。

```
{
   "Error": {
      "Code": "PrometheusClusterUnreachable",
      "Value": "Unable to communicate with the cluster"
   }
}
```

#### DescribeGetMetricData イベント
<a name="MultiDataSources-DescribeGetMetricData"></a>

**リクエストペイロード**

次に、`DescribeGetMetricData` リクエストペイロードの例を示します。

```
{
  "EventType": "DescribeGetMetricData"
}
```

**レスポンスペイロード**

次に、`DescribeGetMetricData` レスポンスペイロードの例を示します。

```
{
    "Description": "Data source connector",
    "ArgumentDefaults": [{
        Value: "default value"
     }]
}
```
+ **Description** - データソースコネクタの使用方法の説明です。この説明は、CloudWatch コンソールに表示されます。Markdown がサポートされています。

  タイプ: 文字列
+ **ArgumentDefaults** - カスタムデータソースビルダーを事前に入力しておくために必要に応じて使用できる、引数のデフォルト値からなる配列です。

  `[{ Value: "default value 1"}, { Value: 10}]` が返された場合、CloudWatch コンソールのクエリビルダーに入力が 2 つ表示されます。1 つ目は「デフォルト値 1」で、2 つ目は 10 です。

  `ArgumentDefaults` を指定しない場合、入力は 1 つだけ表示され、型がデフォルトの `String` に設定されます。

  Type: 値と型が含まれているオブジェクトの配列です。
+ **Error** - (オプション) エラーフィールドは、どのレスポンスにも含めることができます。「[GetMetricData イベント](#MultiDataSources-GetMetricData)」で例を確認できます。

#### CloudWatch アラームに関する重要な考慮事項
<a name="MultiDataSources-Connect-Custom-Lambda-Alarms"></a>

 データソースを使用して CloudWatch アラームを設定する場合は、データをタイムスタンプ付きで 1 分ごとに CloudWatch に報告するように設定する必要があります。接続先のデータソースのメトリクスに対してアラームを作成する方法の詳細とその他の考慮事項については、「[接続されたデータソースに基づいてアラームを作成する](Create_MultiSource_Alarm.md)」を参照してください。

#### (オプション) AWS Secrets Manager を使用した認証情報の保存
<a name="MultiDataSources-Connect-Custom-Lambda-Secrets"></a>

Lambda 関数で認証情報を使用してデータソースにアクセスする必要がある場合は、認証情報を Lambda 関数にハードコーディングするのではなく、AWS Secrets Manager を使用して認証情報を保存しておくことをお勧めします。Lambda で AWS Secrets Manager を使用する方法の詳細については、「[Use AWS Secrets Manager secrets in AWS Lambda functions](https://docs.aws.amazon.com/secretsmanager/latest/userguide/retrieving-secrets_lambda.html)」を参照してください。

#### (オプション) VPC のデータソースへの接続
<a name="MultiDataSources-Connect-Custom-Lambda-VPC"></a>

データソースが Amazon Virtual Private Cloud によって管理される VPC にある場合は、そのデータソースにアクセスするように Lambda 関数を設定する必要があります。詳細については、「[アウトバウンドネットワークを VPC 内のリソースに接続する](https://docs.aws.amazon.com/lambda/latest/dg/configuration-vpc.html)」を参照してください。

場合によっては、AWS Secrets Manager などのサービスにアクセスするように VPC サービスエンドポイントを設定する必要があります。詳細については、「[インターフェイス VPC エンドポイントを使用して AWS サービスにアクセスする](https://docs.aws.amazon.com/vpc/latest/privatelink/create-interface-endpoint.html#access-service-though-endpoint)」を参照してください。

### ステップ 2: Lambda アクセス許可ポリシーを作成する
<a name="MultiDataSources-Connect-Custom-Lambda-Permissions"></a>

作成した Lambda 関数を使用するためには、ポリシーステートメントを作成して必要な CloudWatch アクセス許可を付与する必要があります。ポリシーステートメントは、AWS CLI または Lambda コンソールを使用して作成できます。

**AWS CLI を使用してポリシーステートメントを作成するには**
+ 次のコマンドを入力します。*123456789012* を自分のアカウント ID に、*my-data-source-function* を Lambda 関数の名前に、*MyDataSource-DataSourcePermission1234* を任意の一意の値にそれぞれ置き換えます。

  ```
  aws lambda add-permission --function-name my-data-source-function --statement-id MyDataSource-DataSourcePermission1234 --action lambda:InvokeFunction --principal lambda.datasource.cloudwatch.amazonaws.com --source-account 123456789012
  ```

### ステップ 3: シークレットリソースを Lambda 関数にアタッチする
<a name="MultiDataSources-Connect-Custom-Lambda-tags"></a>

CloudWatch コンソールが、タグを使用してどの Lambda 関数がデータソースコネクタであるかを判断します。いずれかのウィザードを使用してデータソースを作成すると、その設定を行う CloudFormation スタックによってタグが自動的に適用されます。データソースを自分で作成する場合は、Lambda 関数に以下のタグを使用できます。これにより、メトリクスをクエリしたときに、コネクタが CloudWatch コンソールの **[データソース]** ドロップダウンに表示されます。
+ `cloudwatch:datasource` をキーとし、`custom` を値とするタグ。