Пользовательский TraceListener и несколько сообщений - PullRequest
2 голосов
/ 05 августа 2011

У меня возникли сложности с пользовательским TraceListener. Проблема заключается в том, что запись одной строки трассировки приводит к двум вызовам, один для Write (), другой для WriteLine (). Вызов Write () содержит источник трассировки, уровень и идентификатор события. Вызов WriteLine () является фактическим сообщением

Похоже, что прослушиватель трассировки создается только один раз, поэтому я не могу просто поставить в очередь первый вызов метода Write (). Похоже, нет никакого способа сопоставить два вызова. К сожалению, это проблема, так как это заставляет меня отправлять 2 сообщения удаленному сервису, удваивая накладные расходы.

Там также нет никакого общего способа фильтрации вызовов. Я бы согласился просто игнорировать вызов с источником и уровнем, но кажется, что это может быть очень склонным.

Вот пример кода:

 /// <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);
 }

Использование с:

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

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

Будет вызывать функцию Write () с:

"Источник: ошибка: 0"

А затем вызов метода WriteLine () с

«Сообщение об ошибке»

Можно ли объединить два сообщения? Или просто фильтр первый? Спасибо!

Ответы [ 2 ]

0 голосов
/ 13 сентября 2013

Мне удалось решить эту проблему, реализовав базовый класс TraceListener из Ukadc Diagnostics

Базовый класс:

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

0 голосов
/ 05 августа 2011

Есть 2 сообщения в 2 разных форматах ... куда они пишут?Использует ли это блок Enterprise Logging?Если это так, вы должны проверить файл конфигурации - слушатель может быть зарегистрирован дважды.

...