Журналирование сообщений WCF - добавьте фильтры с запросами XPath - PullRequest
5 голосов
/ 27 мая 2011

У меня есть служба WCF со следующим контрактом:

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

    [OperationContract]
    string ToUpper(string s);
}

Клиенты вызывают оба метода, Invert и ToUpper.Представьте, что я хочу использовать ведение журнала сообщений, но единственный метод, который меня интересует, это ToUpper, так как другой метод интенсивно используется, и регистрация всех сообщений приведет к срыву журнала;)

Здесь , я читал, как фильтровать сообщения, которые записываются в журнал.Но я, должно быть, что-то делаю не так, поскольку мой журнал остается пустым ... Моя конфигурация выглядит следующим образом

<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 сообщения по умолчанию (метод ToUpper, вызываемый со строковым параметром hello) выглядит следующим образом:

<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.Моей целью было записать все, кроме сообщений, связанных с Method1 и Method3.Я сделал это с помощью следующего фильтра:

<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>

Таким образом, только сообщения, относящиеся к Invert, ToUpper и Method2, регистрируются.

Это может быть чищеподход к решению этого с двумя отдельными фильтрами, но на данный момент я вполне доволен этим.

Ответы [ 3 ]

7 голосов
/ 28 мая 2011

Вы используете неправильное пространство имен для элемента Action в выражении XPath

У вас есть

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 (содержание мыла) и затем применить фильтр XPath. Если это не так, и ваш XPath должен создать совпадение с данным XML-документом, тогда вы должны начать выражение с // или с пути к элементу soap:Envelope (например, /*/*/*/*/*/soap:Envelope). Использование оператора // в начале неэффективно, поскольку требует прохождения всех узлов во всем документе.

4 голосов
/ 24 ноября 2011

Большое спасибо за полезную информацию!

Согласно моему собственному исследованию, чтобы успешно выполнить фильтрацию, должны соблюдаться следующие ключевые моменты:

  1. не начинайте выражение XPath с двойного «/», иначе фильтрация не будет работать вообще. Хотя это двойное «/» правильно в отношении синтаксиса XPath (так же, как то, на что указал Яссо 27 мая 23:06, 2011).
  2. не полагайтесь на инструмент редактирования конфигурации WCF, чтобы выбрать псевдоним для соответствующего пространства имен xml. До сих пор выясняется, что «s12» не работает, но «s» или «s1a» в порядке (возможно, это ошибка Microsoft, я не уверен).
0 голосов
/ 27 мая 2011

Вероятно, проблема в XPath-запросе.Попробуйте эту более простую версию:

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