【必見】Sentry Performance でユーザ体験を改善する方法

本日、3つの新しいSentry Performance機能により、ユーザーに影響を与える問題の発見と解決がさらに簡単になりました。 INP(Interaction to Next Paint)が新たなCore Web Vitalになった 改善されたトレース体験 モバイル開発者がコールドスタートとウォームスタートでアクションを起こすための新しいワークフロー Core Web Vital に INP のサポート追加 Googleは3月12日、First Input Delay(FID)に代わる新しいCore Web VitalであるInteraction to Next Paint(INP)を発表しました。 FIDは最初のユーザーインタラクションの応答遅延を測定するのに対し、INPはページ上のすべてのインタラクションのパフォーマンスを測定するため、INPはページ全体の応答性をより正確に測定することができます。 ユーザーがページとインタラクションするとき、アクションが完了したこと、または何かが進行中であることを示す視覚的なフィードバックを表示することが重要です。 例えば、ショッピングカートに商品を追加する場合、カートのカウントはほぼ即座に更新され、商品が追加されたことを示すべきです。 ページが反応せず、視覚的なフィードバックがない場合、ユーザーはページが壊れていると思うかもしれません。 SentryがINPをサポートし、ページがすべてのユーザーインタラクションにどのように反応するかをモニターできるようになったのはそのためです。 SentryのWeb Vitalsのホームページには、INP、LCP、CLSのような指標を考慮したパフォーマンススコアが表示されます。 トレースでは、INPスコアから開始し、トレース内のスパンを使って、関連するエレメントとインタラクションのタイプを素早く特定することができます。また、Sentryのプロファイリングを使用している場合は、そのインタラクションに応答している間にブラウザがどのコードでブロックされたかを見つけることで、根本原因を診断することもできます。 このINPの新しいサポートにより、迅速な対応を講じることができ、問題に関連する可能性のあるすべてのトレースを検査したりする手間を省くことができます。 根本原因を追跡して、低い INP スコアを調査します。 もちろん、この同じ論理ワークフローで他のウェブ・バイタル(LCP、CLSなど)もモニタリングできるため、ユーザーに影響を与えるパフォーマンス問題の根本原因を迅速に突き止めることができます。 フロントエンドからバックエンドまで、エンドユーザーのパフォーマンスをデバッグする ページの読み込みが遅いなど、ひどいUX(ユーザーエクスペリエンス)は、非効率的なSQLクエリ、キャッシュ(またはその欠如)、その他のバックエンドのパフォーマンスの問題などに起因することがよくあります。 そのため、アプリケーションスタック全体の異なるサービスで発生した問題を結び付けることが、ユーザー向けのパフォーマンス問題をデバッグするために必要になります。 パフォーマンスのボトルネックを引き起こしているサービスまで、ユーザー側の問題を簡単に追跡できるようにするため、Sentryのトレースエクスペリエンスを簡素化しました。 当社の更新されたトレースビューは、マルチサービスアプリケーションの統一されたビューを提供し、コンテキストを失うことなく、スタック全体の重要な問題を簡単に特定できるようにします。 Sentryのトレースビューは、フロントエンドとバックエンドのサービスを統合的に表示します。 例えば、LCP(Largest Contentful Paint)のスコアが落ちたとしましょう。 Sentryを使うことで、トレースビューでスコアの悪いページロードの調査を開始し、APIリクエストのバックエンドの操作に焦点を当てることができます。 トレースビューでは、遅いデータベースクエリやフレームドロップのような関連するパフォーマンスの問題も表示されるので、実際のユーザーに影響を与える問題を即座に修正するために何をすべきか(または誰のせいにすべきかᘏ)を正確に知ることができます。 Sentryの新しいトレースビューでは、パフォーマンスの問題を引き起こしているAPIリクエストについて、バックエンドの操作に集中することができます。 【モバイルパフォーマンス】コールドスタートとウォームスタートからコード行数まで モバイル開発者にとって、本番環境でパフォーマンスの問題を発見し、それを修正するのは時間の浪費につながります。 特に、アプリの起動が遅いという苦情があったときにデバッグしようとすると大変です。これを解決するために、私たちは、コールドスタートとウォームスタートの根本的な原因を、原因となっているコードまで検出して追跡できるように、まったく新しいワークフローを構築しました。 簡単に復習すると、コールドスタートとは、アプリがまだ実行されていない状態で起動することです。 ウォームスタートとは、アプリがバックグラウンドからフォアグラウンドになることです。 例を見てみましょう。 […]

【Beta版公開中】Metricsで重要指標を測定し、問題を迅速に解決する方法

