株式会社ヘンリー エンジニアブログ

株式会社ヘンリーのエンジニアが技術情報を発信します

ヘンリーにおける Honeycomb 活用を紹介します

株式会社ヘンリーで SRE をやっている id:nabeop です。

弊社で開発しているクラウド型電子カルテ・レセコンシステムの Henry は複雑な医療ドメインを紐解いてシステムとして実装しており、開発と運用の両面でドメインの複雑性からくる問題の迅速に特定・解決することは重要なテーマです。

このため、弊社では OpenTelemetry を活用してアプリケーションのトレース情報を収集し、Honeycomb を活用してトレース情報の分析を行っています。この記事では、弊社での Honeycomb の活用方法について紹介します。

ヘンリーにおける Honeycomb 活用

組織全体での活用促進

筆者はオブザーバビリティツールは特定の職種が使うものではなく、製品組織全体で活用されるべきものと考えています。そういった中で、Honeycomb は思想として組織全体で活用されることを強く意識している製品であるという感想を持っています。

例えば、Honeycomb は取り込まれたイベント数に応じて毎月のきまる従量課金体課金体系を採用しています。これは利用するユーザ数に応じて課金が増える SaaS 型のツールとは異なり、組織全体で活用されることを前提とした課金体系です。このため、少しだけでも Honeycomb を使ってみたいという要望に対して気軽にアカウントを払い出すことができるので、組織全体での利用促進のハードルが低いといえます。

また、他のオブザーバビリティツールと比較すると、Honeycomb は強力なクエリ機能を備えていることが特徴ですが、とっつきにくい印象があります。しかし、Honeycomb ではクエリの実行結果を Slack で共有する時にクエリの内容が表示されたり、自分以外のユーザが実行したクエリの履歴を参照することができます。他のメンバーが実行したクエリの様子を参考にする機会が多くなるように設計されているため、キャッチアップに役立っていると考えています。

実際に Honeycomb の導入当初は SREs が中心になって利用をしていましたが、徐々に開発チームでの活用が広がっており、Honeycomb で実行されたクエリの7割近くは開発チームのメンバーによって実行されています。また、新しい機能のリリースがされたあとにはリリースされた機能のパフォーマンスを確認するために独自のダッシュボードが開発チームによって作成されるなど活用が広がっています。

Calculated Field を使ってクエリによる探索範囲を広げる

製品組織全体のHoneycomb活用事例 で紹介した通り、弊社で Honeycomb が根付いた大きな理由として強力なクエリ機能を使った集計によって探索的な分析ができるということがあります。

データの分析で SQL を使ったり、ログの集計などで grep や awk を使っている感覚と同じように、Honeycomb のクエリ機能を使って分散トレースの分析ができるため、とっつきやすいという側面がります。

Honeycomb は強力なクエリ機能が特徴ですが、クエリ単体では異なる属性の値を比較したりすることはできません。そこで、属性の値を関数などをつかって新しくデータを定義する Calculated Field という機能を利用しています。

例えば、スパンの処理時間に閾値をもうけて、全体の傾向の分析をしたい場合を考えます。

スパンの処理時間は duration_ms として記録されています。例えば、32ms 以上の処理時間を要したスパンのみを分析対象としたい場合はクエリに duration_ms >= 32 を追加することになりますが、32ms を閾値とした分析はクエリのみでは不可能です。そこで、IF(LTE($duration_ms, 32), 1, 0) という計算結果を is_under_32ms という Calculated Fields として定義しておきます。

このようにすることで Group By で is_under_32ms を指定すると 32ms を閾値とした処理時間でスパンが分離されたり、BubbleUp での分布でも is_under_32ms を集計対象として追加され傾向の分析に使用することができます。

手動計装で分析用の属性を追加する

Honeycomb には BubbleUp という外れ値の特定に役立つツールが提供されています。

詳細については Honeycomb のドキュメントにどのような様子かが書かれています。この BubbleUp を十分に使うためにはサービスの特有の情報を属性としてスパンに追加しておくことが重要になってきます。

例えば、手動で計装しているものの1つに GraphQL の variables をスパンの属性に追加しています。

内部のマイクロサービスでは gRPC を採用していますが、外部のクライアントとの通信には GraphQL を採用しています。GraphQL は柔軟なクエリが可能である一方で、クエリの内容が複雑になるとパフォーマンスに影響を与えることがあります。このため、特定の GraphQL クエリがシステム全体のパフォーマンスに与える影響を分析するために、GraphQL の variables をスパンの属性として追加しています。

ただし、Henry に送信される GraphQL クエリには患者さんの個人情報などが含まれるケースもあります。このため、あらかじめ要配慮個人情報などが含まれる値についてはスパンにはマスクされた状態で保存するようにしています。

確率的サンプリングを使用せずに必要な情報を保存する

Honeycomb は取り込まれたスパンの容量に応じた従量課金です。また、他のオブザーバビリティツールと比較しても決して安くはありません。不要なコストを削減するために確率的なサンプリングやエラーベースのサンプリングを採用することが一般的です。

しかし、Henry をご利用いただいている医療機関様は Henry に保存されている診療情報などを使って毎月の保険費用の請求をしているため、医療会計部分の不具合はお客様の経営に直結する問題になります。ヘンリーとしても医療会計の複雑性を解決することは技術戦略上重要なテーマです。したがって、確率的なサンプリングやエラーベースのサンプリングでは重要な情報が欠落してしまうため、全量を保存する方針で使っています。

このような使い方だと契約しているスパンの上限を超えてしまい、レートリミットが発動し、新規のスパンの保存がされないということが過去に何回か発生しました。

そこで、我々のニーズにあうように Honeycomb で保存するスパンやトレースを選択しやすいようにエンドポイントカットのトレースサンプリングを採用しています。エンドポイントカットのトレースサンプリングの詳細については以下のエントリに詳しく書いています。

エンドポイントカットのトレースサンプリングの他にも opentelemery collector のサンプリングプロセッサで比較的重要度が低いスパンを Honeycomb には送信しないようにしています。このような重要度が低いが数が多いスパンの特定でも Honeycomb のクエリ機能と可視化機能は役立っています。

we are hiring

Henry は日本の医療 DX を促進するため、これからも様々な機能拡充を予定しています。このため、今のオブザーバビリティツールの活用の状態が完成ではないと思っています。そこで、ヘンリーではオブザーバビリティツールの整備を通じて複雑なシステムの可観測性を向上する仲間を募集しています。

興味がある方はぜひカジュアル面談などで課題などについてディスカッションしたいです。