.net - 使用 Ent-Lib 拨号跟踪的意外后果,没有错误记录

标签 .net error-handling enterprise-library trace

我在使用企业库跟踪和异常日志记录时遇到了意外问题。我注意到的是,当我使用“App.Config”中的类别过滤器调低跟踪日志记录时,我无意中关闭了发生在我过滤到的跟踪日志记录级别以下的错误的错误日志记录。

例如:

Private Sub ProcA()
    Using (New Tracer("Trace High Level")
        Try
            <Do some logic here>
            ProcB()

        Catch ex AS Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(ex, "Log Only Policy")
            If rethrow Then
                Throw ex
            End If
        End Try
    End Using
End Sub

Private Sub ProcB()
    Using (New Tracer("Trace Mid Level")
        Try
            <Do some logic here>
            ProcC()

        Catch ex AS Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(ex, "Log Only Policy")
            If rethrow Then
                Throw ex
            End If
        End Try
    End Using
End Sub

Private Sub ProcC()
    Using (New Tracer("Trace Low Level")
        Try
            Throw New Exception("Test error logging")

        Catch ex AS Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(ex, "Log Only Policy")
            If rethrow Then
                Throw ex
            End If
        End Try
    End Using
End Sub

现在,如果我在 App.Config 中设置了我的类别过滤器以允许完全跟踪,我就会将我的所有跟踪消息和 ProcC 中抛出的错误消息写入我的日志。但是,如果我调低跟踪以仅记录 “Trace High Level”,例如,我会收到我的高级跟踪消息,但不会记录 ProcC 中抛出的错误。

我已经逐步检查了代码并注意到在 ProcC 中出现错误时 LogEntry 的累积类别包括 "Trace High Level"、"Trace Mid Level"、 “跟踪低级别”“错误”。因此,只要我没有跟踪记录我的所有级别,对 LogWriterImpl.cs 中的 ShouldLog() 的调用就会返回 false,结果是我的错误不是已记录。

我的问题:
在这种情况下,有没有办法配置企业库日志记录,即使我没有在所有级别进行详细的跟踪日志记录,仍然允许记录错误?

回应@Tuzo 的评论:

<exceptionHandling>
    <exceptionPolicies>
      <add name="Exception Policy">
        <exceptionTypes>
          <add name="Exception" type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
            postHandlingAction="NotifyRethrow">
            <exceptionHandlers>
              <add name="Exception Logging" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging"
                logCategory="Error" eventId="666" severity="Error" title="REPSS .Net Exception Handler"
                formatterType="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.TextExceptionFormatter, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling"
                priority="1" />
            </exceptionHandlers>
          </add>
        </exceptionTypes>
      </add>
      <add name="Log Only Policy">
        <exceptionTypes>
          <add name="Exception" type="System.Exception, mscorlib" postHandlingAction="None">
            <exceptionHandlers>
              <add name="Exception Logging" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging"
                logCategory="Error" eventId="666" severity="Error" title="REPSS .Net Exception Handler"
                formatterType="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.TextExceptionFormatter, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling"
                priority="2" />
            </exceptionHandlers>
          </add>
        </exceptionTypes>
      </add>
    </exceptionPolicies>


<loggingConfiguration name="Logging Application Block" tracingEnabled="true"
    defaultCategory="General" logWarningsWhenNoCategoriesMatch="true">
    <listeners>
      <add name="Database Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.Database.FormattedDatabaseTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging.Database"
        listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Database.Configuration.FormattedDatabaseTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging.Database"
        databaseInstanceName="ReiApplicationLogging" writeLogStoredProcName="WriteLog"
        addCategoryStoredProcName="AddCategory" formatter="Database Rei Applications Logging Formatter"
        traceOutputOptions="None" />
      <add name="Formatted EventLog TraceListener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging"
        listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging"
        source="REPSS .Net" formatter="Text Formatter" log="REI Applications"
        machineName="" traceOutputOptions="LogicalOperationStack" />
      <add name="SDSCellPhone" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.EmailTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging"
        listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.EmailTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging"
        toAddress="sstudy@flexifloat.com" fromAddress="sstudy@flexifloat.com"
        subjectLineStarter="REPSS .Net: " subjectLineEnder="(sms forward)"
        smtpServer="REISRV05" smtpPort="25" formatter="Cell Phone Formatter"
        authenticationMode="WindowsCredentials" traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, ProcessId, ThreadId, Callstack"
        filter="Off" />
      <add name="Rolling Flat File Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=null"
        listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=null"
        fileName="C:\Users\sstudy\Documents\Visual Studio Projects\_Production\Win Forms\REPSS\REPSS .Net Solution\RepssDN\repps net rolling error.log"
        footer="^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
        formatter="Text Formatter" header="vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv"
        rollInterval="Week" traceOutputOptions="LogicalOperationStack, Callstack" />
    </listeners>
    <formatters>
      <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging"
        template="Timestamp: {timestamp(local:F)}&#xD;&#xA;Title:{title}&#xD;&#xA;Machine: {machine}"
        name="Cell Phone Formatter" />
      <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging"
        template="{newline}{newline}________________________&#xD;&#xA;&#xD;&#xA;Timestamp: {timestamp(local:F)}&#xD;&#xA;&#xD;&#xA;Title:{title}&#xD;&#xA;Process: {processName}&#xD;&#xA;&#xD;&#xA;Extended Properties: &#xD;&#xA;&#xD;&#xA;{dictionary({key} - {value}&#xD;&#xA;&#xD;&#xA;)}{newline}&#xD;&#xA;&#xD;&#xA;Category: {category}&#xD;&#xA;&#xD;&#xA;Priority: {priority}&#xD;&#xA;&#xD;&#xA;EventId: {eventid}&#xD;&#xA;&#xD;&#xA;Severity: {severity}&#xD;&#xA;&#xD;&#xA;Machine: {machine}&#xD;&#xA;&#xD;&#xA;Application Domain: {processName}&#xD;&#xA;&#xD;&#xA;{newline}&#xD;&#xA;&#xD;&#xA;Message: {message}&#xD;&#xA;&#xD;&#xA;{newline}"
        name="Database Rei Applications Logging Formatter" />
      <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging"
        template="Timestamp: {timestamp(local:F)}&#xD;&#xA;Title:{title}&#xD;&#xA;Message: {message}&#xD;&#xA;{newline}&#xD;&#xA;Category: {category}&#xD;&#xA;Priority: {priority}&#xD;&#xA;EventId: {eventid}&#xD;&#xA;Severity: {severity}&#xD;&#xA;Machine: {machine}&#xD;&#xA;Application Domain: {processName}&#xD;&#xA;Process Id: {processId}&#xD;&#xA;Process Name: {processName}&#xD;&#xA;Win32 Thread Id: {win32ThreadId}&#xD;&#xA;Thread Name: {threadName}&#xD;&#xA;{newline}&#xD;&#xA;Extended Properties: &#xD;&#xA;{dictionary({key} - {value}&#xD;&#xA;)}"
        name="Text Formatter" />
    </formatters>
    <logFilters>
      <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Filters.LogEnabledFilter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=null"
        enabled="true" name="Enable All Logging" />
      <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Filters.CategoryFilter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=null"
        categoryFilterMode="AllowAllExceptDenied" name="Trace Filter">
        <categoryFilters>
          <add name="Trace Insane Detail" />
          <add name="Trace Low Level" />
        </categoryFilters>
      </add>
    </logFilters>
    <categorySources>
      <add switchValue="Error" name="Development Error">
        <listeners>
          <add name="Database Trace Listener" />
          <add name="Formatted EventLog TraceListener" />
          <add name="SDSCellPhone" />
        </listeners>
      </add>
      <add switchValue="Error" name="Error">
        <listeners>
          <add name="Database Trace Listener" />
          <add name="Formatted EventLog TraceListener" />
          <add name="SDSCellPhone" />
        </listeners>
      </add>
      <add switchValue="ActivityTracing" name="Feature Usage">
        <listeners>
          <add name="Database Trace Listener" />
          <add name="Formatted EventLog TraceListener" />
        </listeners>
      </add>
      <add switchValue="All" name="General">
        <listeners>
          <add name="Database Trace Listener" />
          <add name="Formatted EventLog TraceListener" />
        </listeners>
      </add>
      <add switchValue="All" name="Security">
        <listeners>
          <add name="Database Trace Listener" />
          <add name="Formatted EventLog TraceListener" />
        </listeners>
      </add>
      <add switchValue="ActivityTracing" name="Trace Start Up">
        <listeners>
          <add name="Database Trace Listener" />
          <add name="Formatted EventLog TraceListener" />
        </listeners>
      </add>
      <add switchValue="ActivityTracing" name="Trace Shut Down">
        <listeners>
          <add name="Database Trace Listener" />
          <add name="Formatted EventLog TraceListener" />
        </listeners>
      </add>
      <add switchValue="ActivityTracing" name="Trace Menu Item Selected">
        <listeners>
          <add name="Database Trace Listener" />
          <add name="Formatted EventLog TraceListener" />
        </listeners>
      </add>
      <add switchValue="ActivityTracing" name="Trace High Level">
        <listeners>
          <add name="Database Trace Listener" />
          <add name="Formatted EventLog TraceListener" />
        </listeners>
      </add>
      <add switchValue="ActivityTracing" name="Trace Mid Level">
        <listeners>
          <add name="Database Trace Listener" />
          <add name="Formatted EventLog TraceListener" />
        </listeners>
      </add>
      <add switchValue="ActivityTracing" name="Trace Low Level">
        <listeners>
          <add name="Database Trace Listener" />
          <add name="Formatted EventLog TraceListener" />
        </listeners>
      </add>
      <add switchValue="ActivityTracing" name="Trace Detail">
        <listeners>
          <add name="Database Trace Listener" />
        </listeners>
      </add>
      <add switchValue="ActivityTracing" name="Trace Insane Detail">
        <listeners>
          <add name="Database Trace Listener" />
        </listeners>
      </add>
      <add switchValue="All" name="Trace">
        <listeners>
          <add name="Rolling Flat File Trace Listener" />
        </listeners>
      </add>
      <add switchValue="Verbose" name="Useful Info">
        <listeners>
          <add name="Database Trace Listener" />
          <add name="Formatted EventLog TraceListener" />
        </listeners>
      </add>
    </categorySources>
    <specialSources>
      <allEvents switchValue="All" name="All Events">
        <listeners>
          <add name="Database Trace Listener" />
          <add name="Formatted EventLog TraceListener" />
        </listeners>
      </allEvents>
      <notProcessed switchValue="All" name="Unprocessed Category">
        <listeners>
          <add name="Database Trace Listener" />
          <add name="Formatted EventLog TraceListener" />
        </listeners>
      </notProcessed>
      <errors switchValue="All" name="Logging Errors &amp; Warnings">
        <listeners>
          <add name="Database Trace Listener" />
          <add name="SDSCellPhone" />
          <add name="Formatted EventLog TraceListener" />
        </listeners>
      </errors>
    </specialSources>
  </loggingConfiguration>

尝试使用@Tuzo推荐的“SourceLevel”:
@Tuzo,我尝试了“SourceLevel”开关并修改了 app.config 以“关闭”较低级别的跟踪类别。有趣的是,这会产生相反的问题。由于跟踪链接在一起,EntLib 看到链中至少有一个跟踪类别不是“关闭”(在我的测试用例中,“跟踪高级”)并继续并在较低级别。
此 EntLib 逻辑在 LogWriterImpl 类的 ProcessLog() 中进行编码。

最终结果是所有较低级别的跟踪现在都已记录,即使它们已关闭。从好的方面来说,我现在确实记录了我的错误。 ;)

我想我会看一下您推荐的自定义过滤器,看看我是否可以让它适用于这种情况。

最佳答案

您看到的行为似乎是设计使然。

如果存在过滤器,则 LogEntry 必须成功通过所有过滤器。与类别过滤器类似,如果您指定 AllowAllExceptDenied 并且其中一个类别出现在日志条目中,则它不会通过类别过滤器并且不会记录消息。

“告诉我一些我还不知道的事情”,你在说。 :)

我可以想到 2 种方法来解决这个问题:

  • 从使用过滤器切换到 源级别
  • 创建一个完全符合您需要的自定义过滤器

从使用过滤器切换到 SourceLevel

您可以使用 SourceLevel(开关值)代替通过过滤器启用和禁用事件跟踪。例如,删除您的过滤器,但对于听众“Trace Insane Detail”和“Trace Low Level”(如在您的过滤器中),将 switchValue 设置为 Off;您仍然可以启用“Trace Mid Level”。

  <add switchValue="Off" name="Trace Insane Detail">
    <listeners>
      <add name="Database Trace Listener" />
    </listeners>
  </add>
  <add switchValue="ActivityTracing" name="Trace Mid Level">
    <listeners>
      <add name="Database Trace Listener" />
      <add name="Formatted EventLog TraceListener" />
    </listeners>
  </add>
  <add switchValue="Off" name="Trace Low Level">
    <listeners>
      <add name="Database Trace Listener" />
      <add name="Formatted EventLog TraceListener" />
    </listeners>
  </add>

创建一个自定义过滤器 正是您所需要的

自定义过滤器几乎可以让您做任何您想做的事情。它更复杂,所以只有在绝对必要时才应该这样做。参见 Using Custom Filters in the Enterprise Library Logging Block一个很好的例子。

关于.net - 使用 Ent-Lib 拨号跟踪的意外后果,没有错误记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6460026/

相关文章:

.net - ASP.NET MVC 和测试驱动开发

java - 引发错误时会发生什么?

c# - .NET : Logging entry/exit without AOP?

C# SQL Server脚本更改数据库问题

java - 如何让 Java 应用程序订阅 NServiceBus 发布者?

c# - 使用 HTTP PUT 上传的文件在开头和结尾有额外的数据

.net - Elasticsearch Nest field boost + fuzzy

configuration - 为什么 PHP 5.2.14 不显示任何错误(即使是从命令行)?

php - pg_query错误直接进入控制台,而pg_last_error不返回任何内容

c# - 如何在 MySQL 的 ASP.NET C# 应用程序中使用微软企业库