4年前、私たちは開発者を第一優先したパフォーマンス監視で大きな一歩を踏み出しました。 それ以来、数千ものソフトウェアチームが当社の最新APMソリューションを採用しています。 しかし、パフォーマンスについてチェックすべき項目が多くある一方で、開発チーム内で別々のツールで管理しているところもあり、監視が分断されてしまっているケースもあります。 エラーの根本原因や、パフォーマンスの問題を結びつけるのは、不必要に難しくさせます。SentryのMetricsは現在ベータ版で公開されています。 最初の立ち上げの週に予告したように、Metricsはまだ開発途中でした。 今回、ベータ版がリリースされ、無料で使用できるようになりました(ローンチウィークのアナウンスはこちら)。 これは単なるツールではなく、あなたにとって最も重要なデータポイントを長期にわたって追跡するための新しいパートナーとなるでしょう。 Metricsを使えば、製品・サービス・コードが常に意図したとおりに動作していることを確認しながら、相関するトレースで問題を特定し、解決することができます。 チームは、処理時間・チェックアウトのコンバージョン率・ユーザーのサインアップなどのカスタムメトリクスを監視して視覚化したり、トランザクションの継続時間などの既成のメトリクスを探索したりすることが可能になります。 また、問題を発見した場合、問題の原因を解決するために相関トレースを使用することができます(もちろん、このような機能はありません)。 メトリクスでクリティカルパスを監視 あなたがショッピングカートとチェックアウトの機能を持つ製品やサービスに取り組んでいるとします。 その処理フローは、あなたの会社の収益に直結しています。ですから、巨大なeコマースチェーンや、ユーザーがクレジットカード情報を入力しなければ続行できないSentry’sのようなSaaSビジネスを思い浮かべてください。 ユーザーがハッピーパスを通して成功できるようにすることは、貴社の成功にとって非常に重要です。このパスに遅延が生じると、収益が失われ、おそらく(間違いなく)多くの顧客が離脱することになります。 以下の例では、チェックアウトのレートを注視し、ユーザーがホームページから配送先住所の追加、チェックアウトへとスムーズに移動できるようにします。 仮想のチェックアウトフローのGIFをご覧いただくとわかるように、訪問者は3つのステップを完了する必要があります。 ホームページでスワッグをリクエストし、住所を入力し、注文を送信します。 Sentryの新しいメトリクスを使用すると、カスタムメトリクスを作成して、チェックアウトプロセスを完了したユーザー数をカウントし、視覚化することができます。 チェックアウトフローの3つのステップを追跡するためにカスタムメトリクスを作成し、何人のユーザーがホームページでスワッグをリクエストし、住所を入力、そして注文を送信したかどうかを可視化できるようになりました。 Metricsのおかげで、チェックアウトのコンバージョン率が安定していることが可視化することが出来るようになりました。 メトリクスが合わないとアラートを受け取る また、アラートを作成して、重大な変更があった場合にSlack、Discord、Teams、Emailで通知を受け取ることもできます。チェックアウトフローですべてがうまくいっていることを確認するために、チェックアウト率が20%下がったら発動する閾値アラートを設定しました。 アラートが表示される場合は、以下の画像のように表示されます。 コンバージョン率が下がったのでしょう。 結果をチェックすると、それを確認することができます。 訪問者が購入者に転換していないようです。 カスタムメトリクスによると、注文を正常に送信するユーザーが明らかに減少している。 一般的な製品の旅はここで終わりです。 しかし、Sentryの場合はまだ始まりに過ぎません。 【メトリクスとトレース】デバッグの強化 問題を特定できたので、当然の次のステップは解決策を見つけ出すことです。 問題がどこにあるのか直感的に分かるかもしれませんし、特定のAPIに問題があるかどうかを確認するために、レスポンスタイムのような他のメトリクスを引き出すかもしれません。 それで十分な場合もありますが、それ以上に厄介な場合もあります。 そんな時こそ、1つのツールでアプリケーションに関する様々な種類のデータにアクセスできるのが本当に便利です。 Metricsは、アプリケーションの幅広いデータを見るのに適しています。 一方、トレースは、フロントエンドからバックエンドまで、アプリケーションの深部を見るのに役立ち、根本原因を見つけるための豊富なトラブルシューティングデータを提供します。 あなたが注目しているメトリクスと相関のあるトレースイベントを表示することで、2つのシグナルを簡単に結びつけることができます。 イベント・サンプル・テーブルから、特定のトレース・ビューにドリルダウンすることができます。 ウォーターフォールを見ると、このトレースに非常に時間がかかっていることがわかります。サードパーティのフルフィルメントAPIが原因です。 これで、問題を解決し、ショップを復旧させるために何をすべきかがはっきりしました。 数えるだけじゃない『分布・ゲージ・セット』 上記の例では、カウント(”インクリメント “できるものをトラッキング)の例を示していますが、以下のようなさまざまなメトリックタイプを作成することができます。 分布: 最大値、最小値、平均値のように、時間にわたって集計できる値のリストを追跡します(たとえば、ページのロード時間)。プロセスの開始時間やキューの健全性やターンアラウンドタイムのように、アプリケーションの健全性を明らかにするようなことをレポートするために分布を使用することができます。 例えば、Sentryでは、イベントマネージャがイベントを保存するのにかかる時間の分布を測定するために、Dogfood Metricsを使用しています。そして、通常95パーセンタイルを監視し、イベント・インジェスト・パイプラインに影響を与える可能性のあるリグレッションをチェックします。 以下のように、青い点はこのメトリクスで収集されたサンプルです。 サンプルテーブルを使用して単一のサンプルを選択するか、直接ドットをクリックしてトレースの詳細を表示することができます。 ゲージ: 増減する値を追跡します(例えば、使用可能なディスク容量や使用メモリなど)。 セット: count_unique(ユニーク・ユーザー数など)のように、時間の経過とともに集計される値のセットを追跡します。 さあ、始めましょう! Metricsを追加する以前の場合は、SentryのPerformance機能を使えば、すべての典型的なパフォーマンス・メトリクスを測定することは可能でした。 […]

【Autofix】AIを使ってプログラムを簡単にデバッグ&修正する方法

Sentryはアプリケーションのコードベースの内部構造について多くのことを知っています。 そこで私たちは、この豊富なデータセットを使って、デバッグをさらに高速化するにはどうすればいいかを考えました。 多くのジェネレーティブAI(GenAI)ツール(GitHub Copilotなど)は、開発環境における開発者の生産性を向上させますが、Sentryのような本番環境でのエラー修正を支援するコンテキストデータを持つものはほとんどありません。 私たちの新しい『AI対応Autofix機能』は、エラーが発生したときにユーザーが何をしているかを理解し、エラーを分析し、修正を生成し、さらにあなたのレビューのためにプルリクエストを開きます。 これは、オンデマンドで支援する準備ができているジュニア開発者を持つようなものです。 Autofixは本番環境でのエラーのデバッグを支援するためのものですが、もし開発中にそのような支援が必要だと感じたら、Codecovの新しいAIコードレビューをお試しください。 AIを搭載したAutofixの仕組み Autofixはエージェントベースのアーキテクチャを使用し、Sentryの問題を評価し修正するプロセスを管理可能な作業単位に分割します。 まず初めに、問題発見エージェントで、問題の予備評価を行い、コード変更で修正可能かどうかを判断します。 次に、プランニングエージェントが、エラーメッセージとお客様のコードベースから関連するコンテキスト情報を使用して、根本的な問題を解決するための実行プランを構築します。 このプランは、修正と付随する単体テストの生成を担当するAutofixの実行エージェントに渡されます。 最後に、PRを生成する前に、すべての変更を最終的にレビューします。 このプロセスは、反復的で透明性があるように設計されています。 システムは、積極的にコンテキストとフィードバックを求めながら進み、各ステップの結果は、開発者にとってなじみのあるCIライクなインターフェイスで表示されることも特徴的です。   IchizokuはSentryと提携し、日本でSentry製品の導入支援、テクニカルサポート、ベストプラクティスの共有を行なっています。Ichizokuが提供するSentryの日本語サイトについてはこちらをご覧ください。またご導入についての相談はこちらのフォームからお気軽にお問い合わせください。

