Já mostrei neste artigo e vídeo como podemos fazer para habilitar o log de mensagens do WCF, onde podemos capturar o envelope da mensagem SOAP que está sendo trafegado entre as partes envolvidas.
Somente o fato de habilitar já é o suficiente para capturar todas as mensagens que chegam ao serviço e também aquelas que são devolvidas para os respectivos clientes, contendo o resultado do processamento da operação. Dependendo do tamanho do envelope e do volume de requisições, em pouco tempo, você pode consumir uma grande quantidade de espaço em disco.
Para melhorar isso, o message logging do WCF fornece filtros que podemos aplicar aos headers do envelope SOAP, e com isso, analisar e decidir se queremos ou não catalogar aquela mensagem. Para exemplificar, considere o contrato abaixo, que possui duas operações simples:
[ServiceContract(Namespace = “http://www.israelaece.com/servicos“)]
public interface IContrato
{
[OperationContract]
ItemDeExtrato[] VisualizarExtrato(string conta);
[OperationContract]
void Debitar(string conta, decimal valor);
}
A operação VisualizarExtrato retorna um array de itens que fazem parte de um extrato de uma determinada conta, informada através do parâmetro conta. Já a segunda operação, recebe a conta e o valor a ser debitado da mesma. Como sabemos, podemos ligar o logging do WCF para começarmos a capturar as mensagens que chegam para este serviço como um todo. O código abaixo ilustra essa configuração:
<?xml version=”1.0″ encoding=”utf-8″ ?>
<configuration>
<system.diagnostics>
<sources>
<source name=”System.ServiceModel.MessageLogging”
switchValue=”All”
propagateActivity=”true”>
<listeners>
<add name=”Xml”
type=”System.Diagnostics.XmlWriterTraceListener”
initializeData=”C:TempMessageLogging.svclog” />
</listeners>
</source>
</sources>
<trace autoflush=”true” />
</system.diagnostics>
<system.serviceModel>
<diagnostics>
<messageLogging logEntireMessage=”true”
logMessagesAtServiceLevel=”true”
maxMessagesToLog=”100″
maxSizeOfMessageToLog=”200000″ />
</diagnostics>
</system.serviceModel>
</configuration>
Com isso, ao abrir o arquivo gerado pelo logging recém habilitado, veremos a mensagem que chegou para o serviço com a requisição de débito:
<s:Envelope xmlns:a=”http://www.w3.org/2005/08/addressing”
xmlns:s=”http://www.w3.org/2003/05/soap-envelope”>
<s:Header>
<Action a:mustUnderstand=”1″
xmlns=”http://www.w3.org/2005/08/addressing”
xmlns:a=”http://www.w3.org/2003/05/soap-envelope”>http://www.israelaece.com/servicos/IContrato/Debitar</Action>
<a:MessageID>urn:uuid:25eb06f3-b1d5-41a4-99c8-37f1a5905d7f</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand=”1″>net.tcp://localhost:9392/srv</a:To>
</s:Header>
<s:Body>
<Debitar xmlns=”http://www.israelaece.com/servicos”>
<conta>000001</conta>
<valor>1200</valor>
</Debitar>
</s:Body>
</s:Envelope>
Mas o problema é que também as mensagens que chegam para a operação VisualizarExtrato também serão catalogadas, e como elas possuem uma grande quantidade de informações, neste caso, não temos a necessidade de monitorar essas mensagens. É aqui que entra em cena os filtros, tema deste artigo. Dentro do elemento messageLogging temos um sub-elemento chamado de filters, que nada mais é que uma coleção, onde você pode elencar diversos filtros, utilizando a linguagem/tecnologia XPath para analisar e escrever tais filtros. Exemplo:
<system.serviceModel>
<diagnostics performanceCounters=”All”>
<messageLogging logEntireMessage=”true”
logMessagesAtServiceLevel=”true”
logMessagesAtTransportLevel=”false”
maxMessagesToLog=”100″
maxSizeOfMessageToLog=”200000″>
<filters>
<add xmlns:a=”http://www.w3.org/2005/08/addressing”
xmlns:s=”http://www.w3.org/2003/05/soap-envelope”>/s:Envelope/s:Header/a:Action%5Btext()=”http://www.israelaece.com/servicos/IContrato/Debitar“]</add>
</filters>
</messageLogging>
</diagnostics>
</system.serviceModel>
Modificando o arquivo de configuração do serviço, estamos acrescentando um filtro que utilizaremos para catalogar as mensagens somente se a Action (que representa a operação) for igual a Debitar, descartando assim todas as mensagens que chegam para as outras operações e, consequentemente, eventuais dados gerados por elas.