【问题标题】:WCF message logging - add filters with XPath queriesWCF 消息记录 - 使用 XPath 查询添加过滤器
【发布时间】:2011-05-27 18:06:15
【问题描述】:

我有一个具有以下合同的 WCF 服务:

[ServiceContract(Namespace="http://myNamespace.org/")]
public interface IMyService
{
    [OperationContract]
    string Invert(string s);

    [OperationContract]
    string ToUpper(string s);
}

客户端调用InvertToUpper 这两种方法。想象一下我想使用消息记录,但我感兴趣的唯一方法是ToUpper,因为另一种方法被大量使用并且记录所有消息会破坏日志;)

Here,我阅读了如何过滤写入日志的消息。但是我一定是做错了什么,因为我的日志仍然是空的......我的配置看起来像这样

<system.serviceModel>
  ...
  <diagnostics>
    <messageLogging logEntireMessage="true" logMessagesAtServiceLevel="false" logMalformedMessages="true" logMessagesAtTransportLevel="true">
      <filters>
        <add xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">/soap:Envelope/soap:Header/a:Action[starts-with(text(),'http://myNamespace.org/IMyService/ToUpper')]</add>
      </filters>
    </messageLogging>
  </diagnostics>

</system.serviceModel>

<system.diagnostics>
  <sources>
    <source name="System.ServiceModel.MessageLogging">
      <listeners>
        <add name="ServiceModelTraceListener" />
      </listeners>
    </source>
  </sources>
  <sharedListeners>
    <add initializeData="LogServer.svclog" type="System.Diagnostics.XmlWriterTraceListener" name="ServiceModelTraceListener" />
  </sharedListeners>
  <trace autoflush="true" />
</system.diagnostics>

如果我应用此过滤器,日志中不会有一条消息... 那么对于上面的链接示例,我做错了什么?

如果没有过滤器,默认消息的 xml 跟踪(使用字符串参数 hello 调用的方法 ToUpper)如下所示:

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
  <System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
    <EventID>0</EventID>
    <Type>3</Type>
    <SubType Name="Information">0</SubType>
    <Level>8</Level>
    <TimeCreated SystemTime="2011-05-27T17:53:53.9908714Z" />
    <Source Name="System.ServiceModel.MessageLogging" />
    <Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" />
    <Execution ProcessName="WcfLoggingTest.Host.vshost" ProcessID="4324" ThreadID="12" />
    <Channel />
    <Computer>MY-Machine</Computer>
  </System>
  <ApplicationData>
    <TraceData>
      <DataItem>
        <MessageLogTraceRecord Time="2011-05-27T19:53:53.9908714+02:00" Source="TransportReceive" Type="System.ServiceModel.Channels.BufferedMessage" xmlns="http://schemas.microsoft.com/2004/06/ServiceModel/Management/MessageTrace">
          <HttpRequest>
            <Method>POST</Method>
            <QueryString></QueryString>
            <WebHeaders>
              <VsDebuggerCausalityData>uIDPozEtlPQCjkhCodYdPWh6joUAAAAAamILDP7v3kG5sY6zKsB7HPPiLBWr+AVGmfFDQbk8GYAACQAA</VsDebuggerCausalityData>
              <SOAPAction>"http://myNamespace.org/IMyService/ToUpper"</SOAPAction>
              <Content-Length>157</Content-Length>
              <Content-Type>text/xml; charset=utf-8</Content-Type>
              <Accept-Encoding>gzip, deflate</Accept-Encoding>
              <Expect>100-continue</Expect>
              <Host>localhost:8731</Host>
            </WebHeaders>
          </HttpRequest>
          <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
            <s:Header>
              <To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://localhost:8731/Design_Time_Addresses/MyService/</To>
              <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://myNamespace.org/IMyService/ToUpper</Action>
            </s:Header>
            <s:Body>
              <ToUpper xmlns="http://myNamespace.org/">
                <s>hello</s>
              </ToUpper>
            </s:Body>
          </s:Envelope>
        </MessageLogTraceRecord>
      </DataItem>
    </TraceData>
  </ApplicationData>