INPとは何か?

2024年3月12日、Googleは新しいCore Web Vital指標である Interaction to Next Paint (INP) を開始することを発表しました。INPは、FID(First Input Delay)に代わるもので、Googleによるサイトのパフォーマンス評価の方法を変え、最終的に検索エンジンの検索結果に影響を与えます。 TL;DR:3月12日以降にあなたのサイトが悪影響を受けないよう、今日からINPに最適化する必要があります。 INPへ変更した経緯 FID(First Input Delay)は、Webページがユーザーの最初のアクションに対してどれだけ速く反応するかを測定するために設計されました。一般的に良いとされるFIDスコアは、100ms以下とされています。 しかしChromeの使用データによると「ユーザーのページ滞在時間の90%は読み込み後に費やされる」ため、FIDではユーザー体験のすべてを把握することはできません。 そこで INPは、最初のインタラクションだけでなくページ上のユーザージャーニー全体にわたってクリック、タップ、キーの押下を観察するように設計することで、ページの全体的な知覚応答性を測定することが可能になっています。 最終的なINPの値は、ユーザーがアクションを実行してから視覚的なフィードバックを受け取るまでに観測された最長時間として計算されます。 ユーザーインタラクションの例としては、製品をカートに追加するボタンのクリック、展開可能なアコーディオンのクリック、折りたたまれたナビゲーションメニューのタップ、入力フィールドへの入力などがあります。 INPは、特定のアクションが実行された後、視覚的フィードバックが表示されるまでの時間(つまり、次のペイント-ここでペイントとは、ブラウザがスクリーンにピクセルを追加するプロセスのことです)に焦点を当て、インタラクションの最終的な効果(ネットワークリクエストやUIの更新など)は除外します。 開発ツールにおけるINPの調査 Chrome、Brave、Edge、ArcなどのChromiumベースのブラウザを使用して、INP測定値に寄与するアクションとイベントを調査する方法を見てみましょう。 INPが計測する以下のユーザーインタラクションのいずれかを受け付けるウェブページを選択します(スクロールやポインタの移動などは計測されない) マウスでのクリック タッチスクリーンを使ってデバイスをタップする 物理キーボードまたはオンスクリーンキーボードのキーを押す 今回は、Sentry Docsのホームページで “web vitals “を検索したときに何が起こるかを調査することにしました。 開発ツールパネルを開き、「パフォーマンス」タブをクリックします。 Webサイトのターゲット層にもよりますが、古いマシンや低速のインターネット上でのユーザー体験を分析するために、CPUやネットワーク速度を調整することはしばしば有用です。 より遅いCPUやネットワークをシミュレートしたい場合は、それに応じてオプションを設定してください。 記録ボタンをクリックし、ページ上でいくつかのインタラクションを実行します。 録画を停止し、プロファイルがロードされるのを待ちます。 すると、色分けされたブロックとラベルの付いたレーンの形で、多くのデータが表示されます。 INPの要因を分析する際に最も重要なレーンは、”Interactions”(ページ上で実行されたユーザーインタラクション)と “Main”(ブラウザのメインスレッド)です。 文脈上、メインスレッドは “ブラウザがユーザーイベントとペイントを処理する場所 “です。デフォルトでは、ブラウザはメインスレッドを使用して、ページ上のすべてのJavaScriptの実行、ページのレイアウト、あらゆる変更の再計算、メモリの確保と解放(ガベージコレクション)を行います。 つまり、長時間実行されるJavaScript関数がメインスレッドをブロックする可能性があり、レスポンスの悪いページや悪いユーザーエクスペリエンスにつながります。GoogleはINPメトリックを導入することで、開発者にこれを解決するよう促しています。 記録されたパフォーマンスプロファイルを見ると、メインスレッドのブロックが赤くハイライトされていることがあります。タスクにカーソルを合わせると、実行にかかった時間が表示され、そのタスクブロックの下には、そのタスクを構成する個別のイベントや関数呼び出しがすべて表示されます。 マウスやトラックパッドでズームイン/ズームアウトしたり、ウィンドウの右側にあるスクロールバーを使ってスタックを上下にスクロールすることができます。 レーンの下にあるサマリー・タブは、各タスクでどれだけの時間が異なるプロセスに割り当てられたかを示しています。 これはタスクによって異なりますが、通常は「スクリプティング」(つまりJavaScriptの処理)と「ローディング」に最も長い時間がかかっていることが明確になります。 では、メインスレッドのアクティビティと、インタラクションレーンを確認してみましょう。 この例では、Sentry Docsホームページの検索入力に “web vitals “と入力した状態です。 […]

【Sentry】モバイルアプリのパフォーマンス改善方法

