過去分
- EnterpriseLibrary 6のSemantic Logging Application Blockを触ってみた - かずきのBlog@hatena
- EnterpriseLibrary 6のSemantic Logging Application BlockでAzure Storageにログをはく - かずきのBlog@hatena
- Enterprise Library 6のSemantic Logging Application Block + Reactive Extensions - かずきのBlog@hatena
はじめに
ログ関係のライブラリを使いこんでいくうちに出てくる要求として出力先をカスタマイズしたいというのはよくあると思います。Semantic Logging Application Blockでも当然そこは拡張できるように作られてるのでやってみました。
****Sinkというクラスを作る
Semantic Logging Application BlockはRxと相性がいいだけあって、ログの出力する人はEventEntryのIObserverです。OnNextを処理すればOKというわかりやすい設計。今回はコンソールに出すだけの簡単なものを作ってみました。フォーマッティングはIEventTextFormatterにお任せしてます。
// 独自の出力先class MyConsoleSink : IObserver<EventEntry> { private IEventTextFormatter formatter; public MyConsoleSink(IEventTextFormatter formatter = null) { this.formatter = formatter ?? new EventTextFormatter(); } publicvoid OnCompleted() { } publicvoid OnError(Exception error) { } publicvoid OnNext(EventEntry value) { // 値がわたってきたときだけif (value == null) { return; } // formatterで整形して出力するusing (var w = new StringWriter()) { this.formatter.WriteEvent(value, w); Console.Write(w); } } }
そして、IObservable
// MyConsoleSink購読用拡張メソッドstaticclass MyConsoleSinkExtensions { publicstatic SinkSubscription<MyConsoleSink> LogToMyConsole(this IObservable<EventEntry> self, IEventTextFormatter formatter = null) { var sink = new MyConsoleSink(formatter); var d = self.Subscribe(sink); returnnew SinkSubscription<MyConsoleSink>(d, sink); } }
Subscribeして、SinkSubscriptionというものを返すのがお約束っぽいのでそれに従ってます。Semantic Logging Application BlockのログがIObservableから発行されたものをIObserverで監視して出力するだけということがわかれば、間にRxのLINQ挟み込めるのも納得ですね。
使い方
// リスナー作って var l = new ObservableEventListener(); // 監視するログの種類を設定して l.EnableEvents( MyEventSource.Log, EventLevel.Verbose, MyEventSource.Keywords.Diagnostic | MyEventSource.Keywords.Lifecycle); // 自前のログ出力先へ出力する l.LogToMyConsole(); MyEventSource.Log.Start(); MyEventSource.Log.Query("select * from dual"); MyEventSource.Log.Stop();
とても簡単ですね。