FastCo.が選ぶ2022年最も革新的な企業の一つで、プラットフォームの安定性を最優先する

プラットフォームの安定性を最優先する

フィットネス業界では、ずいぶん前に「スマート」な機器をビジネスモデルに取り入れていました。 最近では、ユーザー体験の高さで差別化をはかり、競い合っています。 安定性と品質は、プロダクトの成功に不可欠です。 これはトナール社の開発者たちにとっての最重要課題でした。 「ユーザー数は多いのですが、バグを報告するユーザーは比較的少ないです。私たちは非常に安定した製品を持っており、目標はそれを維持することです。- トナール社、モバイルソフトウェアエンジニアリングシニアマネージャー、マックス・ラピデス氏」 トナール社は、ニューヨークマガジンのベストスマートホームトレーニングソリューション2022年にランクインしています。 また、メンズヘルスでも、ベストコネクテッドケーブルマシン2022にランクインしています。 トナール社は、スマートホームトレーナーの業界水準を定めており、その標準を維持するために、開発者たちは製品がユーザーの期待に応えられるように、今までとは違うアプローチをとっています。 彼らは、製品の問題を減らすだけでなく、完全に無くすことに注力しています。 「エラーやクラッシュを減らそうという意識は持っていません。なぜなら、私たちは、システムがクラッシュすることを想定しておらず、システムはクラッシュしないと想定しています。」 バグのないUXを実現するワークフロー 当たり前ですが、システムエラーはどのシステムにも存在します。しかし、そのエラーがユーザーに影響を与えることを防がなければなりません。 そのためには、パフォーマンスモニタリングと自動エラーレポートを開発作業に取り込む必要があります。 マックスのチームは、Debug Symbolを使用して、エラーログをデバッグの段階で活用することでこれを実現しました。 そして、スタックトレースからSentryが提供する追加のデータコンテキストを使用しています。 例えば、このスタックトレースだけでは、必要なコンテキストデータがあまり得られないため、デバッグには使えません。 しかし、マックスのチームがデバッグ用のシンボルをSentryにアップロードすると、シンボル化されたスタックトレースができてしまいます。 「Sentryがなければ、これらのデバッグ用シンボルファイルを収集する必要があります。Sentryは、App Store Connectや CIシステムからのアップロードから自動的に収集します。これにより、不明瞭で難解なデータを人間が読めるものに変換することができるようになります。」 トナール社がスムーズなUXを維持するもう一つの方法は、Sentryにパンくずリストを設定することです。 これにより、問題を調査している開発者たちは、エラーにつながったユーザーのアクションを時系列で確認することができます。また、問題を再現し、迅速に解決するために必要なすべてのコンテキストも確認することができます。 「これらのユーザーイベントは、デバッグに役立つアプリ内のユーザーのアクションの流れを表していることに気づきました。そこで、現在ではこれらのユーザーイベントもパンくずリストとしてSentryに送信しています。 これにより、Sentryを起動したまま、問題が発生する前のユーザーの行動を正確に把握できるようになりました。」 例えば、新機能のエッジケースのテストでQAエンジニアが、UIの問題を見つけることがあります。 Sentryは、ユーザーがエラーに至るまでに行ったHTTPリクエストや、ユーザーが行ったナビゲーションなど、その問題に関するリアルタイムのデータを表示してくれます。 また、Sentryは担当チーム、Flutterのバージョン、ビルド番号などの詳細なコンテキストデータも提供してくれます。 これにより、対処可能なバグレポートを提出することが簡単になります。 バグレポートには、問題を再現し、最終的に解決する方法について、十分な情報が詳細に含まれています。 コードを “即断即決で “修正することなどありえない トナール社は、2019年から続いている2週間のスプリントとデプロイの徹底した周期に従っています。しかも、そのペースは2019年から変わっていないそうです。 規則的で予測できるリリースは、安定して高性能なユーザー体験を提供するための高い基準をチームに課すことになります。しかし、モバイルでは、その場でコードを修正することは、あまり現実的ではありません。 「AndroidとiOSの両プラットフォームに対応したアプリを再構築する必要があります。そして、24時間から48時間かけてレビューを行い、Google PlayとApp Storeの両方にリリースすることができます。その後、ユーザーの端末で自動的にアップデートされるのを待ちます。重要な機能を追加する場合は、さらに3日ほどかかることもあります」 そのため、マックスのチームはデプロイ前の約一週間、QAでビルドを確認し、リリース用のダッシュボードで監視するようにしています。 リリースは個々のビルド番号で標準化されており、QAを通過すると、チームは最新のビルド番号を「ゴールドマスター」と宣言します。 これで本番リリースの準備が整います。 「Sentryで重大な問題が確認された場合、通常48時間以内に修正することが可能です。しかし、目標はこうした問題が本番環境で発生しないことです。」 トナールのチームは、プラットフォームの安定性、復旧力、ユーザー体験に重点を置いています。マックスのチームは、開発能力とSentryのカスタムソリューションを組み合わせているため、以下のようなことができるようになります。 詳細なコンテキストデータを含むエラーを積極的に監視します。 プラットフォームの安定性とUXに直接影響を与えるエラーを簡単に優先順位付けすることができます。 品質を犠牲にすることなく、きっちりとリリーススケジュールを維持します。 アプリ内のユーザー行動を分析し、解決までの時間を短縮します。 ユーザーに高いパフォーマンスのUXを提供することで、他社よりも優位になります。 「Sentryは、私たちがプラットフォームの安定性を維持するのに役立ちます。 Sentryは、ユーザーたちに直接影響を与えるようなコードをリリースするのを防いでくれます。私たちにとって良い日とは、クラッシュがないときです…それが毎日ならいいですが」     Sentryは、アプリケーションコードの健全性を監視するために不可欠です。エラートラッキングからパフォーマンスモニタリングまで、開発者は、フロントエンドからバックエンドまで、アプリケーションをより明確に把握し、より迅速に解決し、継続的に学習することができます。 […]