何千ものモバイル開発者チームと協力してきた経験に基づいて、Sentryではモバイルモニタリングの成熟曲線を開発しました。 私たちは、チームが安定性を達成し、クラッシュの消火と修正がなくなると、ワークフローの合理化にシフトし、最終的にはモバイルアプリのパフォーマンスの最適化に集中するようになるという仮説を立てました。 先日のワークショップで、私たちはモバイル開発者たちに、D彼らがカーブのどこに位置するかを尋ねました。 するとその結果は驚くべきものでした。 ほとんどの開発者(41%)は「安定性の確保」の段階にいました。 また、4分の1近く(24%)が現在パフォーマンスを最適化しています。 集中力とリソースは必要ですが、パフォーマンスの改善はモバイルアプリの成功に不可欠です。開発者が成熟度カーブを上れるよう、当社はモバイル・パフォーマンスの問題を検出して修正する方法を改善しています。これらの改善は、4つの重要な要素に分けることができます。 TTID / TTFDを使って遅い画面を最適化する アプリの起動が遅い根本原因を特定する アプリケーションの応答性を向上 モバイル・サービス・ビューで主要メトリクスを確認 TTID / TTFDを使って遅い画面を最適化する モバイル画面のロード時間、特にTTID(Time to Initial Display)とTTFD(Time to First Display)に焦点を当てたトラブルシューティングのワークフローを開発しました。 TTIDは、ユーザーにアプリがロード中であることを知らせる最初のフレームを表示するのにかかる時間です。 TTFDは意味のあるコンテンツが画面に表示され、アプリが完全にインタラクティブになるまでの時間です。ニュース記事をスクロールしたり、おしゃれな洋服を買ったりするのに、数秒待たされるのは誰だって嫌ですよね。 TTIDとTTFDのどちらかが遅いと、ユーザーはすぐに離脱してしまいます。 TTIDとTTFDは、プロダクションでの遅いメトリクスに寄与する作業を強調します。Sentry の Screen Loads を使用すると、トラフィックが最も多いユーザー画面を確認し、リリース間で TTID と TTFD を比較できます。 これにより、新しいリリースで導入された潜在的なパフォーマンスのボトルネックが強調されるため、速度低下の原因となっているコード変更、依存関係、または資産を調査することができます。以下のスクリーンショットのように表示されます。 また、単一画面の画面ロード・サマリー・メトリクスを見たり、モバイル・デバイス・クラスでフィルタリングして、リリース全体の平均TTID / TTFDを見ることもできます。 サマリー・グラフの下には、最も時間のかかるスパンが表示されます。これらについては、データのフィルタリングも可能です。 これにより、どの操作が TTID または TTFD の遅さの原因となっているかを知るために必要なコンテキストが得られます。以下のスクリーンショットをご覧ください。 Screen Loadsは現在、すべてのAndroidおよびiOSユーザーに提供されています。 アプリの起動が遅い根本原因を特定する 当社の新しいモバイルパフォーマンスアップデートは、アプリの起動が遅い根本原因の特定にも役立ちます。 モバイルアプリの起動シーケンスとは、アプリの起動からTTIDまでのステップを指します。迅速なアプリの起動は、ユーザーに好印象を与え、高い満足度、継続率、コンバージョン率を確保するために非常に重要です。 コールドスタート(アプリが初めて起動されるとき)であれ、ウォームスタート(アプリがバックグラウンドからフォアグラウンドに移動するとき)であれ、アプリの起動時間はAppleやGoogle Playストアでのアプリのランク付けや発見にも影響します。 Sentryでは、SentryのパフォーマンスナビゲーションバーでApp Startを使用して、最近リリースされたアプリバージョンのパフォーマンスを監視できるようになりました。 下の例のように、あるリリースと次のリリースのコールド(またはウォーム)スタート時間を比較し、両方のリリースのイベント […]

正しい指標を選ぶ: パーセンタイルと平均値のガイド

アプリケーションのパフォーマンスを測定するために、どのパフォーマンス指標を使用すればよいか分からない。 そんなことでお悩みではありませんか? でも心配ありません。 あなただけではなく、様々なプロジェクトで同様の悩みを抱えています。 多種多様なオプションがあるため、適切なメトリックを選択する作業は難しいです。この記事では、各メトリクスの長所と限界について解説します。 モニタリングに適したメトリックを決める際にお役立てください。 なぜ正しいメトリックス(指標)を選ぶことが重要なのか パフォーマンス監視において、適切なメトリックスを選択することは、タスクに適切なツールを選択するようなものです。 釘を打つのにレンチを使っても最良の結果が得られないように、パフォーマンス監視に誤った指標を使用すると、誤解を招くような解析結果につながる可能性があります。 アプリのパフォーマンスの全体像を把握しなければ、ユーザー満足度の低下、最適化の機会損失、問題の解決時間の長期化などのリスクが生じます。 例えば、アプリケーションのパフォーマンスを評価するために平均的な指標だけに頼っていると、UXに大きな影響を与える可能性のある「スパイク」や「ディップ」を見落とす可能性があります。 逆に、p99のようなパーセンタイルを使用すると、レーダーを潜り抜けてしまうような、まれではあるが影響力のあるパフォーマンス問題を特定するのに役立ちます。 平均:簡単な概要 平均値は、パフォーマンス監視のためのわかりやすい指標です。 すべてのデータポイントを合計し、データポイントの総数で割ることで、パフォーマンス全体のスナップショットを提供します。 この指標は理解しやすく、計算も簡単であるため、魅力的な選択肢であると言えます。 しかし、平均がうまく機能し、典型的な経験を反映するのは、データが比較的一貫している(つまり、大きな外れ値や歪みがない)場合だけです。 例えば、移動平均はシステム全体が過負荷になりつつあることを知らせます。 しかし、その他のユースケースでは、平均値で対応できる領域には限界があります。 平均値の落とし穴 データが均一でない場合、平均値は誤解を招くリスクを含みます。 ページのロード時間をモニタリングする場合、平均値は役に立たないかもしれません。ユーザーデバイスは、ネットワークのような、あなたのアプリがコントロールできない、あらゆる種類の不安定な特性の影響を受けます。 そこで、パーセンタイルの出番となります。 パーセンタイル:ばらつきを理解する パーセンタイルは、データをその分布に基づいてセグメントに分割することで、パフォーマンスのより微妙なビューを提供します。 理論的には、どのパーセンタイルもモニターすることができますが、実際には、p50、p75、p95、p99、p100の5つが使用されます。 p50(中央値): データの50%が該当する値。p50は、データの中心的な傾向と典型的なパフォーマンスについての洞察を与えます。p50の上昇または下降は、中央値のパフォーマンスの変化を示し、データポイント間の応答時間の速さや遅さを反映します。 p75:データの75%がこの値を下回る。p75は、フロントエンド・アプリケーションにとって貴重な指標です。これは、ユーザーの状況に大きなばらつきがあるため、データの分布が予測しにくくなるからです。p75は、中心的なパフォーマンスの傾向と、フロントエンドで遭遇する幅広いUXとの間でバランスをとります。 p95:これは、データの95%が該当する閾値です。p95は、均一なデータを持つバックエンドアプリケーションにとって価値があり、ほとんどのユーザーが期待するパフォーマンスを捕捉し、ボトルネックを強調します。しかし、可変フロントエンドの設定では、p95は最悪のシナリオを意味し、典型的なUXを代表するものではありません。 p99: この値を超えるデータはわずか1%であることを示します。バックエンドアプリケーションのようにデータの一貫性が高いシナリオでは、p99がパフォーマンスの上限を示し、最も極端なケースを強調します。 p100(最大値): p100は、計測器の問題やクライアント側の変数など、フロントエンド・アプリケーションにおけるノイズの原因を特定するために有用です。バックエンドアプリケーションでは、真のノイズや極端な異常値を示すことがあります。 以下はバックエンドトランザクションのパーセンタイルの例です。 典型的なパターンが観察されます。 p25からp75まで徐々に上昇し、p75からp95まで急な、しかしまだ緩やかな上昇が続きます。最後に、p99まで急上昇しています。 興味深いことに、p100はグラフに含まれていません。 その理由は、Y軸のスケールが大きくなるため、他のパーセンタイルの詳細が平坦な線に圧縮され、視覚化が歪んでしまうからです。 続いてフロントエンド・アプリケーションの典型的なパーセンタイル・チャートをお見せします。 このシナリオでは、p25からp50まで緩やかに上昇し、持続時間が適度に長くなっていることがわかります。 続いて、p50からp90まで急上昇していますが、これはより急激な値の上昇を意味します。 最適な指標の選択:バランスを取る どのメトリクスを監視するかは、アプリケーションのパフォーマンス目標に沿う必要があり、データのばらつきの大きさによって決まります。 十分な情報に基づいた選択ができるように、選択肢を分類してみましょう。 ユーザー・エクスペリエンスの観点 ユーザーがシステムとどのように相互作用しているかを理解することを第一に考えるのであれば、p75やp95のようなパーセンタイルに注目してください。これらのメトリクスは、典型的なパフォーマンスの全体的なビューを提供しています。 p75とp95のどちらをトラッキングするかは、モニターしたいアプリケーションのタイプによって異なります。フロントエンド・アプリケーションのような変動性の高い環境では、p75を選択することをお勧めします。バックエンド・アプリケーションのようなデータの一貫性が高い状況では、p95の方が適しているかもしれません。 異常値の検出 少数のユーザー・サブセットに影響する異常値や稀な事象を特定することが重要な場合は、p95(フロントエンド・アプリの場合)またはp99(バックエンド・アプリの場合)を選択します。 これらのパーセンタイルは、平均中心のメトリクスを使用した場合に発見できない可能性のある問題を特定するのに役立ちます。 スケーラビリティの計画 リソースの割り当てとシステムのスケーラビリティを計画することが目的であれば、平均値が適しているでしょう。 負荷が増加している期間の平均を監視することで、システムがいつ容量の限界に達するかを特定することができます。 Sentry […]

