実証済みの技術で Ruby と Rails のバグを迅速に解決
ソフトウェアのバグは、破壊的で、とらえどころがなく、不快で、侵入的である可能性があります。実際、開発者は問題を見つけて修正するためにエジソンの粘り強さを必要とすることがよくあります。
しかし、開発者に必要な資産は根性だけではありません。コードをデバッグするための情報も必要です。問題の症状と影響は何ですか?その頻度はどれくらいですか?浸透性?来歴?バグの証拠と成果物 (コア ダンプ、スタック トレース、ログ、テスト ケース) は非常に貴重です。
Ruby と Rails 開発者が問題の証拠を収集して調査するためにすぐに利用できるいくつかのテクニックとツールを見てみましょう。データは粘り強さに勝つことはできませんが、努力を軽減する (そして睡眠時間を節約する) のには役立ちます。
Rails は、実行中のアプリケーションを監視するための優れたツールをいくつか提供しています。これには、独自の診断や追加したい診断をキャプチャするための構成可能なLoggerが含まれます。 Rails は、データベース クエリの発信元を特定するための詳細なクエリ ログと、バックグラウンド ジョブがキューに入れられている場所を明らかにするための詳細なエンキュー ログも提供します。後者の 2 つのログは、development でデフォルトで有効になっています。 環境。他の環境では 2 つのステートメントを使用して両方を有効にできます。
Rails 7 では各 SQL クエリにコメントが付けられるため、あまり知られていないログ オプションが利用可能になります。 config/application.rb に以下を追加すると または任意の環境ファイル:
クエリ ログは、アプリケーション名、コントローラー名、アクション名、またはバックグラウンド ジョブ名で自動的に修正されます。次のサンプル出力は、Rails のデバッグ ガイドから直接取得したものです。
おそらく、実稼働環境ではこれらすべての機能を有効にしたくないでしょう。ログ生成は、メモリと時間の点でコストがかかる可能性があります (負荷がかかるアプリケーションのリソースは有限です)。
ただし、例外もあります。特に開発モードやテスト モードをデバッグする場合は、オンデマンド機能を一時的に有効にすることができます。診断を有効または無効にするためにコードを変更 (場合によっては再デプロイ) するのではなく、環境変数を使用して状態を制御します。 Heroku などの一部の環境では、環境変数の設定を変更しても、新しいデプロイメントは必須ではありません。
たとえば、一連の変数を定義して、ロギングと詳細度を制御できます。
便宜上、構成設定をクエリするための小さなクラスを作成します。
次に、変数とコードを使用して、config/application.rb でログ機能を設定します。 :
シェル、dotenv ファイル、継続的統合、またはホスティングおよびデプロイメント プラットフォームを使用して、各オプションを設定します。オンデマンドで機能を使用することもできます。コマンド ラインで定義された環境変数を使用してアプリケーションを起動するだけです。
開発用に Puma を調整する
前のセクションに基づいて、環境変数を使用して開発環境でのデバッグ用に Puma 構成を調整する方法を見てみましょう。
通常、Puma は実稼働環境でのスループットを最大化するように構成され、複数のワーカーとワーカーごとに多くのスレッドを実行します。開発では、その逆、つまり対話型デバッグを可能にするために 1 つのワーカー、1 つのスレッド、および非常に長いタイムアウトが必要になります。それぞれは調整できるパラメータです。
config/puma.rb を変更します 次のコードを反映します。
各環境で Puma を制御するための 3 つの環境変数を設定できるようになりました。開発時は、対話型デバッグ用に最適化する値を設定します。
Puma の設定を検証したい場合は、環境変数PUMA_LOG_CONFIG=true を設定します。 そしてアプリケーションを起動します。 Puma は起動時にアクティブな設定を出力します。
偶然にも、最新の Rails リリースのデフォルトの Puma 構成は、ここに示されているものと似ています (ヒントをくれた Nate Matykiewicz に感謝します)。
バックグラウンド ジョブをインラインで実行する
複雑さを問わず Rails アプリケーションは通常、バックグラウンド ジョブを活用して、計算集約的で (比較的) 長時間実行されるタスクを実行します。バックグラウンド ジョブは、要求/応答サイクルから切り離されて非同期に実行されます。 「帯域外」処理の理想的な候補には、レポートの生成、電子メールの送信、サードパーティ API との対話などが含まれます。ただし、ジョブの非同期的な性質により、デバッグも複雑になります。
トラブルシューティングを簡素化するには、 ジョブをすぐに実行します。 ローカルの開発およびテスト環境で。即時モードでは、ジョブはキューに入れられず、即座に実行されます。「フォアグラウンド」で実行すると、ブレークポイントを設定し、対話的に状態を検査できます。
人気があり管理しやすいアクティブ ジョブのキュー バックエンドである遅延ジョブを使用した例を見てみましょう。遅延ジョブでは、キューイングを有効にする設定を提供します。デフォルトの設定は true です。 そしてジョブは通常どおりキューに入れられます。ただし、false に設定した場合 、ジョブはすぐに実行されます。
次のコードをアプリケーションの config/initializers/delayed_job.rb に追加します。 :
DELAYED_JOBS_DISABLE_JOB_QUEUES の場合 任意の値に設定すると、キューイングは無効になります。環境変数が空白であるか定義されていない場合、キューイングは有効になります。
次に、シェル、コマンド ライン、またはドット ファイルで、setDELAYED_JOBS_DISABLE_JOB_QUEUES を設定します。 必要に応じて。
環境変数を何も設定しないか、環境変数を削除してキューイングを復元します。
環境変数の命名規則はありません。自分にとって意味のある名前を選択してください。変数を分類するための便利な規則の 1 つは、PUMA_ などのプレフィックスとしてパッケージ名を追加することです。 と DELAYED_JOB_ 。前者は Puma に影響を与える変数を示します。後者は、遅延ジョブで使用される変数を暗示します。
ネットワーク通話のピアイン
バックグラウンド ジョブと同様に、Rails アプリケーションはアプリケーション プログラミング インターフェイス (API) を使用することもできます。 API は、GraphQL データベース、電子商取引トランザクション、パブリック データ ソースなどの外部サービスへのアクセスを提供します。
Net::HTTP から条件付きで HTTP リクエストとレスポンスを発行する別の例を次に示します。 図書館。環境変数 DEBUG_HTTP の場合 空白以外の値に設定すると、発信リクエストと受信レスポンスは STDOUT に出力されます。 .
ネットワーク アクティビティを確認するには、コマンド ラインで定義された環境変数を使用してアプリケーションを起動するだけです。
debug? メソッドは、実際のフラグ実装からの抽象化を提供します。このコードとこのコードの残りの部分は、実稼働コードから抜粋したこの要点に示すように、すべてのネットワーク リクエストの基本クラスを形成できます。
Ruby gem の世界は広大です。デバッグに利用できるすべての優れた gem をカバーすることは不可能です。代わりに、すぐに効果を高めるために今日追加できるツールをいくつか見てみましょう。おそらく、これらをすべてのプロジェクトに追加することになるでしょう。
-
awesome_printとtable_printActive Record モデルを含む、Ruby データ構造の豊富で読みやすい検査を作成します。 gemin コードまたはコンソールから使用できます。awesome_printによって出力されるモデルの例を次に示します。 コンソール内:pの代わりに 、apを使用します 拡張された出力を表示します。 awesome_print 属性をアルファベット順にリストし、1 行に 1 つの属性を追加します。 -
better_errors標準の Rails エラー ページを、拡張されたスタック バックトレース、パラメータ リスト、および例外発生時のスタック フレームと変数を調査できる対話型コンソールに置き換えます。ソース コードのリンクをお気に入りのエディターに結び付けることもできます。better_errorsを結び付けるコードは次のとおりです。 Visual Studio コードへ:export BETTER_ERRORS_EDITOR=vscodeを実行します シェル内で Rails サーバーを再起動します。これで、ファイルへのリンクが Visual Studio で自動的に開きます。 -
fakerはそのままにしておきます およびfactory_botGemfile のテスト グループと開発グループの両方にある gem (またはその代替案) 。コンソールでデータを迅速に生成する必要がある場合、どちらも非常に貴重です。
もう 1 つのアイデア:AppSignal をアプリケーション監視ツールとして使用する場合、ログを解釈してエラーの原因を特定する機能があります。詳細については、「AppSignal を使用した Ruby でのデバッグ」を参照してください。
デバッグはスキルです
コードのデバッグは一種の芸術であり、他の創造的な取り組みと同様、練習すればするほど上達します。
別の開発者、特に経験豊富な開発者とペアになりながらデバッグします。パートナーが喜んでいる場合は、一緒に大声で考え、予感や洞察を交換してください。
さあ、ハッキングしましょう!
追記Ruby Magic の投稿を報道後すぐに読みたい場合は、Ruby Magic ニュースレターを購読して、投稿を 1 つも見逃さないようにしてください。
マルティン シュトライヒャー
ゲスト著者の Martin はプロの Ruby 開発者です。彼はパデュー大学でコンピュータ サイエンスの高度な学位を取得し、Linux Magazine (米国) の編集長を 5 年間務め、IBM の旧開発者ワークス ポータルに掲載されていたコラム「Speaking in Unix」の創設者でもありました。コーディングやコードについての執筆を行っていないときは、アートを収集したり、たくさんの小型犬と格闘したりしています。
Martin Streicher によるすべての記事
-
科学者による重要な Ruby on Rails コードのリファクタリング:実証済みのアプローチ
ソフトウェア エンジニアに本番コードの重要な部分をレビューするよう依頼すると、必ずリファクタリングが必要な 3 つの点を指摘するでしょう。では、なぜこれほど多くの悪いコード、脆弱なコード、または誤解されたコードが実稼働環境で実行され続けるのでしょうか? 答えは簡単です。エンジニアはそれに触れるのを恐れているからです。リファクタリング タスクは特定されてバックログに追加されますが、現在のスプリントに反映されることはほとんどありません。 これには多くの理由があります。コードは何年も前にチームを離れたエンジニアによって書かれたものである可能性があり、それを完全に理解している人は誰もいません。また
-
Trix および Turbo Frame を使用して Rails で動的テーブル エディタを作成する
この投稿では、Rails アプリケーションに基本的な ActionText テーブル エディタを実装します。次の方法を学習します。 ActionText と Trix は添付ファイルを処理します 独自の Attachable を実装するには と入力し、これを活用して基本的なテーブル エディタを構築します ターボ フレームを使用してテーブルを編集できます ターボは役立つと同時に邪魔にもなります この記事は、2020 年の優れたブログ投稿「Stimulus.js を使用して ActionText にテーブルを追加する」からインスピレーションを得ています。ただし、これは Turbo の出現前に