2011-08-05 37 views
2

我有一些自定義TraceListener困難。問題在於編寫單個跟蹤行會產生兩個調用,一個調用Write(),另一個調用WriteLine()。對Write()的調用包含跟蹤源,級別和事件ID。對WriteLine()的調用是實際的消息自定義TraceListener和多個消息

它看起來像跟蹤偵聽器只實例化一次,所以我不能只是第一次調用Write()的隊列。看起來沒有辦法關聯這兩個電話。不幸的是,這是一個問題,因爲它導致我發送2條消息到遠程服務,使開銷加倍。

似乎沒有任何通用的方法來過濾調用。我會接受只是忽略了來源和級別的調用,但似乎這可能是非常容易的。

這裏的代碼樣片:與

private static readonly TraceSource Ts = new TraceSource("Source"); 

Ts.TraceEvent(TraceEventType.Error, 0, "Error Message"); 

會產生一個調用write():

"Source: Error: 0"

然後打電話

/// <summary> 
/// When overridden in a derived class, writes the specified message to the listener you create in the derived class. 
/// </summary> 
/// <param name="message">A message to write. </param><filterpriority>2</filterpriority> 
public override void Write(string message) 
{ 
     _client.Post(message); 
} 


/// <summary> 
/// When overridden in a derived class, writes a message to the listener you create in the derived class, followed by a line terminator. 
/// </summary> 
/// <param name="message">A message to write. </param><filterpriority>2</filterpriority> 
public override void WriteLine(string message) 
{ 
     _client.Post(message); 
} 

用法是WriteLine()與

"Error Message"

是否可以合併這兩條消息?或者只是過濾第一個?謝謝!

+0

您可以發佈您的整個TraceListener?這可能是代碼中的其他地方存在問題,而Write和WriteLine方法除外。也許你也可以嘗試編寫一個簡單的TraceListener,它只寫入控制檯或調試器或其他東西。看看你能否做到這一點,然後解決爲什麼基於Web的服務無法正常工作。另外,如果您使用的是System.Diagnostics,則可以考慮使用此項目來獲得一些自定義格式化功能,這與使用log4net和NLog可以執行的操作類似。 http://ukadcdiagnostics.codeplex.com/ – wageoghe

+0

我得到了同樣的行爲,而且我的操作非常簡單,我只是在寫入和寫入中打斷點。我還看到兩個電話來的消息。你找到解決方案嗎? –

+0

我的歉意,我應該回答我的問題。我確實找到了解決方案,但我並沒有完全理解它。檢查我剛剛發佈的答案和github鏈接。 – mfanto

回答

0

有兩種不同格式的信息......這些信息寫在哪裏?這是使用企業日誌記錄塊嗎?如果是這樣,你應該檢查配置文件 - 監聽器可能會被註冊兩次。

+0

正在寫入外部服務。 _client.Post()正在進行Web服務調用。它沒有註冊兩次。這是消息的一部分調用Write(),另一部分調用WriteLine()。這似乎是由設計發生的。信息不重複,只分成兩半。它不使用企業日誌記錄塊。只需一個簡單的跟蹤監聽器和一個1行演示程序即可進行調用。 – mfanto

0

我能夠從Ukadc Diagnostics

的基類實現的TraceListener基類來解決這個問題是:

public abstract class CustomTraceListener : TraceListener 
{ 
    private static readonly TraceSource Trace = new TraceSource("PostmarkTraceListener"); 

    /// <summary> 
    /// Construct an instance of the trace listener 
    /// </summary> 
    /// <param name="name">The name of the trace listener</param> 
    protected CustomTraceListener(string name) 
     : base(name) 
    { 

    } 

    #region Abstracts 

    /// <summary> 
    /// This method must be overriden and forms the core logging method called by all other TraceEvent methods. 
    /// </summary> 
    /// <param name="eventCache">A cache of data that defines the trace event</param> 
    /// <param name="source">The trace source</param> 
    /// <param name="eventType">The type of event</param> 
    /// <param name="id">The unique ID of the trace event</param> 
    /// <param name="message">A message to be output regarding the trace event</param> 
    protected abstract void TraceEventCore(TraceEventCache eventCache, string source, TraceEventType eventType, 
              int id, string message); 

    /// <summary> 
    /// This method must be overriden and forms the core logging method called by all otherTraceData methods. 
    /// </summary> 
    /// <param name="eventCache">A cache of data that defines the trace event</param> 
    /// <param name="source">The trace source</param> 
    /// <param name="eventType">The type of event</param> 
    /// <param name="id">The unique ID of the trace event</param> 
    /// <param name="data">The data to be logged</param> 
    protected abstract void TraceDataCore(TraceEventCache eventCache, string source, TraceEventType eventType, 
              int id, params object[] data); 

    #endregion 

    #region TraceData/TraceEvent Overrides 