パフォーマンス監視機能によってアプリの安定性を向上させ、エンジニアの負担を軽減した理由

オランダに本社を置くVisma社のYukiは、中小企業や会計事務所に使いやすい自動化された会計・税務サービスを提供しています。 顧客は財務書類をYukiに送り、Yukiのソフトウェアが自動的に書類を処理し、財務報告や税務申告を行うというものです。 多くの税務・会計ソフトウェアプラットフォームと同様に、Yukiは四半期ごとに約2週間の激務を経験します。 閑散期には機能が長期間使用されないため、バグやパフォーマンスの問題はエンジニアがその場でQAを行い、本番環境で監視していても、気づかれることはありませんでした。 スローダウンは使用量のピーク時にのみ現れ、ただでさえストレスの多い時期にユーザーのフラストレーションを引き起こし、開発者はすべての問題を優先度0(p0)として扱う必要がありました。 チームは迅速に問題を解決していましたが、会社の成長に伴い、自前のロギングおよびモニタリングツールだけでは対応できなくなりました。 エンジニアたちは、パフォーマンス課題を可視化できず、原因の特定が困難となり、反応も鈍かったのです。 影響を受けたユーザー数を確認できないため、最初に修正すべき優先順位を決める方法がありませんでした。 その代わり、エンジニアがコードを見て、それがどのくらいの影響を持つモジュールなのか推測し、問題がクリティカルかどうかを判断することに頼っていました。 「私たちのプラットフォームが成長するにつれ、速度低下に関する顧客からの苦情が増えました。しかし、これらの速度低下を解決するために、エンジニアはローカル環境で問題を再現することができないため、顧客チケットと電子メールの間を往復しなければならず、解決まで期日を要し、フラストレーションも蓄積していきました。」 チームは、顧客が書き込む前にエラーやパフォーマンスの問題を自動的に特定し、トリアージを支援し、解決するソリューションを探し始めました。 課題 エラーの影響に関するグループ化、アラート、メトリクスがない エンジニアにコンテキストがなく、トラブルシューティングが困難で時間がかかる パフォーマンスの問題は表示されるが、根本的な原因を特定するのは難しい ユーザーへの影響を可視化できない 従来のAPMベンダーよりもSentryが適していた Yukiは、いくつかの他のアプリケーションパフォーマンス監視(APM)ツールを比較検討しました。 しかし最終的にエラー追跡とパフォーマンス監視のためにSentryを選択しました。その決め手は、開発者エクスペリエンスの向上、SlackとAzure DevOpsとの連携、および.NETの強力なサポート体制です。 他のソリューションとは異なり、Sentryはカスタマイズをあまり必要としなかったため、エラーや速度低下、エンジニアが気にするメトリクスをすぐに監視することができました。 「私たちが評価した他のツールは圧倒的で、ハイレベルな指標しか示してくれませんでした。データだけで行動を起こすのは難しいのです。しかしSentryはセットアップが簡単なだけでなく、UXもわかりやすい。不必要な情報は適切にカットし、例外や遅いクエリなど、修正すべき点を正確に示してくれます。」 さらにYukiは、ユーザーへの影響やエラーの発生時期などのデータにアクセスすることで、重大性に基づいて問題に優先順位を付け、ログを探し回ったり、顧客と電子メールでやり取りしたりすることなく、それらの問題に対処することができるようになりました。 「問題が発生した場合、正確なバージョン、リリース、完全なURLがわかります。この情報を得ることで、開発者のエクスペリエンスは一変し、何が問題なのか、どこで問題が発生したのかを突き止めるのが非常に簡単になりました。」 すぐに使える.NET SDKサポート カスタムSlackアラート DBクエリと外部API統合のパフォーマンスを監視する機能 ダッシュボードとクエリの活用による迅速な改善 YukiはDB中心のアプリケーションで、より分散されたアーキテクチャに移行する計画があります。 これを念頭に、Yukiは分散サービス全体をトレースし、DBクエリと外部APIに関するパフォーマンス・インサイトを提供するソリューションを必要としていました。 「私たちは多くのサードパーティのAPIに依存し、複雑なクエリを書いています。1つのクエリが遅いと、アプリケーションのさまざまな領域に影響を及ぼす可能性があります」とJeroen氏は説明する。 パフォーマンス・クエリ・モジュールを使用することで、Yukiは、トップ・リグレッション・クエリと、それらがどのAPIエンドポイントから発生しているかを確認することができます。以前は、スローダウンが起きていることを特定するだけでなく、スローランニングしているクエリを見つけるためにエンドポイントごとに時間をかけて確認する必要がありました。 特に、クエリのロード時間が大幅に増加したクエリを検出したケースです。 Arjan氏は、パフォーマンス監視を使って、画像処理に関連する.NETライブラリ内で最近行われた変更までさかのぼりました。 リクエストの URL をすべて見ることができたため、問題を絞り込み、例外をスローする画像フォーマットを特定することができました。 「私たちは、特定の画像タイプのレンダリングに問題があることを知っていました。Sentryは、すべてのメタデータを含む完全なクエリー文字列を提供してくれたので、どの画像タイプが影響を受けているかを正確に突き止めることができました」とArjanは解説します。 以前であれば、問題のクエリは請求書のロードに使用されるコンポーネントを含む多くの異なるコンポーネントと相互作用していたため、Arjan氏のチームは修正パッチの適用を急いでいたことでしょう。しかし、Sentryでその影響を確認できたため、ホットフィックスをプッシュするためにすべてを停止する必要がない、孤立した問題であることがわかりました。 「2週間のリリースサイクルの間にパッチを当てる必要はありませんでした。Sentryのおかげで血圧が下がり、エンジニアが時間を集中させるべき優先順位を効果的に決めることができます。」 もう一つの例は、UIの新バージョンを作成しているときに、TPMメトリクスを使って多用されているエンドポイントを特定したときのことです。 調査の結果、そのエンドポイントは10秒ごとにタイマーを使ってデータベースからステータスをフェッチしていることがわかりました。 彼らはクエリを最適化して書き換え、ラウンドトリップを減らし、古いデータにはキャッシュを適用することができ、スピードが大幅に向上しました。 Slackでクリティカルな接続問題を検出する Yukiは会計を自動化しているため、成功の尺度の1つはアプリで費やされた時間です。このため、開発チームは、ユーザーに影響を与える問題をすべて取り除き、サイト・パフォーマンスを最適化することで、ユーザーが可能な限り速く出入りできるようにしています。 SQLサーバーのDB接続に失敗したことを知らせるアラートをSlackに設定しました。 以前は、Yukiはこのような問題について、サポートチームや顧客からの電話で聞くだけでした。パフォーマンスの問題があった場合、彼らの唯一の手段は、潜在的な問題がないかインフラを検査することだったのです。 「私たちのシステムは大きすぎて、どこが遅いのか、あるいはサーバーの接続数が多すぎて新しい接続を受け付けられないのかを知ることはできません。私たちのインフラ監視ツールはAPIエンドポイントを教えてくれますが、問題がどこにあるのかを突き止めるには十分ではありません。」 適切なロギングがなければ、システムの負荷や使用状況について把握することは困難です。Sentryをインストゥルメント化して以来、Yukiは顧客ベースの5%以上がアクセスできない2つのDB接続エラーを検出し、修正しました。 一旦警告が出されると、彼らはSentryで1分あたりのトランザクション(TPM)の指標を見ながら応答時間を追跡し、顧客が書き込みを始める前に問題を修正し、全員が請求書と税務情報にアクセスできるようにしました。 「私たちはサポートよりも早く、アラートとそれを解決するためのコンテキストを得たので、すぐにシステムをリブートしました。」 2日から2時間の短縮。コントロールの回復、問題の解決、不安の軽減 Sentryを導入して以来、Yukiのエンジニアリングチームは、より透明性の高いワークフローを実現し、開発者が自分のコードのパフォーマンスを管理できるようになりました。 「Sentryはリリースをプッシュするたびに不安を取り除いてくれます。以前はコントロールできませんでした。Sentryを使えば、問題を見つけるだけでなく、より深く掘り下げて解決するためのデータが得られるのです。」 […]

