Erlangでイベントトレースツールを使用する

並行システムの一般的な問題の1つは次のとおりです。イベントはプログラムのさまざまな部分でさまざまな時間に絶えず発生し、その発生の原因と時間を制御する能力はありません。 問題を追跡するために、シーケンス図を使用できます。 たとえば、これ(ウィキペディアのおかげ):







この図の目的は、システムのさまざまな並列コンポーネント間の相互作用を示すことです。 この例では、フレッド、ボブ、ハンク、レニーがレストランにいます。 誰でも簡単に同様の図を紙に描くことができます。 問題は、紙のスケッチがプログラムの実行中に起こることと異なる場合があることです。



確かに、プログラムトレースデータに基づいて同様の図を自動的に作成できたら素晴らしいと思いますか? まあ、Erlangはこれをお手伝いします。 これを行う方法の例を示すために、いくつかのコードを使用します。



ステップ1.トレース機能を作成する



最初のステップは、トレース機能を構築することです。 私のものは次のように見え、「utp」モジュールにあります。

report_event(DetailLevel, FromTo, Label, Contents) -> %% NB External call ?MODULE:report_event(DetailLevel, FromTo, FromTo, Label, Contents). report_event(_DetailLevel, _From, _To, _Label, _Contents) -> hopefully_traced.
      
      







主なアイデアは、2番目の機能です。 これは5つの引数のスタブ関数であり、すぐに解決されます。 「hopefully_traced」の戻り値は任意ですが、この関数から何を返したいかを示しています。 最初の関数は、同じコンポーネントによる発信イベントと受信イベントを追跡するときに使用されます。



引数の説明:



ステップ2.プログラムのイベントをトレースする



プログラムで重要なことが発生した場合、「utp:report_event / 5」を呼び出します(ここでは、手順1でアナウンスされたトレース関数の名前に置き換えます)。 デフォルトでは、この関数は何もしませんが、後でErlangトレース機能を使用してキャッチできます。 上記の相互作用の例を次に示します。

 trace_test() -> Events = [{fred, bob, order_food}, {bob, hank, order_food}, {bob, fred, serve_wine}, {hank, bob, pickup}, {bob, fred, serve_feed}, {fred, renee, pay}], [utp:report_event(50, F, T, L, []) || {F,T,L} <- Events].
      
      







コード内のさまざまな場所でこの関数を呼び出すと、何でも追跡できることに注意してください。 多くのデバッグブロックを起動する代わりに、プログラムの任意の場所にトレース関数呼び出しを追加できます。 また、リストジェネレータを使用して上記の例を少し刺したことに注意してください。 イベントとその内容の詳細レベルは気にしません。



ステップ3. アプリケーション 「et」を呼び出す



次に、Erlangアプリケーションを「et」と呼ぶ正しい方法が必要です。 この呼び出しを行うモジュール「utp_filter」を作成しましたが、まだフィルタリング機能は含まれていません。

 start(ExtraOptions) -> Options = [{event_order, event_ts}, {scale, 2}, {max_actors, 10}, {detail_level, 90}, {actors, [fred, bob, hank, renee]}, {trace_pattern, {utp, max}}, {trace_global, true}, {title, "uTP tracer"} | ExtraOptions], et_viewer:start(Options).
      
      







このモジュールはet_viewerを初期化して、この例で使用できるようにします。 イベントの順序-「event_ts」は、イベントが受信されたときではなく、イベントが発生したときにタイムスタンプを追加することを意味します。 アクター属性は、アクターが表示される順序を設定します。 trace_pattern属性は非常に重要です。 「utp:report_event / 5」への呼び出しを追跡できます。 また、他の多くのオプションを指定することもできます。そうしないと、イベントが自分で選択します。 Rトレース機能が配置されているモジュールを単に示します。



ステップ4.テスト



手順3で説明した「et viewer」を実行して「utp_filter:start([])」を呼び出すと、手順2からトレーステストを実行できます。







これは、プログラムをトレースして取得することを除いて、Wikipediaの例に似ているはずです。 特に、このアイデアは、TCPスタック「uTP」の亜種のバグをキャプチャして見つけるために使用されました。







(チャートが小さいという事実にもかかわらず、それは依然として主要なアイデアを反映しています-この例はチャートを表示するためではなく、世界的な名声を得るためです:)。 TCPのようなプロトコルの場合、これは非常に強力なツールです。tcpdump(1)とstrace(1)の出力、および1つの図のプロトコルの内部状態。 プログラムの相互作用を見るだけで、これらのツールを使用していくつかのバグを見つけました。



以上です。 上記のコードを使用すると、いつでもグラフィカルトレーサーを使用できます。 有効にしない場合、トレース機能の使用によるオーバーヘッドは無視できます。有効にすると、この状況でのコードの動作を確認できます。



アプリケーション-用語Erlang / OTP、 詳細



All Articles