サーバーを停止することなく、稼働中の本番システムの動作を追跡するために、erlang:trace/3とdbgモジュールの使用を開始しようとしています。
documentation は opaque (控えめに言っても)であり、オンラインで役に立つチュートリアルはないようです。
私が一日中費やしたことは、dbg:cとdbg:pを使用してmodule:functionにトレースを適用しようとして、特定の関数で何が起こっているのかをキャプチャすることでしたが、成功しませんでした...
ライブErlangシステムでトレースを使用する方法について簡潔な説明がありますか?
グラフィカルなトレーサーを使用する場合は、 erlyberly を試してください。 (現時点ですべてのプロセスで)トレースする関数を選択し、dbg APIを処理できます。
ただし、過負荷に対しては保護されないため、実稼働システムには適していません。
関数呼び出しのトレースの基本的な手順は、非ライブノード上にあります。
_> dbg:start(). % start dbg
> dbg:tracer(). % start a simple tracer process
> dbg:tp(Module, Function, Arity, []). % specify MFA you are interested in
> dbg:p(all, c). % trace calls (c) of that MFA for all processes.
... trace here
> dbg:stop_clear(). % stop tracer and clear effect of tp and p calls.
_
複数の機能を同時にトレースできます。関数ごとにtp
を呼び出して関数を追加します。エクスポートされていない関数をトレースする場合は、tpl
を呼び出す必要があります。関数を削除するには、ctp
またはctpl
を同様の方法で呼び出します。一般的なtp呼び出しは次のとおりです。
_> dbg:tpl(Module, '_', []). % all calls in Module
> dbg:tpl(Module, Function, '_', []). % all calls to Module:Function with any arity.
> dbg:tpl(Module, Function, Arity, []). % all calls to Module:Function/Arity.
> dbg:tpl(M, F, A, [{'_', [], [{return_trace}]}]). % same as before, but also show return value.
_
最後の引数は一致指定です。 _dbg:fun2ms
_を使用して、それを試すことができます。
P()を呼び出して、トレースするプロセスを選択できます。項目はerlang:traceで説明されています。いくつかの呼び出しは次のとおりです。
_> dbg:p(all, c). % trace calls to selected functions by all functions
> dbg:p(new, c). % trace calls by processes spawned from now on
> dbg:p(Pid, c). % trace calls by given process
> dbg:p(Pid, [c, m]). % trace calls and messages of a given process
_
dbg
はほとんどすべてを行うため、_erlang:trace
_を直接呼び出す必要はないでしょう。
ライブノードの黄金律は、シェルへのトレース出力の量のみを生成することです。これにより、dbg:stop_clear().
と入力できます。 :)
多くの場合、多くのイベントの後に自動的に停止するトレーサーを使用します。例えば:
_dbg:tracer(process, {fun (_,100) -> dbg:stop_clear();
(Msg, N) -> io:format("~p~n", [Msg]), N+1 end, 0
}).
_
リモートノード(または複数のノード)でデバッグする場合は、pan
、eper
、inviso
、またはonviso
を検索します。
ライブシステムでは、シェルにトレースすることはほとんどありません。システムが適切に構成されていれば、シェルに出力されたErlangログをすでに収集しています。ライブノードでこれが重要である理由を強調する必要はありません...
ファイルへのトレースについて詳しく説明しましょう:
ファイルにトレースすることができます。これにより、後で変換および解析できるバイナリ出力が生成されます。 (さらなる分析または自動制御システムなどのため)
例は次のとおりです。
ラップされた複数のファイル(12x50メガバイト)にトレースします。このような大きなトレースを使用する前に、常に使用可能なディスク領域を確認してください!
_dbg:tracer(port,dbg:trace_port(file,{"/log/trace",wrap,atom_to_list(node()),50000000,12})).
_
dbg:p(all,[call,timestamp,return_to]).
つまり、基本的なトレースコマンドシーケンスを見てみましょう:
<1>dbg:stop_clear().
<2>dbg:tracer().
<3>dbg:p(all,[call, timestamp]).
<4>dbg:tp( ... ).
<5>dbg:tpl( ... ).
<42>dbg:stop_clear().
次のことができます:
シェルでfun()-sを定義してトリガーを追加し、特定の時間またはイベントでトレースを停止します。再帰的なfun()-sはこれを達成するのに最適ですが、それらを適用するときは非常に注意してください。
多種多様なパターンマッチングを適用して、特定のタイプの引数を持つ特定の関数呼び出しで特定のプロセスのみをトレースするようにします...
しばらく前に問題がありました。ETSテーブルの内容を確認する必要があり、特定のエントリが表示されたら、2〜3分以内にトレースを停止する必要がありました。
また、フランチェスコ・セサリーニによって書かれた本Erlang Programmingもお勧めします。 ( Erlang Programming @ Amazon )
「dbg」モジュールは非常に低レベルのものです。私がよく必要とするタスクのために非常に頻繁に使用する2つのハックがあります。
http://www.snookles.com/erlang/user_default.erl でErlang CLI/Shell拡張コードを使用します。もともとは(私が知る限り)Serge Aleynikovによって書かれたもので、「シェルにカスタム関数を追加する方法」の例として有用です。モジュールをコンパイルし、そのパスを指すように〜/ .erlangファイルを編集します(ファイルの上部にあるコメントを参照)。
[〜#〜] eper [〜#〜] ユーティリティのコレクションにバンドルされている " redbug "ユーティリティを使用します。 「dbg」を使用すると、数秒で数百万のトレースイベントを簡単に作成できます。実稼働環境でこれを行うと、悲惨な結果を招く可能性があります。開発または実稼働で使用する場合、redbugはトレースによって引き起こされる過負荷で実行中のシステムを強制終了することをほぼ不可能にします。