自定义 TraceListener 和多个消息

发布于 2024-11-28 09:36:17 字数 1423 浏览 0 评论 0原文

我在使用自定义 TraceListener 时遇到一些困难。问题是写入单个跟踪行会产生两次调用,一次调用 Write(),另一个调用 WriteLine()。对 Write() 的调用包含跟踪源、级别和事件 ID。对 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()

“错误消息”

是否可以将这两个消息结合起来?还是只过滤第一个?谢谢!

I'm having some difficulity with a custom TraceListener. The issue is that writing a single trace line produces two calls, one to Write(), the other to WriteLine(). The call to Write() contains the trace source, level, and event id. The call to WriteLine() is the actual message

It looks like the trace listener is instantiated only once, so I can't just queue the first call to Write(). It looks like there's no way to correlate the two calls. Unfortunately this is a problem, since it causes me to send 2 messages to the remote service, doubling the overhead.

There doesn't seem any generic way to filter the calls either. I'd accept just ignoring the call with the source and level, but it seems like that might be very prone.

Here's a sample piece of code:

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

Usage is with:

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

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

Will produce a call to Write() with:

"Source: Error: 0"

And then a call to WriteLine() with

"Error Message"

Is it possible to combine the two messages? Or just filter the first? Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜警司 2024-12-05 09:36:17

有 2 条消息,有 2 种不同的格式……这些消息要写到哪里?这是使用企业日志记录块吗?如果是这样,您应该检查配置文件 - 侦听器可能会注册两次。

There's 2 messages with 2 different formats... where are these writing to? Is this using the Enterprise Logging block? If so, you should check the config file - the listener might be registered twice.

独﹏钓一江月 2024-12-05 09:36:17

我能够通过实现来自 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 帐户 上找到一个工作示例

I was able to solve this by implementing the TraceListener base class from Ukadc Diagnostics

The base class is:

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
}

and my custom 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
    }
}

You can find a working example on my github account

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文