Pythonのプロファイリングでコードレベルでボトルネックを解決

Pythonのプロファイリング

プロファイリングは、最も重要なツールです。 プロファイリングを利用することで、本番環境で実行中のプログラム情報を詳しく見ることができます。 パフォーマンスのボトルネックは、ローカルで再現するのが非常に困難であったり、不可能であったりすることがよくあります。そのため、この機能はとても重要なのです。 再現が困難である理由は、外部制約や本番環境特有の負荷が理由にあります。 Pythonは、最も人気のあるプログラミング言語の一つです。 SentryもPythonをメインに開発しています。Pythonのプロファイリングは現在ベータ版です。しかし、sentry-sdk==1.11.0を利用することでWSGIアプリケーションで利用可能になります。 これにより、実運用でのアプリケーションのパフォーマンスについて、コードレベルで把握することができます。 Pythonのプロファイリングを始めるには、SDK上でprofiles_sample_rateを設定するだけです。 SDKは100ヘルツのサンプリング周波数でサンプルを取得する別スレッドを実行します。 プロファイルが終了すると、サンプルはSentryに送られ、プロファイルがフレームチャートとして可視化されます。 フレームチャートは、エンドポイントや遅いトレースにおいて、頻繁に実行されるコードを素早く見つけ、リソース消費(例:CPU)を最適化することができます。 SentryプロファイリングでSentryを改善する 長い間、Sentry上でPythonプロファイラの内部バージョンを実行することで、Sentryを最適化することができました。 日付時刻と連携 多くの人は、時系列で確認できることほど嬉しいことはありません。そのため、Sentryの様々なところで時系列グラフを用意しています。しかし、時系列グラフの生成には時間がかかります。 処理が重い箇所を調査したら、 discover.discover – timeseries.transform_results が原因である可能性があることがわかりました。 さらに調査を進めると、この関数が本当に原因であることがわかりました。 たまに数百ミリ秒の遅さになることがあり、これはデータ取得のクエリよりも遅いです! 実はクエリよりも後処理の方が遅いんです! コードを見ると、単純な変換をしているだけでした。そのため、根本的な原因はすぐには分かりませんでした。しかし、プロファイルを見ると、リクエストの大半が、ゼロフィル(データが全て0埋めになっている状態のこと)内で日付のパース処理だということがわかりました。 ゼロフィル内の日付時間のパース処理でした! これを知った時は驚きました。 検証するために、いくつかの簡単なベンチマークを行ました。また、日付と時刻の文字列をパースするいくつかの方法を比較してみました。 それは衝撃的事実でした。なぜなら、dateutil.parser.parseからdatetime.datetime.fromisoformatに変更することで、数百倍速くなる可能性があるからです! datetime.datetime.fromisoformatは完全なISO 8601通りのパース関数ではありません(とりあえずはPython 3.11までは)。しかし、我々はdatetime.datetime.isoformatに満足していました。なぜなら、この一行を変更するだけで、最悪な状況が大幅に改善されるからです。 Django:プリフェッチするかしないか プリフェッチはDjangoでよく採用されるテクニックです。 これは、関連するオブジェクトにアクセスする時に、大量にデータベースクエリが発生するのを防いでくれます。 オブジェクトごとに1つのクエリを作る代わりに、プリフェッチすることによって、関連するすべてのオブジェクトを一度に取得する一つのクエリを作ることができます。 Sentryの様々な場所でこの技術を採用しています。しかし、ユーザーのエンドポイントが非常に遅いことに気づきました。大きな影響を与えずに、関連するオブジェクトにプリフェッチを使用するようにしました。 いくつかのトランザクションを見ると、興味深いことがわかりました。 それは監視できていない期間があったのです。さらに最も興味深いのは、それがいくつかのデータベーススパンに散らばっていたことです。 また、コードを調べてみると、これらのデータベーススパンは以下のクエリに対応していることがわかりました。 最初のクエリはOrganizationMemberに対するもので、それに続く3つのクエリはprefetch_related内で指定された3つのルックアップに対するものです。 プロファイルを調べると、prefetch_related_objectsがありました。これはDjangoの内部呼び出しで、リクエストの大部分を占めています。 OrganizationMemberとTeamの間の多対多の関係、そしてTeamとProjectの間の多対多のリレーションクエリをしていたことがわかりました。 prefetch_relatedを使ったクエリは高速でしたが、Djangoは結合処理を実行していました。つまり、一部のチームとプロジェクトを取得しただけですが、 DjangoはすべてのOrganizationMember、Team、Projectを繰り返し、関連するオブジェクトを属性として設定していました。 この知識をもとに、クエリの書き換えに取り掛かりました。 Pythonでこの結合処理を実行したくはなかったのです。prefetch_relatedを削除し、関連するオブジェクトを手動でフェッチし、レスポンスを丁寧に構築することで、これを達成することができました。これにより、p95は50%近く減少しました! プロファイリングはパフォーマンスを補完する プロファイリングは、Sentryパフォーマンスを完璧に補完します。 パフォーマンスが問題を大まかに把握することができますが、プロファイリングは正確なプログラムのコード行番号まで把握することができるので、簡単に問題を解決することができます。 コードのプロファイリングをできるようにするために、まずすべてのサービスをSentryのパフォーマンス製品で接続するようにしました。 Sentryは、サービス全体のレイテンシー問題を把握することができます。 これにより、プロファイルとトランザクションを簡単に関連づけることができ、遅いリクエストの根本原因を特定することができます。 パフォーマンスのダッシュボードは、アプリケーションがどのように動作しているかのを把握するのにも役立ちました。プロファイリングを導入する前と導入した後を比較すると、P75の時間やスループットなどを簡単に把握することができました。 早速いまからプロファイリングを始めてみましょう。 最初に「パフォーマンスを計測する」を確認してください(わずか5行のコードで可能です)。 […]