Cron監視の拡張

この1年間、我々はCronを構築してきました。 小さなプロトタイプから始まったこの機能は、Sentryのエラー、パフォーマンス、信頼性モニタリングツールの本格的な機能へと生まれ変わりました。 この機能自体はまだベータ版ではありますが、すでに1日あたり700万以上のチェックインを受け付けています。 このような規模が大きくなった機能なので、信頼性を保証する方法について慎重な決断が必要でした。 早期実施 Sentryの新しいCron監視機能とは、スケジュールされたジョブ(例:古典的なcronjobs、celery beatタスク、Sidekiq、Laravel Scheduled Tasks、あるいはsystemdタイマー)が通常通り動作しているか、あるいは実行に失敗したシナリオを検証し、アラートを出す方法のことです。 これは、スケジュールされたタスクが “check-in “イベントを介して私たちに通知することで機能します。 Missed:予定時刻にチェックインしなかった場合、「チェックイン漏れ」となる Timed-Out:進行中のチェックインが完了しなかった場合、「タイムアウト」となる Error:status=errorのチェックインを送信すると、明示的にエラーとしてマークされる 最初のプロトタイプでは、チェックインの取り込みはDjangoアプリケーションに組み込まれたいくつかのAPIエンドポイントによって処理されていました。 物事をシンプルに保つために、チェックインは単に Postgres テーブルのエントリとして記録されます。 チェックイン漏れを検出するために、1分間に1回、celery beatタスクを実行して、予定時刻にチェックインがなかったモニターを探すだけです。タイムアウトの検出も同様です。 しかし、この最初のプロトタイプをアーリーアクセスユーザーに提供できるようにしたのは、今年に入ってからでした。 アルファ版の機能であっても、私たちはすぐに勢いを取り戻し、信頼性とスケーリングについて考える時が来たということです。 インジェスト・インフラストラクチャー 私たちが最初に解決しようとした問題は、チェックインの取り込みでした。 私たちのSDKが使用するAPIエンドポイントは、可用性が高く分散されています(私たちの分散取り込みインフラであるRelayを使用しています)。 しかし、私たちのフロントエンドを駆動し、プロトタイプのエンドポイントが実装されたSentry製品のAPIは、このような保証がありません。 Relayが可用性を向上させるだけでなく、Relay経由でチェックインを実装するもう一つの大きな利点は、私たちのSDK群全体でCronチェックインを作成するためのサポートを迅速に実装できることです。 これはRelayが統一された「エンベロープシリアライゼーションスキーマ」を使用しており、SDKが任意のイベント(もちろん最も一般的なのはエラーとトランザクションです)をRelayのポイント・オブ・プレゼンスに簡単に渡すことができるためです。 Cronのチェックイン・インジェストをRelayに移行するのは当然のことでしたが、プロトタイプのインフラを大きく変更する必要がありました。 この改良された世界では、Relay は SDK からのチェックインイベントを受け付けます。これは従来の curl スタイルでのチェックイン用の API エンドポイントも提供します。 これらのチェックインは検証され、正規化され、Kafkaトピックに入れられます。 これにより、処理できるチェックインの量をスケールアップするためのノブをすぐに回すことができます。以下のようなイメージです。 このアーキテクチャにより、ユーザーのチェックインを失うことなく、コンシューマーの問題を確実に回復することができます。Kafkaは問題のあるシナリオでもチェックインのバックログを維持することができ、負荷の要求に応じてコンシューマーの数を微調整することができます。 チェックイン漏れを確実に検知 Cronのインジェストインフラストラクチャの可用性が改善されたので、私たちはチェックイン漏れ検出の信頼性に注目しました。 Sentryは通常、プラットフォームに送られたデータを処理します。 未チェックインの検出は、我々のインフラにとって斬新な領域です。 1分間に1回のCelery beatタスクを使ってチェックインを検出するというプロトタイプのアプローチには、2つの大きな問題があることがすぐにわかりました。 Celery beatスケジューラのデプロイ中に、タスクがスキップされる短い期間があります。 これは、1分間に1回のチェックイン・プロデューサ・タスクが、特定の1分間実行されないことがあることを意味します。 このシナリオでは、すべてのユーザに自分のモニタのチェックインミスが通知されません。 Kafkaメッセージのバックログシナリオで、1分以上バックログしている場合、成功したチェックインが単にバックログにあるだけで、まだ処理されていないスケジュールされた時間のチェックインミスが発生する可能性があります。 これらはどちらも問題があるだけでなく、エンドユーザーを混乱させます。 私たちの目標は、モニターが停止したことを確実に伝えることなので、ミスしたチェックインを正しく検出することが重要です。 では、チェックイン漏れをチェックするタスクが、1)毎日毎時毎分、無期限に実行され、2)チェックインが壁掛け時計の時間より遅れても影響を受けないようにするにはどうすればいいのでしょうか? […]