</E2ETraceEvent>

更新: 对于每个对解决方案感兴趣的人,我终于在 jasso 的帮助下完成了工作,谢谢:

<add xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">/soap:Envelope/soap:Header/a:Action[starts-with(text(),'http://myNamespace.org/IMyService/ToUpper')]</add>

然后我编辑了我的界面并添加了方法Method1 直到Method3。我的目标是记录除与Method1Method3 相关的消息之外的所有内容。我使用以下过滤器做到了这一点:

<add xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">/soap:Envelope/soap:Header/a:Action[starts-with(text(),'http://myNamespace.org/IMyService/Method1')=false() and starts-with(text(),'http://myNamespace.org/IMyService/Method3')=false()]</add>

这样,只记录与InvertToUpperMethod2 相关的消息。

使用两个单独的过滤器来处理这个问题可能是一种更简洁的方法,但目前我对此非常满意。

【问题讨论】:

    标签: wcf logging xpath filter message


    【解决方案1】:

    您在 XPath 表达式中为 Action 元素使用了错误的命名空间

    你有

    xmlns:a="http://www.w3.org/2005/08/addressing"
    ... /a:Action[starts-with ...
    

    而且文件有

    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">
    

    所以命名空间不同,因为Action 元素附加了一个默认命名空间定义。

    此外,您的 XPath 正在搜索 soap:Envelope root 元素,因为您的表达式以 / 开头。我不熟悉该框架,它可能会从您的示例 XML(soap 内容)中选择一个子树,然后应用 XPath 过滤器。如果不是这种情况,并且您的 XPath 应该在给定的 XML 文档上生成匹配项,那么您应该以//soap:Envelope 元素的路径(如/*/*/*/*/*/soap:Envelope)开始表达式。在开头使用// 运算符效率低下,因为它需要遍历整个文档中的所有节点。

    【讨论】:

    • 如果我尝试使用此过滤器&lt;add xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none"&gt;/soap:Envelope/soap:Header/a:Action[starts-with(text(),'http://myNamespace.org/IMyService/Invert')]&lt;/add&gt; 将不会有一条消息进入日志:/
    • 您的第一个命名空间(soap)也不正确。而不是http://www.w3.org/2003/05/soap-envelope,您的文档有&lt;s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"&gt;,当我写答案时,我没有注意到另一个命名空间错误,对不起。
    • 天哪,我太瞎了......你说得对,如果我添加以下过滤器,它会按预期工作:) &lt;add xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none"&gt;/soap:Envelope/soap:Header/a:Action[starts-with(text(),'http://myNamespace.org/IMyService/ToUpper')]&lt;/add&gt; 谢谢!
    • 如果有人和我一样的白痴,只是试图从以前的评论中复制 XPath 表达式,请注意“/soap:Envelope”部分有一些特殊字符不是也显示在浏览器和 Notepad++ 中。他们使我的 web.config 崩溃了,所以只需删除它们就可以了(至少它对我有用)
    【解决方案2】:

    非常感谢您提供有用的信息!

    根据我自己的研究,要成功执行过滤,还必须执行以下关键点:

    1. 不要以双“/”开始 XPath 表达式,否则过滤将根本不起作用。尽管这个双“/”对于 XPath 语法是正确的(与 jasso 在 2011 年 5 月 27 日 23:06 指出的相同)。
    2. 不要依赖 WCF 配置编辑工具为涉及的 xml 命名空间选择别名。到现在发现“s12”不行,但是“s”或者“s1a”都可以(可能是微软做的bug,我不确定)。

    【讨论】:

      【解决方案3】:

      XPath 查询可能是问题所在。试试这个更简单的版本:

      <filters>
          <add xmlns:msgtr="http://schemas.microsoft.com/2004/06/ServiceModel/Management/MessageTrace" >//msgtr:SOAPAction[contains(.,'ToUpper')]</add>
      </filters>
      

      【讨论】:

      • 这个过滤器似乎没有效果。如果我应用它,则不会过滤任何消息。效果和我没有应用过滤器一样。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-08
      • 2010-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-17
      相关资源
      最近更新 更多