Pythonのテストを数百の環境で高速に実行する方法

Pythonのテスト

長文を読む気分ではない方は、ここからDjangoCon 2022で行われた講演(英語)を見ることができます。 Sentryの信念のひとつに「すべての開発者のために」というものがあります。 すべての開発者をサポートしたいと思っています。しかし、すべての開発者が最新の技術や広く採用されている技術スタックを使っているわけではありません。そのため、古いバージョンのライブラリやフレームワークもサポートするように心がけて取り組んでいます。 当社のSentry SDK for Pythonでは、次のことをサポートしています。 約20種類のWebフレームワーク Python2.7を引き続きサポートします(!) Python 3.5から3.11まで対応しています 古いバージョンのフレームワークをサポートしています。(例:8年前のDjango 1.8をサポートしています) SDKが正しく動作することを確認するために、テストスイートには約450の自動テストが用意されており、SDKに変更を加わるたびに実行されます。 7つのPythonのバージョンと約20のフレームワークをサポートしているため、それぞれのフレームワークのバージョンが2~9になると、テストを実行する環境は400を超えます。 テスト用スタック テストスイートはpytestを使用して実行されます。 テスト実行前に、Flake8とblackを使ってソースコードのリントとフォーマットを行い、mypyを使って型チェックを行っています。 Toxは、さまざまな環境でテストスイートを実行するためのツールです。 ローカルマシンの異なる環境でテストスイートを実行するために、古き良きmakeを使用しています。そして最後に、GitHub ActionsをCIとして使用し、すべてのプルリクエストに対してすべての環境でテストスイートを実行できるようにしています。 スローテスト 私たちのテストセットアップは何年も前に作成され、時間の経過とともに多くのテストが追加されました。 しかし、テストセットアップ自体をリファクタリングする時間がありませんでした。そのため、テストスイートを実行するのに約40分も時間がかかっていました。 このようなテストスイートは、苦痛でしかありません。 SDKの新しいバージョンをリリースする際には、リリースごとにテストスイートを実行するため、テストが完了するのに最大で1時間もかかることもありました。 これは由々しき事態です。そこで私たちは、テストスイートの改善に取り組みました。 テストスイートを高速化する すべてのテストをリファクタリングすることなく、より速くテストを実行する方法について、いくつか考えました。どのようなことをしたのかをご紹介します。 フレームワークごとにテストスイートを分割 テスト実行にかかる時間を大幅に短縮 開発者の生産性を向上 考えた結果、テストそのものではなく、テストの実行方法を変えようという結論に至りました。 まず、テストスイートを改善するのに着目したのは次のことです。それはいままでそれぞれのプルリクエストで、すべての環境でテストスイートを実行するGiHub Actionsランナー1つでToxを起動し、1つずつ実行していました。 これは、テストを実行する上で最も遅い方法であり、1回の実行に38〜42分はかかります。 アイデア1:toxでテストスイートを並列に実行する Toxのコマンドラインには、–parallel autoオプションがあり、利用可能なCPUコアの数だけテストスイートを並列実行することができます。 これにより、すでにテストの実行時間は劇的に改善されました。 今まで40分かかっていたテストが、25分程度になったのです。しかし、これではまだ「速い」とは言えません。 GitHub ActionsのランナーはCPUコアを2つしか持っておらず、使用できるCPUコア数には限界がありました。 アイデア2:GitHub Actionsを使ったテストスイートの並列実行 GitHub ActionsのランナーのCPUを増やすことはできませんが、GitHub Actionsのランナーを増やすことは可能です(大きなマシンを購入しない場合)。 そこで、テストを実行するすべての環境に対してGithub Actionsの設定yamlファイルを作成するスクリプトを作成しました。 アイデアとしては、このようなものでした。 しかし、GitHub Actionsの同時実行できるワークフローにも制限があることがわかりました。 私たちはGitHub […]

コードカバレッジインサイト – スタックトレースで確認できるようになりました

コードカバレッジインサイト

