この記事は bitFlyer Advent Calendar 2022 の 17 日目の記事です。
前提知識
Azure Functions と Azure Durable Functions については説明しません。
Durable Functions Monitor とは
https://github.com/microsoft/DurableFunctionsMonitor
Durable Functions によって、時間的な状態を持つ処理をサーバーレスな形で動かすことが比較的簡単にできますが、ある程度複雑な状態をもつ function を開発していると、デバッグや状況の監視が難しいと感じることがあります。
- アプリケーション内でログをとっていても、直線的なログだけでは、処理の依存関係と対応付けるのが難しい(例えば、activity の一部だけが失敗してリトライが絡んでいる場合とか……)
- Azure Storage(デフォルトの場合)に history としてログが保存されているが、これも同じ問題があってしんどい
- 失敗した処理や、時間のかかっている処理を見つけたい
Durable Functions Monitor(以下、DfMon)を利用すると、Azure Storage に保存されたログを、各 orchestration / activity function の処理と対応させて視覚化することができ、上記のような問題に対処できます。
また、Durable Functions をあまり使ったことのない方が、動作を把握するのにも役立つと思います。
意外と知名度が低く、Azure Functions を利用していても Durable Functions は使っていない、あるいは
Durable Functions を利用していても DfMon は使っていなかった、ということがあり、ここで紹介しています。
導入方法
大きく分けて 3 つの導入方法があります
- Visual Studio Code の拡張機能としてインストールする
- 既存の Function に NuGet パッケージとしてインストールして UI を追加する
- 独立したサービスとして動かす
開発する際には VSCode 拡張として導入するのが簡単です。
インストールすると Azure タブに "Durable Functions" ペインが追加され、ここから起動できるようになります。
導入方法や機能について詳細はリポジトリの wiki に記載されています。
機能
Orchestration インスタンスの検索と状態の閲覧
各インスタンスごとの状態の閲覧、操作
インスタンス ID を選択すると各インスタンスの状態が見えます:
- ここからリスタートや実行中の instance の停止などの操作も可能です
- 各 activity functions の結果や例外の内容がすぐ見られて、デバッグが捗ります
- 時間のかかる処理について Gantt chart タブもよく見ることがあると思います
- 例: exponential backoff が効いているのがよくわかる様子
開発上の注意
DfMon を使うかどうかにかかわらないものの、Durable Functions の開発の上で注意しておくとよい点があります。
Instance ID と外部の ID を結びつける
orchestration instance ID はデフォルトでは GUID が割り振られますが、外部の ID がある場合はその値と同じにしておくと特定が楽になります。
Custom status を有効に使う
IDurableOrchestrationContext.SetCustomStatus()
で custom status を設定しておくと、DfMon 上でも一覧・フィルタできて便利です。
see: https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-custom-orchestration-status?tabs=csharp
Activity function を分割する
オーバーヘッドとの兼ね合いではあるものの、それぞれの activity functions はなるべく小さい処理にして分割しておくと、DfMon 上でも処理が追いやすく、また時間のかかっている処理や並列化できる処理を探すこともしやすくなります。
並列化したり sub orchestration を使ったりすると、ログが貧弱だと処理の流れがわかりづらくなり、問題が起きたときの対処が難しくなりがちですが、DfMon のような方法で視覚化することでそれに恐れず設計できるのではないかと思います。