.Net:如何抑制 TraceSource header ("SourceName TraceEventType: Id : ")?

标签 .net logging trace listener output-formatting

我有一个 TraceSource 对象,用于记录 VB.Net 应用程序的初始化。它附加了几个 TraceListeners:

  • ConsoleTraceListener
  • TextWriterTraceListener
  • EventLogTraceListener

  • 对于前两个,我希望条目输出为“原始”——也就是说,没有标准标题:
    SourceName TraceEventType: Id :
    我已经实现了一个包装器,当 TraceEventType 设置为 Verbose 时,它​​会执行此操作:
    If _buffer.EventType = TraceEventType.Verbose Then
        For Each listener As TraceListener In _traceSource.Listeners
            listener.Write(_buffer.Text)
        Next
    Else
        _traceSource.TraceEvent(_buffer.EventType, id, _buffer.Text)
    End If
    

    我可以为所有跟踪执行此操作,但随后 EventLog 中的所有条目都将使用 Level = Information 列出。所以我希望能够指定跟踪消息的严重性,但是我在 TraceSource 或 TraceListeners 上找不到任何允许我这样做的方法。据我所知,TraceListener 有以下写入选项:
  • 写()
  • WriteLine()
  • TraceData()
  • TraceEvent()
  • TraceTransfer()

  • 最后 3 个允许提供 TraceEventType(它正确标记了 EventLog 条目,但结果输出到控制台和日志文件然后包含前缀并以这样的方式结束(例如):
    Bootstrapper Warning: 0 : Failed to validate assembly
    有没有办法覆盖 ConsoleTraceListener 和 TextWriterTraceListener 如何将其输出格式化为不包含此 header ,同时能够使用 TraceEventType(对于 EventLog)标记条目?

    这是迄今为止我想出的最好的:
    For Each listener As TraceListener In _traceSource.Listeners
        If listener.GetType Is GetType(ConsoleTraceListener) OrElse listener.GetType Is GetType(TextWriterTraceListener) Then
            listener.Write(_buffer.Text)
        Else
            listener.TraceEvent(Nothing, _traceSource.Name, _buffer.EventType, id, _buffer.Text)
        End If
    Next
    

    这似乎有效,但在 TraceListener.TraceEvent Method 的文档中来自微软,它说:
    Important: This method is not intended to be called directly by application code but by members of the Debug, Trace, and TraceSource classes to write trace data to output.
    ..所以我不确定这是否是一件好事?

    编辑:

    我刚刚意识到,如果我在这里执行类似于上一个示例的操作,则根本不需要 TraceSource,因为无论如何它都会被绕过。但这也意味着我必须实现我自己的过滤和切换机制(但为了让它按我想要的方式工作,这可能是一个不错的代价)。

    最佳答案

    另一个具有您可以使用的可格式化监听器的类似项目是 Essential Diagnostics ,这实际上最初是受到 Ukadc.Diagnostics 的启发。

    但是,您已经表明您不想要外部依赖项,但您仍然有多种选择,无需重新编写框架的某些部分:

    (一种)
    .NET Framework 中设计的扩展点不是重写 TraceSource,而是编写您自己的 TraceListener。

    如果您编写自己的跟踪监听器“ConsoleWithoutPrefixListener”和“FileWithoutPrefixListener”,那么您可以覆盖 TraceEvent() 方法以仅将消息转发到 TraceWrite()(并删除前缀)。

    事实上,ConsoleTraceListener 或 TextWriterTraceListener 都不是密封的,所以我认为你可以从它们继承并使用 TraceEvent() 方法(加上构造函数)的一行覆盖来实现它。

    (二)
    另一种选择是保留针对源配置的 EventLogTraceListener,但在(而不是跟踪源)下配置其他两个监听器。

    这样做的缺点是在您的代码中,您每次都需要记录两次,例如:

    _traceSource.TraceEvent(_buffer.EventType, id, _buffer.Text)
    Trace.TraceWrite(_buffer.Text)

    如果您想编写一些带有前缀的消息而一些不带前缀的消息,那么您将需要两个跟踪源:一个配置了所有三个监听器,一个仅配置了事件日志监听器。

    然后,在您的包装器中写入源 A(所有三个)或源 B + Trace 静态方法。

    (C)
    就我个人而言,我的指导是不要使用跟踪来写入事件日志——如果问题足够重要以写入事件日志,您通常不希望用户能够通过配置将它们关闭。

    在这种情况下,您的包装器直接写入事件日志(EventLog.WriteEntry 或其他),然后您的代码写入文件和控制台的跟踪源和/或跟踪静态方法。

    请注意,要正确写入事件日志,您需要考虑权限。要创建事件日志源,您需要以管理员身份运行。作为开发人员,您通常可能拥有管理员权限,因此您需要在没有管理员权限的情况下正确测试。

    另请注意,只有初始创建需要管理员权限,并且这会在您编写第一条消息时自动完成,因此如果您已经以开发人员管理员身份完成此操作,则需要找到一台干净的机器进行测试。

    因此,通常您需要将 EventLogInstaller 作为代码的一部分,它由 InstallUtil(或等效的 MSI 或其他)运行,在安装期间创建事件日志源(因为安装是由管理员完成的)。然后,当程序运行时源存在。

    那么,这与写入跟踪有什么关系——好吧,如果你唯一要做的就是在你的配置中配置 EventLogTraceListener 那么对于普通用户来说它不会工作;它将尝试将事件写入源(在 initializeData 属性中),然后将尝试创建源,如果不以管理员身份运行将失败。

    如果您确实为事件源添加了安装程序,那么如果有人更改了配置文件,您仍然会遇到问题。

    因此,我建议直接在代码中创建 EventLogInstaller 和 EventLog,以确保名称匹配,而不是通过跟踪基础结构。

    关于.Net:如何抑制 TraceSource header ("SourceName TraceEventType: Id : ")?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4062277/

    相关文章:

    node.js - 自定义记录器和 Socket.io 1.x

    Python崩溃没有错误

    visual-studio-2010 - 从命令行运行 mstest.exe 时没有调试跟踪

    c# - 使用 .net 可执行文件执行 SQL 脚本

    qt - 替换 console.debug() 的日志记录后端 console.warn()

    .net - 在 WinForms 中向系统菜单(左上角图标菜单)添加条目?

    logging - ASP.NET 核心 2.2 + IIS : Where can I see logs (ILogger) for my app in IIS on server?

    db2 - 如何通过 WebSphere 启用和收集 DB2 跟踪?

    java - .NET 中的 GWT 之类的东西

    c# - 事件不会跨模块触发(prism、MVVM、silverlight c#)