その理由 コードカバレッジとは、テスト手法の一つで、どのコードがテストされているかを知らせるもので、パーセントで表示されます。 コードカバレッジは、コードの総行数のうち、全体の何割がテストされているのかを把握することができます。 また、テストを書くことはとても大変です。しかし、コード変更があると、せっかく書いたテストコードも変更内容をテストできているかがわかりません。 このストレスから、共同創業者のイーライ氏と私は、テスト駆動開発で解決したいと思うようになりました。 私たちは、(まだ)存在していないものを作ることが好きです。 また、ほとんどの開発者はエラーが発生するコードのテスト状況を見たいだろうと思っていました。 しかし、SentryがCodecovを買収したとき、次のような反応が最も多かったです。 それは私たちもとても感じていました。 Codecovを使ってコードレビューしても、デプロイ後の作業にはあまり役立ちませんでした。 長い間、ユーザー/顧客向けの製品に携わる開発者は、”OK、でも次の問題は何?”ということに向き合ってきました。 その問題は、おおよそ次のように表現されます。 アプリでエラー・不具合内容を受け取る エラー周辺のデータを開く(アプリケーションのパフォーマンス監視と例外処理) “よし、でも次はどうする?“ 別画面で自分のIDEを開く 2つの画面を見渡し、コードのメンタルモデル(価値観やイメージのこと)を構築する。 そのコードにテストがあるのなら、根本的な原因を修正する方法を考える。 必要であれば、今後同様のエラーが発生するのを防ぐために、基となるソースコードを変更し、テストを記述・編集する。 さらに一歩踏み込むと… もしエラーが発生するコードがテストされていない場合、次のステップは、このケースを中心にテストを書くことかもしれません。 または もしエラーが発生するコードがテストされていた場合、次のステップとして、問題のテストとコードのロジックとの関連性を調査します。例えば、テストケースに見落としがないかを確認します。 SentryのスタックトレースにCodecovを導入することは、本番前とデプロイ後のデータ連携を実現する最初の取り組みです。 これにより、問題が発生した際のデバッグやパッチ適用がより迅速かつ容易になります。 何を? ひとことで言うとCodecovのSentry連携を使えば、Sentry Issueのスタックトレースでエラーの原因となる未テストのコードを直接確認することができます。 この機能を使うことで、さまざまなユーザー操作を考えたり、コードを手動で分析したりする必要はもうなくなります。 SentryにCodecovを導入すれば、テストするべき優先箇所を正確に把握できるので、時間を無駄にすることなく、信頼性の高いコードを維持することができます。   テストカバレッジを改善するために、数ヶ月に一度「カバレッジ週間」を設けて、コードのテストを改善していました。しかし、SentryとCodecovの連携により、コードを分析し、テストカバレッジが必要な箇所を考えることはなくなりました。さらに、Sentryが取り組むべき箇所を正確に教えてくれるので、テストカバレッジの構築に費やしていた時間を約50%ほど削減できました。 – アレックス・ナサネイル(技術担当ディレクター)@vectare.co.jp   Codecovの使用方法 前提条件: Sentryの場合 SentryのGitHubインテグレーションをインストールし、Codecovにテストカバレッジデータがあれば、使い始められます。 また、GitHubインテグレーションにCode Mappingsをセットアップする必要もあります。これはテストカバレッジを表示するためのソースコードファイルを把握するのに必要です。 GitHubを使われていない方は、GitLabとBitbucketは対応中ですので、しばらくお待ちください。 Codecovの場合 Codecovにサインアップするだけです。一度アカウントを取得すれば、テストされていないコードが本番環境でエラーを引き起こしている箇所をワンクリックで確認できます。 コードカバレッジは初めてですか? 大丈夫です。詳しくはこちらをご覧ください。 SentryとCodecov – スタックトレースでコードカバレッジを即座に確認できるようになります。 最も簡単な方法 – 全く何もする必要はありません。両方のサービスでセットアップされたときに、自動連携を有効にする日次ジョブを実行します。 簡単な方法 – すぐにでも始めたい場合は、設定ページに移動し、「コードカバレッジインサイトの有効化」をオンにしてください。 […]

Sentryのプロファイリング: コードレベルでパフォーマンスのボトルネックを特定し排除する

Sentryのプロファイリング

ユーザーからロードが遅いと言われたため、ログやトレース、メトリクスを通して分析をしました。 さらに、アプリケーションのパフォーマンスの原因を特定するために、利用可能なデータはすべて分析しました。 しかし、それでもボトルネックの原因を突き止めることはできませんでした。 もしかしたら、監視が十分じゃなかったのかもしれません。 あるいは、本番環境と大きく異なる環境でテストしているだけかもしれません。 いずれにせよ、根本的な原因を突き止めるのに、精神的負荷と時間がかかります。 このようなパフォーマンスの悩みを解決するために、プロファイリング機能を構築しました。 現在、Python、Node.js、iOS、Android、PHPでは、最新の料金プランで利用可能です。 プロファイリングは、パフォーマンスの問題を引き起こしているプログラムの行番号までピンポイントで特定するため、Sentryのパフォーマンスを向上させます。 プロファイリングは、関数の実行時にその実行時間に関する本番環境のデータを収集します。 そして、その結果を集計して、あらゆる環境におけるアプリケーションのパフォーマンスを把握することが可能になります。 実行時間を推測したり、パフォーマンステストを書いたりする代わりに、アプリケーション内で非常に多く実行されるコードを確認し、パフォーマンスのボトルネックを素早く特定することができます。 さらに、プロファイリングは手作業による計測にかかる時間を短縮するため、導入後すぐにパフォーマンスを計測することができます。 プロファイリングによってパフォーマンスチューニング作業がどれくらい楽になり、ボトルネックをどのように修正するのかをご紹介します。 また、SDKのサポートに関する最新情報についてもご紹介します。 こちらは、動作の遅い関数からアプリケーションフレームやコールツリーまで掘り下げて、問題の原因となっているプログラムの行番号を特定するデモ画面です。   プロファイリングを始める準備はできていますか?詳しくは価格ページをご覧ください。 トランザクションからプロファイルまで掘り下げる Sentryパフォーマンスでは、トランザクションと期間ごとに、個々のサービスとそのサービスのパフォーマンスを表すトレースを収集することができます。 トランザクションを監視して、速度低下の原因となっている期間を特定するのに役立ちますが、多くのタスクで長時間実行される箇所の原因を特定するのは難しい場合があります。 長期間を小さく分割して計測するのではなく、プロファイリングを使用することで必要なコンテキストを提供することができます。 プロファイリングデータがあると、最も頻繁に発生するコールスタックが表示され、最適化すべきコードを教えてくれます。 以下の例では、特定のコールスタックが収集したサンプルの84.3%に、アプリ内関数の最上位がBigTableKVStorage.get_manyで、GCPのビッグテーブルクエリを実行していることがわかります。 詳細を見ると、その関数が定義されている正確なファイルと行番号がわかります。 さらにデバッグが難しいシナリオとして『一部のデータが抜けているケース』が挙げられます。 観測できていない箇所を推測する代わりに、プロファイリングはその時間帯に実行されるコードを教えてくれます。 これによって、コードのどこを修正する必要があるかがわかるだけでなく、このプレビューによって、新しく監視する箇所を追加しなくても根本的な原因を見つけることができます。 この例では、観測できていなかった474msまでの間が、Redisクラスタへの接続をしていたことがわかります。 さらに、フレームチャートビューアでは、すべてのスレッドのデータを含むプロファイル全体を表示します。 トランザクションデータはプロファイリングデータとインラインで表示されるため、その時間に関連する機能をシームレスに関連付けることができます。 フレームチャートの操作方法と解釈方法についての案内を作成しました。 開発者のヴィトール・カリクストはプロファイルを利用して、Azos Segurosの顧客保険金の分割払いサービスのパフォーマンスを向上させています。 ヴィトールは、フレームチャートを使用して、パフォーマンスの問題に関連するプロファイルを掘り下げ、リクエストが遅くなっている原因の関数コールを特定し、迅速に対応しました。 これにより、リクエストの実行時間が大幅に改善されました。 フレームチャートを使って、顧客決済サービス内で最も遅いデータベースリクエストを見つけることができました。 プロファイリングを使用することで、リクエストの実行時間を1000msから300msに短縮することができました。– アゾス・セグロス社  Vytor Calixto氏 プロファイリングで改善されるパフォーマンス問題 プロファイリングは、トランザクションデータをグループ化して、共通のパフォーマンス問題を検出するなど、パフォーマンス機能を補うものです。 プロファイリングデータが問題をコードレベルで可視化することによって、検出できることが増えます。 プロファイリング・データを活用する最初の新しい課題タイプは、iOSとAndroidでサポートされるJSON Decoding on Main ThreadとImage Decoding on Main Threadの2つです。 例えば、画像のデコード処理(ファイルの解凍などのこと)をメインスレッドから別スレッドに移動させることで、メインスレッド時間を150ミリ秒程度短縮できたことがわかります。 さらに、UIジャンクの発生やスクロール性能の低下を防ぐこともできます。 […]