    /// <summary> 
    /// Write a trace event 
    /// </summary> 
    /// <param name="eventCache">A cache of data that defines the trace event</param> 
    /// <param name="source">The trace source</param> 
    /// <param name="eventType">The type of event</param> 
    /// <param name="id">The unique ID of the trace event</param> 
    /// <param name="message">A message to be output regarding the trace event</param> 
    public override sealed void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, 
              int id, string message) 
    { 
     FilterTraceEventCore(eventCache, source, eventType, id, message); 
    } 

    /// <summary> 
    /// Write a trace event 
    /// </summary> 
    /// <param name="eventCache">A cache of data that defines the trace event</param> 
    /// <param name="source">The trace source</param> 
    /// <param name="eventType">The type of event</param> 
    /// <param name="id">The unique ID of the trace event</param> 
    /// <param name="format">A string format specification for the trace event</param> 
    /// <param name="args">Arguments used within the format specification string</param> 
    public override sealed void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, 
              int id, string format, params object[] args) 
    { 
     string message = string.Format(CultureInfo.CurrentCulture, format, args); 

     FilterTraceEventCore(eventCache, source, eventType, id, message); 
    } 

    /// <summary> 
    /// Write a trace event 
    /// </summary> 
    /// <param name="eventCache">A cache of data that defines the trace event</param> 
    /// <param name="source">The trace source</param> 
    /// <param name="eventType">The type of event</param> 
    /// <param name="id">The unique ID of the trace event</param> 
    public override sealed void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, 
              int id) 
    { 
     FilterTraceEventCore(eventCache, source, eventType, id, null); 
    } 

    /// <summary> 
    /// Write a trace event 
    /// </summary> 
    /// <param name="eventCache">A cache of data that defines the trace event</param> 
    /// <param name="source">The trace source</param> 
    /// <param name="eventType">The type of event</param> 
    /// <param name="id">The unique ID of the trace event</param> 
    /// <param name="data">The data to be written</param> 
    public override sealed void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, 
              int id, object data) 
    { 
     FilterTraceDataCore(eventCache, source, eventType, id, data); 
    } 

    /// <summary> 
    /// Write a trace event 
    /// </summary> 
    /// <param name="eventCache">A cache of data that defines the trace event</param> 
    /// <param name="source">The trace source</param> 
    /// <param name="eventType">The type of event</param> 
    /// <param name="id">The unique ID of the trace event</param> 
    /// <param name="data">The data to be written</param> 
    public override sealed void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, 
              int id, params object[] data) 
    { 
     FilterTraceDataCore(eventCache, source, eventType, id, data); 
    } 

    #endregion 

    #region Write Methods 

    /// <summary> 
    /// Write a message to the trace listeners 
    /// </summary> 
    /// <param name="message">The message to write</param> 
    public override void Write(string message) 
    { 
     FilterTraceEventCore(null, string.Empty, TraceEventType.Information, 0, message); 
    } 

    /// <summary> 
    /// Write a message to the trace listeners 
    /// </summary> 
    /// <param name="message">The message to write</param> 
    public override void WriteLine(string message) 
    { 
     Write(message); 
    } 

    #endregion 

    #region ShouldTrace 

    /// <summary> 
    /// Determines whether a filter is attached to this listener and, if so, asks whether it ShouldTrace applies to this data. 
    /// </summary> 
    protected virtual bool ShouldTrace(TraceEventCache eventCache, string source, TraceEventType eventType, int id, 
             string formatOrMessage, object[] args, object data1, object[] data) 
    { 
     return !(Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, formatOrMessage, args, data1, data)); 
    } 

    #endregion 

    #region FilterTraceCore 

    /// <summary> 
    /// Called before the main TraceEventCore method and applies any filter by calling ShouldTrace. 
    /// </summary> 
    protected virtual void FilterTraceEventCore(TraceEventCache eventCache, string source, TraceEventType eventType, 
               int id, string message) 
    { 
     try 
     { 
      if (!ShouldTrace(eventCache, source, eventType, id, message, null, null, null)) 
       return; 

      TraceEventCore(eventCache, source, eventType, id, message); 
     } 
     catch (Exception exc) 
     { 
      Trace.TraceEvent(TraceEventType.Error, 0, "{0}", exc); 
     } 
    } 

    /// <summary> 
    /// Called before the main TraceDataCore method and applies any filter by calling ShouldTrace. 
    /// </summary> 
    protected virtual void FilterTraceDataCore(TraceEventCache eventCache, string source, TraceEventType eventType, 
               int id, params object[] data) 
    { 
     try 
     { 
      if (!ShouldTrace(eventCache, source, eventType, id, null, null, null, data)) 
       return; 

      TraceDataCore(eventCache, source, eventType, id, data); 
     } 
     catch (Exception exc) 
     { 
      Trace.TraceEvent(TraceEventType.Error, 0, "{0}", exc); 
     } 
    } 

    #endregion 
} 

和我的自定義的TraceListener:

public class PostmarkTraceListener : CustomTraceListener 
{ 
    #region CustomTraceListener Overrides 

    /// <summary> 
    /// This method must be overriden and forms the core logging method called by all other TraceEvent methods. 
    /// </summary> 
    /// <param name="eventCache">A cache of data that defines the trace event</param> 
    /// <param name="source">The trace source</param> 
    /// <param name="eventType">The type of event</param> 
    /// <param name="id">The unique ID of the trace event</param> 
    /// <param name="message">A message to be output regarding the trace event</param> 
    protected override void TraceEventCore(TraceEventCache eventCache, string source, TraceEventType eventType, 
              int id, string message) 
    { 
     SendPostmarkMessage(eventCache, source, eventType, id, message, null); 
    } 

    /// <summary> 
    /// This method must be overriden and forms the core logging method called by all otherTraceData methods. 
    /// </summary> 
    /// <param name="eventCache">A cache of data that defines the trace event</param> 
    /// <param name="source">The trace source</param> 
    /// <param name="eventType">The type of event</param> 
    /// <param name="id">The unique ID of the trace event</param> 
    /// <param name="data">The data to be logged</param> 
    protected override void TraceDataCore(TraceEventCache eventCache, string source, TraceEventType eventType, 
              int id, params object[] data) 
    { 
     SendPostmarkMessage(eventCache, source, eventType, id, null, data); 
    } 

    #endregion 

    private void SendPostmarkMessage(TraceEventCache eventCache, string source, TraceEventType eventType, int id, params object[] data) 
    { 
     // do your work here 
    } 
} 

你可以找到一個在我的工作示例github account