OTP イベント マネージャ プロセス (ロガーなど) は、独自の状態 (ログ レベルなど) を持ち、それに基づいてイベントをフィルタ/変換できますか?
3 に答える
また、いくつかの状態を gen_event 自体に入れる必要があります。現時点での最善のアイデアは、プロセス ディクショナリ (get/put) を使用することです。ハンドラは gen_event プロセスのコンテキストで呼び出されるため、すべてのハンドラ呼び出しに対して同じプロセス ディクショナリが存在します。
はい、プロセス ディクショナリは悪ですが、この場合、代替手段 (ets テーブル、ステート サーバー) よりも悪くないように見えます。
OTP に含まれる gen_event の実装は、状態を追加する手段を提供しません。これを実現するために実装を拡張し、gen_event の代わりに実装を使用できます。しかし、私はそれに反対することをお勧めします。
イベント マネージャーに追加したい状態の種類は、いくつかの理由から、実際にはイベント ハンドラーに属します。
異なるハンドラーで異なるレベルを使用したい場合があります。たとえば、コンソールにエラーを表示するだけで、すべてをディスクに書き込みます。
フィルター処理されていないすべてのイベントの取得に応じて、マネージャー イベント ハンドラーでイベント レベルが変更されると、機能しなくなる可能性があります (イベントには、ログ記録以外にもさまざまな用途があります)。これにより、デバッグが困難な問題が発生する可能性があります。
すべてがフィルター処理されたイベントのみを取得する複数のハンドラー用のイベント マネージャーが必要な場合は、2 つのマネージャーを用意することで簡単に実現できます。次に、フィルター処理されていないハンドラーにハンドラーをインストールし、ハンドラーをレベルでフィルター処理して (簡単)、フィルター処理されたイベントを他のマネージャーに渡します。フィルター処理されたメッセージのみを取得するすべてのハンドラーは、2 番目のマネージャーに登録できます。
ハンドラーは、次のようなすべてのコールバックで渡される独自の状態を持つことができます。
Module:handle_event(Event, State) -> Result
フィルタリングは次のようになります ({level N, Content}
イベントなどを想定):
handle_event({level, Lvl, Content}, State#state{max_level=Max}) when Lvl >= Max ->
gen_event:notify(filtered_man, Content);
State は、特別なイベント、gen_event:call\3,4
(できれば)、または handle_info によって処理されるメッセージによって変更できます。
詳細については、 Gen_Event Behaviorおよびgen_event(3)を参照してください。
プロセスの場合(常にスーパーバイザー経由で行う必要があります)、新しいプロセスを登録する必要がある場合は、新しいプロセスの名前を指定するだけですstart_link
。gen_event
私が見る限り、state
その動作を使用してある種のを開始する方法はありません。
もちろん、gen_event
単純な や の上に、独自の振る舞いを書くことができますgen_server
。
別の方法として、デバッグ レベルgen_event
ごとに個別のプロセスを使用することもできます。または、ハンドラーでメッセージをフィルター処理することもできます。