Sentryでもっと早くトリアージし、安らかな睡眠を

Sentryでもっと早くトリアージ

開発者にとって、トリアージする月の1週間は、しばしば憂鬱でした。 トリアージとは、バグが報告されるたびに、手作業でログを分析し、関係するスタックトレースがあることを期待し、そして記憶を頼りに適切なチームへ連絡することでした。 トリアージをする開発者は、バグを適切なチームに連絡する必要があります。また、バグを調査するのに必要な情報を併せて報告する必要があります。 十分な情報がない場合、開発者はプロダクトを作成するよりも多くの時間をデバッグに費やすことになります。 現在、Sentryは400万人以上の開発者のトリアージとコンテキスト収集作業を最適化してくれます。しかし私たちは、さらに課題解決までの時間と課題解決率を向上するように努めています。 課題解決率および解決までの時間の改善 課題のトリアージは、4つのフェーズに分けることができます。 検知 通知 アサインメント 解決 ユーザーからのフィードバックやインタビューに基づく、通知やアサインメントの改善は、より良い結果をもたらすと考えました。 具体的な改善点として、以下の2点に着目しました。 サジェストでアサインメントの改善 関係ない通知によるノイズ低減 アサインメントの改善とアラートノイズの低減 簡単に課題を特定し、適切なチームや開発者にアサインすることができるようになります。 各課題について、担当者はSentry組織内のメンバーまたはチーム内で、最も詳しい情報を持っています。 Sentryは、3つのシグナルに基づいて、課題をサジェストします。 サスペクト(疑わしい)コミット – Sentryは、問題が起きたコードを最近変更した開発者を特定します。 所有権ルール – Sentryは、イシューのタグやコードなどに基づいて、適切にSentryチーム/メンバーを見つけるためのルールを評価します。 コードオーナー – SentryはGitHub/GitLabのCODEOWNERSファイルを解析し、コードに基づいて、イシューに適切なSentryチーム/メンバーを設定してくれます。 お客様からのフィードバックを目にして、ユーザーが確実かつ迅速に課題をアサイン、解決するのに役立っていることを知りました。 そして、より多くのユーザーがサジェストアサインを利用できるように、ここ数ヶ月で様々な機能を追加しました。 Git Blameを使ったサスペクトコミットについて サスペクトコミットは、Sentryでは問題の原因となっているファイルを最後に変更した人を表示するだけでした。 しかし、Git Blame API連携することで、Sentryは特定のコード行を変更した人、および問題の原因となったコードのプルリクエストを特定することができるようになりました。 また、イシューを自動的にコミット作成者にアサインすることができるようになりました。 この機能は、GitHubまたはGitLab連携を利用すれば、誰でも利用できます。 組織でこの機能を有効にする詳しい方法は、以下をお読みください。 コードマッピングを自動で設定 怪しいコミットを見つけるために、Sentryはエラーの原因となるファイルとリポジトリ内のソースコードファイルを結びつける必要があります。 しかし、これを正しく設定するのはなかなか難しく、ユーザーがこの設定を怠っていることに気づきました。 そのため、SentryのGitHub連携を利用するユーザーのために、この設定を自動化するようにしました。 Sentryは、Python、JavaScript、Node、Rubyなどのプラットフォームのソースコードと、エラーの原因となるコードを自動的にマッピングしてくれます。 この自動化されたセットアップにより、Sentryはさらに多くの怪しいコミットを見つけてくれるようになります。 不要なSentry通知を減らす Sentryでは、新しいプロジェクトを作成すると、デフォルトのイシューアラートルールが作成されます。 しかし、このルールはアサインできる人がいないイシューに対して、同じプロジェクトで作業しているチームメンバーに対して、通知を行う可能性があることに気づきました。 このアラートルールを使うことで、そのプロジェクトの全メンバーに迷惑をかけることなく、チームに通知できるように変更しました。 より良い結果を出すために ここでは、ユーザーがどのように問題解決をするか、その過程を紹介します。 Sentryはイシュー担当候補者がいる場合、アラートルールに従って、適切な開発者、チーム、Slackチャンネルに通知することができます。 これにより、開発者に不要な通知を減らし、チームにとって重要なイシューに集中してもらうことができます。 この利点は、イシューの担当候補者が増えれば増えるほど大きくなります。 さらに、Sentryがデフォルトのイシューアラートルールを変更したことで、問題を迅速にトリアージする能力を維持しながら、全体で不要な通知を33%削減することができました。 […]

Sentryの新しい予算配分とスパイク保護で安心して複数のプロジェクトを管理