Node.jsのLoaderパフォーマンスを向上させる

Node.jsは2種類のモジュールをサポートしています。 EcmaScriptモジュールとCommonJSモジュールです。 ESモジュールはJavaScriptにおけるモジュールの公式な標準であり、すべてのモダンブラウザでサポートされています。 CommonJSモジュールは、Node.jsがデフォルトで使用するモジュールです。これらはブラウザによってサポートされておらず、公式の標準でもありません。しかし、現在でも広く使われています。 Node.jsはどのようにエントリーポイントをロードするのか? どのローダーを使うかを区別するために、Node.jsはいくつかの要因に依存することを理解しておきましょう。 最も重要なのはファイルの拡張子です。 ファイル拡張子が .mjs の場合、Node.js は ES モジュールローダを使用します。 ファイル拡張子が.cjsの場合、Node.jsはCommonJSモジュール・ローダーを使用します。 ファイル拡張子が .js の場合、 package.json ファイルに “type”: “commonjs” があれば(または単に “type “フィールドがない場合)、Node.js は CommonJS モジュールローダを使用します。 package.jsonファイルに “type”: “module”があれば、Node.jsはESモジュールローダを使用します。 この決定はlib/internal/modules/run_main.jsファイルで行われます。 以下にコードの簡略版を記載します。 readPackageScope は、package.json ファイルを見つけるまで、ディレクトリツリーを上方向に走査します。 この投稿で最適化する前は、readPackageScopeはpackage.jsonファイルを見つけるまで内部バージョンのfs.readFileSyncを呼び出します。 この同期呼び出しはファイルシステム操作を行い、Node.js C++レイヤーと通信します。 この操作には、データのシリアライズ/デシリアライズのコストがかかるため、返す値/タイプによってパフォーマンスのボトルネックがあります。 そのため、readPackageScope内でreadPackage(別名fs.readFileSync)を呼び出すことはできるだけ避けたいです。 Node.jsはどのようにpackage.jsonを解析するの? デフォルトでは、readPackageは内部バージョンfs.readFileSyncを呼び出してpackage.jsonファイルを読み込みます。 この同期呼び出しは、Node.js C++レイヤから文字列を返し、後でV8のJSON.parse()メソッドを使用して解析されます。 このJSONの妥当性に応じて、Node.jsは残りのローダーの実行に必要なオブジェクトをチェックした後作成します。 これらのフィールドは、pkg.name、pkg.main、pkg.exports、pkg.imports、pkg.typeです。JSONの構文に誤りがある場合、Node.jsはエラーを投げて処理を終了します。 この関数の出力は、同じパスに対して readPackageScope を再度呼び出さないように、後で内部 Map にキャッシュされます。このキャッシュは、プロセスの寿命が尽きるまで保存されます。 package.jsonフィールドとリーダーの使用法 最適化の前に、Node.jsがこれらのフィールドをどのように使用しているかを見てみましょう。 Node.jsコードベースでpackage.jsonフィールドをパースして再利用する一般的なユースケースは以下の通りです。 pkg.exportsとpkg.importsは、入力に応じて異なるモジュールを解決するために使われます […]

