WCF 仅跟踪失败的请求?

发布于 2024-10-03 10:51:13 字数 3546 浏览 2 评论 0原文

我想将跟踪信息保存到 .svclog 文件中,但仅限于失败的请求。这可能吗?如果是这样,具体如何?

我有一个每分钟调用数百次的 WCF 服务。在极少数情况下,客户端会收到错误 500,该错误发生在 WCF 内运行的代码边界之外(通常是安全问题)。我想确切地知道为什么会发生这些错误以及造成这些错误的原因。

我还很想使用跟踪查看器工具来检查 .svclog 文件。

据我所知,我有两个选择: 1) 通过 system.webServer\tracing 设置记录失败的请求来进行 FERB 跟踪。不幸的是,我真的不喜欢 IE 跟踪查看器的界面,也没有从跟踪日志中获得足够的信息来找出代码之外发生错误的原因。

2) 在system.diagnostics\trace 部分打开全局跟踪。本节生成了很棒的跟踪日志,其中包含我想要的所有捕获内容。但是,我找不到一种方法来仅捕获失败请求的信息。此部分捕获所有请求的跟踪信息。我的跟踪日志很快就填满了!

我的错误 500 是间歇性的且罕见。最终,我希望始终打开 .svclog 跟踪,但仅在发生失败的请求时才启动它。

请建议这是否可能?

谢谢你!

编辑:

格雷厄姆, 我已遵循您的建议,但没有看到我期望的日志。以下是 web.config 中的相关部分:

<system.diagnostics>
    <trace>
        <listeners>
            <add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="AzureDiagnostics">
                <filter type="" />
            </add>
        </listeners>
    </trace>

    <sources>
        <source name="System.ServiceModel" switchValue="Error">
            <listeners>
                <add name="wcfTracing" 
                         type="System.Diagnostics.XmlWriterTraceListener" 
                         initializeData="Traces1.svclog"/>
                <add name="log4netTracing"
                         type="AzureWatch.Model.Service.Log4netTraceListener,AzureWatch.Model.Service"/>
            </listeners>
        </source>
        <source name="System.ServiceModel.MessageLogging" switchValue="Error">
            <listeners>
                <add name="wcfTracing"
                         type="System.Diagnostics.XmlWriterTraceListener"
                         initializeData="Traces2.svclog"/>
                <!--<add name="log4netTracing"
                         type="AzureWatch.Model.Service.Log4netTraceListener,AzureWatch.Model.Service"/>-->
            </listeners>
        </source>
    </sources>
    </system.diagnostics>

<!-- ... -->

        <diagnostics wmiProviderEnabled="true">

        <messageLogging 
            logEntireMessage="true" 
            logMalformedMessages="true" 
            logMessagesAtServiceLevel="true" 
            logMessagesAtTransportLevel="true"
            maxSizeOfMessageToLog="1000000"
            maxMessagesToLog="-1" />
    </diagnostics>

这是 WCF 的客户端错误:

  <Exception>
    <Type>System.Net.Sockets.SocketException</Type>
    <Message>An existing connection was forcibly closed by the remote host</Message>
    <StackTrace>
      <Frame>at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)</Frame>
    </StackTrace>
  </Exception>

不幸的是,两个跟踪侦听器都没有记录任何内容。 失败的请求日志包含以下内容:

-GENERAL_READ_ENTITY_END 
    BytesReceived 0 
    ErrorCode 2147943395 
    ErrorCode The I/O operation has been aborted because of either a thread exit or an application request. (0x800703e3) 
     Warning
-MODULE_SET_RESPONSE_ERROR_STATUS 
    ModuleName ManagedPipelineHandler 
    Notification 128 
    HttpStatus 400 
    HttpReason Bad Request 
    HttpSubStatus 0 
    ErrorCode 0 
    ConfigExceptionInfo  
    Notification EXECUTE_REQUEST_HANDLER 
    ErrorCode The operation completed successfully. (0x0) 
    0 msInformational

I want to save trace information into .svclog files but only for failed requests. Is this possible? If so, how precisely?

I have a WCF service that's called hundreds of times per minute. On rare occasions clients will get an error 500 that occurs outside of the boundaries of my code running inside WCF (usually security issues). I'd like to know exactly why those errors are happening and what's causing them.

I would also really like to use the Trace Viewer tool to examine the .svclog files.

As far as I can tell, I have two options:
1) instrument FERB tracing by logging failed requests via system.webServer\tracing settings. Unfortunately, I really don't like the interface of the IE trace-viewer, nor do I get enough information from the trace-logs to figure out why an error outside of my code has occurred.

2) turn on the global tracing under system.diagnostics\trace section. This section produces great trace-logs with everything captured that I could ever want. However, I cannot find a way to only capture the information for failed requests. This section captures trace information for ALL requests. My trace logs quickly fill up!

My Errors 500 are intermittent and rare. Ultimately, I want to always have my .svclog tracing ON but only have it kick in when failed requests occur.

Please advice if this is possible?

Thank you!

Edit:

Graham,
I've followed your advice and I'm not seeing the logs I expect. Here are relevant sections from the web.config:

<system.diagnostics>
    <trace>
        <listeners>
            <add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="AzureDiagnostics">
                <filter type="" />
            </add>
        </listeners>
    </trace>

    <sources>
        <source name="System.ServiceModel" switchValue="Error">
            <listeners>
                <add name="wcfTracing" 
                         type="System.Diagnostics.XmlWriterTraceListener" 
                         initializeData="Traces1.svclog"/>
                <add name="log4netTracing"
                         type="AzureWatch.Model.Service.Log4netTraceListener,AzureWatch.Model.Service"/>
            </listeners>
        </source>
        <source name="System.ServiceModel.MessageLogging" switchValue="Error">
            <listeners>
                <add name="wcfTracing"
                         type="System.Diagnostics.XmlWriterTraceListener"
                         initializeData="Traces2.svclog"/>
                <!--<add name="log4netTracing"
                         type="AzureWatch.Model.Service.Log4netTraceListener,AzureWatch.Model.Service"/>-->
            </listeners>
        </source>
    </sources>
    </system.diagnostics>

<!-- ... -->

        <diagnostics wmiProviderEnabled="true">

        <messageLogging 
            logEntireMessage="true" 
            logMalformedMessages="true" 
            logMessagesAtServiceLevel="true" 
            logMessagesAtTransportLevel="true"
            maxSizeOfMessageToLog="1000000"
            maxMessagesToLog="-1" />
    </diagnostics>

Here is the WCF's client error:

  <Exception>
    <Type>System.Net.Sockets.SocketException</Type>
    <Message>An existing connection was forcibly closed by the remote host</Message>
    <StackTrace>
      <Frame>at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)</Frame>
    </StackTrace>
  </Exception>

Unfortunately there is NOTHING that's logged by either of the trace-listeners.
Failed Request log contains this:

-GENERAL_READ_ENTITY_END 
    BytesReceived 0 
    ErrorCode 2147943395 
    ErrorCode The I/O operation has been aborted because of either a thread exit or an application request. (0x800703e3) 
     Warning
-MODULE_SET_RESPONSE_ERROR_STATUS 
    ModuleName ManagedPipelineHandler 
    Notification 128 
    HttpStatus 400 
    HttpReason Bad Request 
    HttpSubStatus 0 
    ErrorCode 0 
    ConfigExceptionInfo  
    Notification EXECUTE_REQUEST_HANDLER 
    ErrorCode The operation completed successfully. (0x0) 
    0 msInformational

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

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

发布评论

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

评论(2

煞人兵器 2024-10-10 10:51:13

我尝试为我的 WCF 服务添加以下配置,并使用有效和无效的凭据访问该服务。只有具有无效凭据的请求才会导致服务跟踪文件中出现任何内容。我的服务使用自定义的 UserNamePasswordValidator 类,该类出现在堆栈跟踪中。重要的部分是 元素中的 switchValue="Error"propagateActivity="false"。不确定这是否正是您想要的,但至少看起来很接近......

<system.diagnostics>
  <sources>
    <source name="System.ServiceModel" switchValue="Error" 
            propagateActivity="false">
      <listeners>
        <add type="System.Diagnostics.DefaultTraceListener" name="Default">
          <filter type="" />
        </add>
        <add name="ServiceModelTraceListener">
          <filter type="" />
        </add>
      </listeners>
    </source>
  </sources>
  <sharedListeners>
    <add initializeData="C:\Path-to-log-file\Web_tracelog.svclog" 
         type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 
         name="ServiceModelTraceListener" 
         traceOutputOptions="DateTime, Timestamp, Callstack">
      <filter type="" />
    </add>
  </sharedListeners>
  <trace autoflush="true" />
</system.diagnostics>

I've tried putting in the following config for my WCF service, and hit the service with valid and invalid credentials. Only the requests with invalid credentials caused anything to appear in the service trace file. My service uses a custom UserNamePasswordValidator class, and this was present in the stack trace. The important parts are the switchValue="Error" and propagateActivity="false" in the <source> element. Not sure if this is exactly what you want, but it at least seems close...

<system.diagnostics>
  <sources>
    <source name="System.ServiceModel" switchValue="Error" 
            propagateActivity="false">
      <listeners>
        <add type="System.Diagnostics.DefaultTraceListener" name="Default">
          <filter type="" />
        </add>
        <add name="ServiceModelTraceListener">
          <filter type="" />
        </add>
      </listeners>
    </source>
  </sources>
  <sharedListeners>
    <add initializeData="C:\Path-to-log-file\Web_tracelog.svclog" 
         type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 
         name="ServiceModelTraceListener" 
         traceOutputOptions="DateTime, Timestamp, Callstack">
      <filter type="" />
    </add>
  </sharedListeners>
  <trace autoflush="true" />
</system.diagnostics>
一曲琵琶半遮面シ 2024-10-10 10:51:13

或者,可以将 EventTypeFilter 指定为侦听器的过滤器

  <listeners>
    <add name="console" 
      type="System.Diagnostics.ConsoleTraceListener" >
      <filter type="System.Diagnostics.EventTypeFilter" 
        initializeData="Error" />
    </add>
  </listeners>

Alternatively it's possible to specify EventTypeFilter as listener's filter

  <listeners>
    <add name="console" 
      type="System.Diagnostics.ConsoleTraceListener" >
      <filter type="System.Diagnostics.EventTypeFilter" 
        initializeData="Error" />
    </add>
  </listeners>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文