Sentryの新しい予算配分

本日、新しいSpend Allocation(予算配分)機能とSpike Protection(スパイク保護)のアップデートを発表します。 これにより、Sentryユーザーは、プロジェクトがどのようにイベントを消費するかをよりコントロールできるようになります。 私たちは、お客様がプロジェクトにSentryを簡単に追加できるように製品を開発してきました。 しかし、コミュニティからは、ノイズの多いイベントデータを扱うプロジェクトで、イベント枠を消費しすぎないようにするための方法がもっと欲しいという声を聞き続けていました。 そこで私たちは、Spend Allocation(予算配分)を構築し、Spike Protection(スパイク保護)を更新しました。 これにより、Sentryを大規模に利用する皆様は、イベント消費のレベルが異なる複数のプロジェクトやチームを簡単に管理できるようになりました。 なぜか プランによっては、毎月Sentryに送信できるイベント数に上限が設定されています。 その数を超えると、Sentryはあなたのイベントを削除し始めます。 この場合、アプリケーションの状態を把握することができなくなります。 インバウンドフィルタ、メトリックアラート、レートリミットなど、イベント消費を管理するためのツールを用意していますが、さらにコントロールを容易にしたいと考えました。 これにより、プロジェクトでイベントが大量に発生するような予期せぬ事態が発生しても、ペナルティを受けることがないようにできます。 Spend Allocation(予算配分)とSpike Protection(スパイク保護)の向上 予算配分は、予約エラー、トランザクション、添付ファイルに対して、プロジェクトごとに最小限のイベントの閾値を設定することができます。 この設定はリアルタイムで行うことができ、すべてのプロジェクトに公平な割り当てを行うことができます。 また、スパイク保護のアップデートは、その名の通り、イベント量の予期せぬ異常な急増からお客様を保護します。 Spike Protection(スパイク保護) – 何が変わったか 予約した容量を使いながら、月内に十分な視認性を確保できるようにしたい。 しかし、インシデントは起こります。 Sentryに送信されるイベントが急増することがあります。 このような場合、数時間または数分で月間クォータを使用することができます。 ユーザーからのフィードバックに基づき、イベントスパイクからお客様を保護するための従来のアプローチには、主に2つの問題があることが判明しました。 「調整」が早すぎる。 数時間以上続く正しく認識されたスパイクを「非スパイク」と誤判定することがあった。 スパイクの閾値が単純に高すぎる場合がある。  その結果、スパイクが捕捉されないことがある。 これらの要因により、スパイク保護機能の有効性が損なわれていました。そこで、スパイク保護の機能を以下のように改善し、ユーザーの保護を強化することにしました。 スパイクはプロジェクトごとに検出されるため、よりきめ細かい制御と可視化が可能です。 スパイクがトランザクションと添付ファイルを検出するようになりました。 アルゴリズムが更新され、イベントスパイクの検出がより正確になりました。 Stats(統計)ページで、プロジェクトごとのスパイク防止閾値を確認できるようになりました。 また、「スパイク保護のアップデートにより、イベント数上限を超えずに管理することができた」というお客様からの声もいただいています。   「スパイク保護は、データ移行の失敗から私たちを救ってくれました。一晩中、そして朝のピーク時まで、1つのスパイクが原因で、1日のイベント量が6000%増加しました。Sentryは、数時間以内にすべてのクォータを使い果たすことから私たちを救ってくれました。」-Vectare社テクノロジーディレクター、Alex Nathanail氏   フィードバックを共有し、改善の詳細を得るには、GitHubのディスカッションに参加してください。 3つのステップで、アカウントのスパイク保護をオンにします。 Organization(組織)の設定に移動する 左のナビバーにある「Spike Protection」をクリック プロジェクトのすべて(または一部)に対してSpike Protectionを有効にするかどうかを選択します。 なぜ、プロジェクトでスパイク保護を有効にしなければならないのか、という疑問があるかもしれません。 スパイクに関係なく、すべてのデータを確認したいお客様もいらっしゃいます。例えば、開発・テスト段階であれば、すべてのイベントを見ることができれば便利です。 Spend […]

SentryのUnity SDKの始め方 – その1

SentryのUnity SDKの始め方