Reactにおけるメモ化の不具合を修正する

Reactのメモ化を使用することで、ウェブアプリケーションを小さなコンポーネントに分割し、再利用しやすくすることができます。 コンポーネントの更新が必要な場合、Reactは再レンダリングを契機に、動的なデータやアニメーションなどを表示する方法です。 しかし、再レンダリングが必要ないコンポーネントを再レンダリングするとなると、アプリケーションのパフォーマンスに悪い影響を与えます。 以下の状況を想像してみてください。 親コンポーネントが、コールバック関数を子コンポーネントにpropsを通じて渡す場面です。 そして、子コンポーネントはメモ化されているにも関わらず、親コンポーネントが再レンダリングされるたびに子コンポーネントを再レンダリングしてしまう。 この問題を調査し、その修正方法を学んでいきましょう。 問題点 親コンポーネントは、コールバック関数を子コンポーネントにpropsを介して渡します。 子コンポーネントはメモ化されていますが、Reactは親コンポーネントが再レンダリングされるたびにそれを再レンダリングします。 何かが原因で、メモ化の特性を失わせています。 以下は親コンポーネントと子コンポーネントのコードスニペットです。 このコードを試したい場合は、こちらのCodeSandboxリンクをご覧ください。 _Numberコンポーネントには、再レンダリングごとに発生する重い操作が含まれています。 これが問題であることを特定するために、私たちはReact SDKに付属するSentryのwithProfilerメソッドを使用して、関心のあるすべてのコンポーネントをラップします。 これにより、その特定のコンポーネントのui.react.mountおよびui.react.updateイベントがキャプチャされます。アプリをリロードし、「増加」ボタンを数回クリックすると、Sentryパフォーマンスダッシュボードで以下のように表示されます。 トランザクションのうち50%がUI操作に費やされたことがわかります。 こちらについて詳細に調べる必要がありそうです。 しかし、なぜでしょうか? 私たちは_NumberコンポーネントをReactのmemo()でラップしました。 なぜそれが再レンダリングされ続けるのでしょうか? Reactと再レンダリングに関して知っていることを考えると、Reactはコンポーネントを再レンダリングするとき、それらの状態またはプロパティのいずれかが変更されたときです。 _Numberコンポーネントを見てみると、状態変数が定義されていないことがわかりますが、propsからsetMessageコールバックを受け入れています。 問題は「増加」ボタンをクリックしたときに発生します。 _Numberコンポーネントには全く関係ありませんが、それによりClosureRerenderコンポーネントが再レンダリングされ、それが_Numberコンポーネントに渡されるonClickメソッドを再作成します。 _Numberコンポーネントはメモ化されていますが、親が再レンダリングされるたびにsetMessageプロパティに異なる値を受け取り、これによりメモ化をバイパスし、再レンダリングします。 onClickメソッドは変更されないにもかかわらず、その参照が変わります。 自分で確認したい場合は、このページでコンソールを開いて、次のように一行ずつ入力してみてください。 最後のx===yコマンドはfalseを出力します。 それにもかかわらず、両方のオブジェクトは同じ値(’Lazar’)を持つ同じ名前のプロパティを持っています。 JavaScriptは、非プリミティブ型を扱う際に変数の値として参照を保持し、手動で両方のオブジェクトを作成したため、xとyは異なる参照を持ち、したがってx===yはfalseになります。 Reactでも同様です。ClosureRerenderが再レンダリングされるとき、onClickメソッドが再作成されるため、実質的に新しい参照が渡されます。 古いsetMessageプロパティは新しいものの値と一致しないため、Reactは_Numberコンポーネントを再レンダリングします。 では、これを修正するにはどうすればよいのでしょうか? 解決策 解決策としては、`useCallback`フックを使用する必要があります。 `useCallback`フックは、コールバックに対する`useMemo`や`memo()`がコンポーネントに対するものであるようなものです。 依存関係の配列に変更がない限り、コールバックの再作成を防ぎます。 新しい`onClick`メソッドは次のように記述します。 このメソッドを`useCallback`フックでラップし、`props.setMessage`を依存関係の配列に配置します。 それが変更されない限り、再レンダリングの間に`onClick`は同じ参照値を保持し続けます。 もはや「増加」ボタンをクリックしても_Numberコンポーネントの再レンダリングがトリガーされません。そして、それをSentryで検証できます。 ずっと良くなりました。 不必要なui.react.updateイベントもなく、長時間実行されるUIブロッキングタスクもありません。 結論 `useMemo`フックや`memo()`メソッドは、常にコンポーネントが不必要に再レンダリングされるのを防ぎません。 今回の記事のようにメモ化を壊してしまう場面があり、それによってパフォーマンスが損なわれることがあります。 これは、`useCallback`フックを使用しないコールバックメソッドを渡す場合だけでなく、`setMessage={(number) => props.setMessage(number)}`のようにコールバックをインラインで定義する場合にも発生する可能性があります。 慣習的にコードを書いていると思うので「それが何を引き起こすか」にまでは、あまり注意を払っていないかもしれません。 今回のように、これらの状況をアプリ全体で修正したことを検証し、Reactアプリのパフォーマンスを監視し始めるために、アプリにSentryを導入してみてください。 開始は無料で、インストールも簡単です。 SentryがReactアプリに対して何ができるかをもっと詳しく知りたい場合は、Sentry […]

;