【Oura × Datadog】API の特性を活かした効率的な連携アプローチ

## はじめに
こんにちは、Datadog Japan で Sales Engineer をしている [**AoTo**](https://qiita.com/AoTo0330) です。

この投稿は **[<font color="#6495ED">AoTo Advent Calendar 2024</font>](https://qiita.com/advent-calendar/2024/aoto) 24日目**の記事です。

昨年『[**Oura API V2 を読み解いて、Datadog にヘルスケアデータを連携する**](https://qiita.com/AoTo0330/items/24277b04be2345b658a1)』というブログを執筆しました。

https://qiita.com/AoTo0330/items/24277b04be2345b658a1

このブログは [**Oura API V2**](https://cloud.ouraring.com/v2/docs) から心拍数データを取得し、[**Datadog Metrics API**](https://docs.datadoghq.com/api/latest/metrics/#submit-metrics) にメトリクスデータとして保存する方法を解説しました。

ですが、実際に使用してみると「API の特性」を正しく理解していないために、上手く連携ができていないことが多々ありました。

こうした教訓からそれぞれの「API の特性」を考慮して、どのように連携方法を変化させたかをここに記録します。

## まとめ
#### どうした？ 
 - ①最新のメトリックを取得するワークフロー連携と、②過去データを取得するワークフロー連携を実装した

①
![OURA_DD_LAST.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2363567/8d92fc43-b651-76cb-05f6-d4a13a5013e6.png)
②
![OURA_DD_MULTI.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2363567/b90c5c89-ee4a-fa7b-a110-44a75141042f.png)

#### どうして？
 - **Oura API V2** は利用者に依存して最新のメトリックが利用可能までの時間が遅延する
 - **Datadog Metrics API** は1時間以上前のタイムスタンプのメトリックを取り込まない
 - **Datadog Workflow Automation** はトリガーとしてスケジュールか何かのイベントが必要

:::note info
現在は、特定のメトリクスを指定して有効化することで、**1時間以上前~15ヶ月以内**のタイムスタンプを持つ[**履歴メトリックの取得**](https://docs.datadoghq.com/metrics/custom_metrics/historical_metrics/)もサポートされています。
:::

## API の特性
### Oura API V2 は利用者に依存して最新のメトリックが利用可能までの時間が遅延する

![OURA_DELAY.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2363567/da49c09d-98f5-b4f9-157c-bd82525d185d.png)

**Oura Ring** は指輪型のウェアラブル端末=スマートリングです。リング内に軽量なメモリを備えており[^1]、使用の種類と頻度に応じて**最大1週間分**のデータを保存できます。つまり、アプリケーションを開かなければ、アプリケーションに連携するまでに**最大で1週間遅延する**ことがあるということです。これが図の①で遅延する大きな要因です。
[^1]: [Product Safety & Use](https://support.ouraring.com/hc/en-us/articles/360025428394-Product-Safety-Use) に記載があります。

**Oura アプリケーション**はローカルに保存されたデータを参照し、現状の**体温・ストレス・コンディション**などを表示してくれます。これはインターネットにモバイル端末を接続していなくても利用できる機能なため、一時的にローカルでデータを保持しまとめて **Oura Cloud** のデータストアに送信していると推測できます。これが図の②で遅延する要因です。

この特性を考慮すると、**最短でも数十秒の遅延**はあることが推測され、**最長で1週間を超える遅延**が発生するとわかります。API を介して最新のデータが利用可能になるまでの遅延を考慮すると、<INS>最新データをこれらの時間範囲の間取得しうる設計</INS>にしておく必要があります。

### Datadog Metrics API は1時間以上前のタイムスタンプのメトリックを取り込まない
![STANDARD_METRIC_INGESTION_LIMIT.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2363567/990df400-bdd0-c3c2-becd-601b652a425d.png)

**Datadog Metrics API** を使用して送信できるメトリクスは[カスタムメトリクスのプロパティ](https://docs.datadoghq.com/ja/metrics/custom_metrics/#カスタムメトリクスのプロパティ)で定義されています。メトリクス名やタグ、メトリクスタイプにもいくつかルールがありますが、最も重要なのはタイムスタンプの制限です。メトリクスのタイムスタンプは、**未来は10分**、**過去は1時間**を超えることはできません。

図では過去30分のタイムスタンプを持つメトリックと過去3時間のタイムスタンプを持つメトリックをそれぞれ送信していますが、同一名のメトリックであってもタイムスタンプが過去1時間を超える3時間のものだけ API で受け付けられないことを示しています。

こうした制限により、過去1時間以上のタイムスタンプを持つメトリクスを取得しておく必要がないとわかります。

## Datadog Workflow Automation はトリガーとしてスケジュールか何かのイベントが必要
最後は厳密にあは API の特性ではありませんが、連携する [**Workflow Automation**](https://docs.datadoghq.com/ja/service_management/workflows/) の制限も考慮する必要があります。

ワークフローはトリガーとなる何かしらによってワークフローの実行を開始する特性があります。つまり、「Oura API で最新のデータが利用可能になった時」というトリガーを作成できることが望ましいです。しかし、最新のアップデートをトリガーにするには Oura API では [**Webhook サブスクリプションルート**](https://cloud.ouraring.com/v2/docs#tag/Webhook-Subscription-Routes)を利用するしかなく、こちらは最新データの送信も担うため、(Webhook の受信を実装できれば)本末転倒になってしまいます…

このトリガー方法を考慮外とすると、ワークフローは[スケジュールトリガー](https://docs.datadoghq.com/ja/service_management/workflows/trigger/#scheduled-triggers)を利用することが最も簡易的に情報を取得できる方法となります。

この時、スケジュールで繰り返しワークフローを実行し、Oura API にデータを取得する頻度は頻繁であればあるほど良くなります。ですが、アプリケーションを開いて Oura Ring からデータを取得する頻度を考えると、それほど頻繁である必要はありません。

考慮結果として今回は、①リアルタイムに最新の心拍数を確認できるように1分程度の頻繁にデータを取得するワークフローと、②1時間以内の遅延に収まったデータを取得するために数分~1時間の頻度で過去1時間までの全データの取得をするワークフローを分けて実装するアプローチを採用しました。

## ワークフローはどうなったのか
ワークフローは前述の通り、①最新のデータをできるだけ早く取得するもの、と②取得可能なデータをできるだけ細かく取得するもの、の2つの異なる目的でに合わせて作成しました。

### ①最新のメトリックを取得するワークフロー連携
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2363567/667b7791-f58e-24d7-6437-fe2536c0dcab.png)

ある程度の時間範囲のメトリクスを Oura API から取得し、その内最新のメトリックのみを [Last Arrry] ステップによって抽出しています。

これにより不要なメトリックを取り込むオーバーヘッドを気にせず、最新のメトリックを素早く取得できます。

### ②過去データを取得するワークフロー連携
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2363567/e4c6b4ae-0d72-f230-613f-203c3e7a9d2b.png)

過去データを取得する場合は、API の特性に合わせて過去1時間までを対象として Oura API にメトリクスを問い合わせます。取得されるメトリックは複数あることが想定されるので、最新のものから順番に繰り返し Datadog Metrics API へ Submit していきます。

こうした処理のために、昨年のブログ執筆時にはなかったワークフローの [For Loop ロジック](https://docs.datadoghq.com/ja/service_management/workflows/actions/flow_control/#for-loop)を活用しています。

## おわりに
今回はちょっとした趣味で連携した Oura × Datadog の環境を、それぞれの API の特性を活かして効率的に連携するために考慮した内容を順を追って解説してみました🐶

Datadog はカスタムメトリクスを柔軟に取り込むオプションとして Datadog Metrics API を直接利用する他にカスタム Agent チェック・DogStatsD・PowerShell など様々用意しています。さらに、現在は今回の制限として説明した「過去1時間までのタイムスタンプ」よりも過去のものを取り込めるオプションもあるため、分析データをまとめて取り込む用途にも Datadog をお使いいただけます！

是非 Datadog のカスタムメトリクスや API、Workflow Automation を利用してオリジナルのメトリクスデータを取り込んでみてください！