ユーザー体験とパフォーマンスは、どんなゲームでも最も重要な2つの指標です。どのようなプラットフォームでも、可能な限り最適な状態で動作するようにする必要があります。 理想を言えば、プレイヤーから「動かない」「壊れている」と怒られるのは避けたいところです。また、ゲーム内で発生した問題が、その関連情報とともに通知されることが求められます。 そこで、Sentryの出番です。 Sentryは、開発者がアプリケーションを監視して、重大なエラーやパフォーマンスの問題について把握するのに役立ちます。さらに、ゲーム内のエラーを追跡する重要なコンテキスト情報を提供するため、迅速に修正することができ、プレイヤーに満足してもらいやすくなります。 また、Unityと統合したSDKを提供することで、開発者がゲームを監視することを容易にしてくれます。 このシリーズでは、SentryのUnity SDKをセットアップして、ゲームのエラーやパフォーマンスの問題を監視する方法について説明します。 入門編 前提条件 はじめに、以下のものがインストールされていることを確認してください。 Unity Hub Unity Package Manager – Unity Hubをインストールした場合、Unity Package Managerもインストールされているはずです。 Sentryのアカウントを作成する すでにSentryのアカウントをお持ちの場合は、このステップをスキップすることができます。お持ちでない場合は、Sentryに移動し、無料のアカウントを作成してください。 アカウント作成後、このような画面が表示されます。 「Install Sentry」をクリックして進むと、新しい画面に遷移します。そこで、監視するプラットフォームとしてUnityを選択します。 最後に、「Create Project」をクリックして、Sentryプロジェクトを作成します。 Sentry SDKの設定 Sentry SDKは、Unityエディタ内で直接インストール、設定することができます。 Sentry SDKのインストール ここでは、Unity Package Manager経由でSDKをインストールすることをお勧めします。 プラスアイコンをクリックすると、パッケージマネージャがパッケージを取得するためのGitHubリポジトリURLを指定するオプションが表示されます。 https://github.com/getsentry/unity.git#0.27.0 インストールが完了すると、以下のようなアウトプットが表示されるはずです。 いくつかのバグをトリガーに、ゲームをクラッシュさせるデモシーンを含むサンプルがあり、オプションでインポートすることができます。 そして、SDKがイベントの送信先と関連するプロジェクトを知るためには、SentryプロジェクトのDSN(データソース名)を追加する必要があります。これは、[ツール] -> [Sentry]に移動して設定することができます。 [Sentry]をクリックすると、以下のようなセットアッププロンプトが表示されるはずです。 「Start Wizard」をクリックし、ウィザードを初期化します。すると、Sentryは自動的にブラウザタブを立ち上げ、既存のプロジェクトをエディタにインポートします。 もしプロジェクトが1つしかない場合、設定ウィザードは終了します。複数ある場合、Unityのゲームと関連づけるプロジェクトを選ぶプロンプトが表示されます。 最後に、同梱のサンプルを使用するか、次のようなスニペットで独自の例外を投げることで、Sentryが期待通りに動作しているかを確認することができます。 上図は、スニペットで発生した例外のエラーイベントを示しています。 SDKはこれを自動的にキャッチアップし、Sentryに送信し、issueとしてリストアップしてくれます。 最新リリースでの新機能 エラーのキャプチャーは、Sentryの多くの機能の1つに過ぎません。Sentryの最新版では、Unityのエラー診断と修正に役立つ多くのユーティリティが追加されました。 iOS、WebGLなどでもUnityをサポートするようになり、開発者はデスクトップアプリケーションの監視サポートも可能になりました。しかし、Sentryはそれだけにとどまりません。次のような機能も追加されました。 すべての対応プラットフォームに対応したシンボルの自動アップロード 以前は、画面のフリーズを検出する方法がありませんでしたが、メインスレッドが5秒以上フリーズした場合に、自動的にイベントを作成するようになりました。 […]

アプリケーションのパフォーマンスを機能的に操作する方法

アプリケーションのパフォーマンスを機能的に操作する方法

私は開発者として、そのアプリケーションがどのように動作すべきか、非常に強い関心を抱いています。 高速に動いた結果、何かを壊すことには興味がありません。正直、世界を変えることにも興味はありません。 快適で人間工学に基づいたソフトウェアを作ることに興味があります。そして、その対価としてお金を貰いたいという思いが強くあります。 私の会社「Buttondown」は、そんな思いから生まれました。Buttondownは、メールやニュースレターを送信するためのツールです。 市場にはこの手のツールはたくさんあります。しかし、Buttondownの強みは「ミニマリスト」であるということです。開発者にとって快適な体験を提供しています。 それはプログラムへのアクセス、アクセシビリティ、そしてパフォーマンスを優先しているためです。 しかし、アプリケーションの性能は時間とともに劣化する 開発者たちはみんな「高パフォーマンスを意識して開発しなければならない!」と考えています。 その意志は常に正しいです。一方で、簡単なことではないことも知っています。 新機能の立ち上げ時には、可能な限り慎重にリリースします。 APIルートごとのデータベース呼び出し回数や負荷テストなど、厳しいテストを実施しています。 誰かが非常に遅いエンドポイントについてバグレポートを提出した場合(あるいは、タイムアウトに関する例外が発生した場合)、私はできるだけ早く対応します。 これは簡単で、テストも可能です。 しかし、性能は時間の経過とともに、ゆっくりと、静かに低下していきます。 余分なループが一つ、最適化されていないデータベースを一回呼び出す……。 それが積み重なっていくように、目に見える小さな問題が積み重なっていくのです。 解約した顧客からメールを受け取って初めて、そのことに気づきます。 彼らは口を揃えて「UX(ユーザ体験)がよくない 」と言います。 クラッシュしないので「問題ない」ように思っていましたが、アプリは知らぬ間に悪化していました。 パフォーマンスを抽象的なものから実用的なものへと変化させる 私は長い間Sentryを、他のユーザーの皆さんと同様エラー処理と問題報告のために使っていました。 軽量なインターフェースと迅速なインストールプロセスにより、私は簡単に問題を処理し、優先順位をつけ、解決することができました。 私は、電子メールの受信箱と同じように、ソフトウェアの問題をクリーンな状態に保っています。 正直、パフォーマンス・モニタリングに注力しているときの私は、半信半疑でした。 たくさんのデータやダッシュボードが送られてきて、それを毎朝監視して見なければいけないからです。 非常に時間がかかる作業な上、結局人が見て判断しなければならないため、億劫に感じました。 しかしその疑念は、Sentryの提供する「パフォーマンスのためのクリアで簡素なアクション層」を理解した途端に消え去りました。 Sentryは、パフォーマンスに関する情報を分かりやすい内容で通知してくれます。 これまでは、分かりにくい折れ線グラフではないにしろ、答えを与える代わりに疑問を増やすだけのものが多かったのです。 代わりに、Sentryは明確で解決可能な問題を提示してくれました。 例えば、SentryはN+1エラー通知をしてくれるので、オンボーディングが重要なルートを高速化することができました。このようなことをPythonの2行で表現しました。 そして、Sentryはこの遅いDB操作にアラートしてくれました。 Sentryは、送信メールのレンダリングと送信を倍の速度で行う方法を教えてくれました。 Sentryは、プログラムのどこでどのトランザクションがパフォーマンスの問題を引き起こしているのかを正確に教えてくれました。 そのため、問題の根本原因を見つけるために、多くのダッシュボードやレポートの分析に時間を費やす必要はありませんでした。 Sentryを使ったおかげで、無駄な作業が減り、アプリのパフォーマンスに注力することができるようになります。 Sentryでは、コードエラーを処理するのと同じように、パフォーマンスの問題を処理することができるので大変便利でした。 開発者にとってパフォーマンスが重要な理由 多くの開発者たちは、アプリケーションのパフォーマンスを「あったらいいな」程度の機能として扱っています。 開発計画や製品ロードマップを作成しているとき、アプリのパフォーマンスについて十分に考えていない開発者がいるのです。これはよくわかります。 お客様の多くは、ページの読み込み時間の遅さやその他のパフォーマンスの問題を受け入れてくれると考えていることが多いからです。 一方で、新機能を搭載しなければ、お客様は不満を募らせるだろうと考えています。 ですから、パフォーマンスよりも新機能を優先することはよくあることです。 しかし、ユーザーや顧客は性能を気にしており、意外とすぐその変化に気がつきます。 しかし、実際にどう説明したらいいのかわからないこともあります。 Buttondownを使い始めてから数カ月後のあるお客様と電話をしたことがあります。 お客様:よく分からないんだけど、[加入者向け管理画面] が操作しやすくなったんですよね。いずれにせよ、UX(ユーザー体験)を向上させたのは素晴らしいです! とはいえ、UXは1ピクセルも変わっていませんでした。 変わったのは、スピードとパフォーマンスです。Sentryのおかげで、5秒のフィードバックループを1秒に短縮することができました。Sentryを使えば、それは本当に簡単なことでした。 一部製品、一部プロセス: アプリケーションのパフォーマンスに関する考え方のオススメ パフォーマンス問題の優先順位付けと、改善を厳密に行うことに関心のあるエンジニアにお勧めのプロセスがあります。 これは、私がAmazonやStripeでエンジニアをしていたときに実際に効果が合った方法です。 […]

