Непреднамеренные последствия отключения трассировки с использованием Ent-Lib, без регистрации ошибок - PullRequest
3 голосов
/ 24 июня 2011

Я столкнулся с неожиданной проблемой, используя корпоративную библиотеку трассировка и ведение журнала исключений . Что я заметил, так это то, что, когда я отключаю ведение журнала трассировки с помощью фильтров категорий в «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, не регистрируется.

Я прошел по коду и отметил, что накопленные категории для LogEntry на момент ошибки в ProcC включают "Trace High Level", "Trace Mid Level", "Trace Low Level" и "Error". В результате вызов ShouldLog() в LogWriterImpl.cs возвращает 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>

Попытка использовать «SourceLevel», рекомендованный @Tuzo:
@Tuzo, я попробовал переключателю «SourceLevel» и изменил app.config, чтобы отключить «категории трассировки» нижнего уровня. Интересно, что это создает противоположную проблему. Поскольку трассы связаны друг с другом, EntLib видит, что в цепочке есть по крайней мере одна категория трасс, которая не имеет значения «Выкл.» (В моем тестовом примере «Высокий уровень трассировки»), и регистрирует отключенную трассировку на более низкий уровень (ы).
Эта логика EntLib кодируется в ProcessLog () в классе LogWriterImpl.

Конечным результатом является то, что все трассировки нижнего уровня теперь регистрируются, даже если они выключены. С другой стороны, моя ошибка теперь регистрируется. ;)

Я думаю, что я посмотрю на пользовательский фильтр, который вы рекомендовали, и посмотрим, смогу ли я сделать это для этого сценария.

1 Ответ

2 голосов
/ 24 июня 2011

Поведение, которое вы видите, похоже на замысел.

Если фильтры существуют, LogEntry должен успешно пройти через все фильтры. Аналогично для фильтра категорий, если вы укажете AllowAllExceptDenied и одна из категорий появится в записи журнала, он не пройдет фильтр категорий и сообщение не будет зарегистрировано.

«Скажи мне что-то, чего я еще не знаю», - говорите вы. :)

Я могу придумать 2 подхода, чтобы обойти это:

  • Переключиться с использования фильтра на SourceLevel
  • Создайте пользовательский фильтр, который делает именно то, что вам нужно

Переключиться с использования фильтра на SourceLevel

Вместо того, чтобы включать и отключать трассировки активности через фильтр, вы, вероятно, могли бы сделать это точно так же, используя SourceLevel (switchvalue). Например, удалите ваш фильтр, но для слушателей «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>

Создать пользовательский фильтр, который делает именно то, что вам нужно

Пользовательский фильтр позволит вам делать практически все, что вы захотите. Это сложнее, поэтому, вероятно, следует делать только в случае крайней необходимости. См. Использование пользовательских фильтров в журнале Enterprise Library для хорошего примера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...