アプリ開発時のReact Nativeのデバッグとエラートラッキングについて

アプリ開発時のReact Nativeのデバッグ

優れたソフトウェア開発者は、コードをデバッグする方法を知っています。 実際、ほとんどのソフトウェア開発者は新しいコードを書くことよりも、既存のコードをデバッグすることがほとんどです。ネイティブアプリの開発に関しては、開発中のデバッグとエラーの追跡は手間のかかる面倒な作業として有名です。 そこで今回は、React Nativeアプリケーションをデバッグし、実際にエラーを追跡する方法をご紹介していきます。 また、React Native Debuggerというツールを使ったエラー追跡についても触れていきたいと思います。 React Nativeにおけるデバッグの攻略法 開発中のコードを効率的にデバッグするためのデバッグ手法を知っておくと便利です。場合によっては、専用のデバッグツールを使用する方が効率的かもしれません。 まず、React Nativeアプリでコードをデバッグするために使用できる一般的なテクニックをご紹介します。 今回の記事を通して使用する、新しいExpoベースのReact Nativeプロジェクトを作成しました。次のコマンドを実行すると作成できます。 ここでは、簡単なReact Nativeのコードを紹介します。 これはボタンをレンダリングして関数を起動し、コンソールに文字列を表示する簡単なアプリケーションです。 デバッグ用端末を使う 新しいExpoプロジェクトを起動したり、React Nativeアプリを実行したりすると、開発モード中に操作した全てのログがターミナルに表示されます。 これは、expo startコマンドを実行する別のターミナルでも、IDEに統合されたターミナルでもかまいません。 例えば、VS Codeを使用した場合、ターミナルにはアプリで行ったすべてのログが表示されます。 これは、ローカルでアプリケーションを実行する方法と似ています。 ReactやReact Nativeなどのフレームワークを使ったクライアントサイドの開発では、このターミナルでクライアントサイドのログを取得し、開発モードのアプリのデバッグに利用でき、どんな操作をしたときにどんなエラーが起きたのか手軽に確認できます。 さて、それではわざと構文エラーを起こしてみましょう。 上記のセクションのレイアウト定義において、最後にセミコロンを追加してみます。するとターミナルには、このようなエラーが表示されます。 何のファイルで、どんなエラーが、どこの行で起きたのか……エラーメッセージとともに表示されていますね。 Expoターミナルは、すべてのログが最初に表示される場所です。 そのため、アプリをデバッグしているときはいつでも、そのターミナルを最初に見ることができます。 エキスポデバッガー Expo を React Native で使用する場合、ビルトイン(備え付け)のデバッガーを入手することができます。 このデバッガーは、エラーメッセージを表示し、エラーが表示されたコードの部分を明示し、コード内のエラー部分をマークしてくれます。 React Nativeプロジェクトを物理デバイスで実行している場合、アプリのコードを実行しているExpoアプリでエラーがどのように表示されるかは次のとおりです。 エラーを確認し、コードを簡単にデバッグすることができますが、この場合、スタックトレースはあまり役に立ちません。なぜなら、エミュレータでExpoを使っているのであれば、ログの方が綺麗に整形されているためです。 スタックトレースはありませんが、こちらの方が簡潔で必要な情報だけが表示されていますね。これで混乱を減らし、より早くエラーにたどり着くことができます。 ブラウザで見るReact開発ツール 先ほどはネイティブアプリでした。 続いては、Web上でフロントエンドアプリケーションをデバッグしてみましょう。 ブラウザを開くだけで、コンソールのログやエラー、レンダリングされたUI要素、関連するスタックトレースなど、あらゆるものが表示されます。 ありがたいことに、React NativeやExpoベースのプロジェクトでも同じことができます。React Developer Tools Chrome拡張をインストールするか、次のコマンドを使用してシステムにグローバルインストールするだけで導入可能です。 Expoアプリの端末で、「w」を押せばWeb上でアプリが開きます。 エラー情報が表示され、Webアプリと同じようにデバッグすることができます。 これは、先ほどデバッグターミナルで見たのと同じエラーで、Expoアプリとエミュレーター上でも同じですね。 […]

;