пятница, 25 декабря 2009 г.

Логирование сообщений в WCF

Работая с WCF редко приходится задумываться "А в каком виде сообщения передаются между клиентом и сервером". В общем случае, достаточно настроить web.config, что бы изменить протокол передачи данных.

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

1. Воспользоваться приемами трассировки.
2. Реализовать заказное поведение оконечной точки.

Трассировка и протоколирование сообщений в WCF

Трассировка используется для вывода информации о потоке выполнения и отдельных действий различных компонентов распределенного приложения. Механизм же протоколирования сообщений предназначен для сохранения содержимого сообщений, которыми обмениваются клиент и служба.
Протоколирование сообщений основано на классах из пространства имен System.Diagnostics и по умолчанию выключено. Что бы его включить, необходимо сначала добавить прослушиватель трассировки (например, XmlWriterTraceListener) для обработки информации от источника трассировки System.ServiceModel.MessageLogging.

Давайте изменим App.config клиента.
<configuration>
    <system.serviceModel>
        <behaviors .../>
        <diagnostics>
            <messageLogging 
                logEntireMessage="true" 
                logMessagesAtTransportLevel="true"
                maxMessagesToLog="4000" />

        </diagnostics>
    </system.serviceModel>

<system.diagnostics>
        <sources>
            <source name="System.ServiceModel.MessageLogging">
                <listeners>
                    <add type="System.Diagnostics.XmlWriterTraceListener" name="messages" initializeData="messages.svclog">
                    </add>
                </listeners>
            </source>

        </sources>
    </system.diagnostics>
</configuration>

Мы добавили источник System.ServiceModel.MessageLogging, с помощью которого выводятся сообщения для протоколирования. Обрабатываем же получаемую от него информацию прослушивателем XmlWriterTraceListener.
Теперь в файл messages.svclog пишутся логи сообщений. Для чтения и анализа этого файла можно воспользоваться программой Service Trace Viewer. Она может использоваться для импорта протоколов сообщений, сформированных одним или несколькими компонентами распределенного приложения. Эта программа входит в пакет Windows SDK.

Реализация заказного поведения для трассировки.

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

Реализация заказного поведения состоит из трех шагов:
Шаг 1. Создать класс, который реализует интерфейс Inspector, Selector, Formater или Invocer. В нашем случае это IClientMessageInspector

internal class LogMessageInspector : IClientMessageInspector
    {
        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            Console.WriteLine("---request---");
            Console.WriteLine(request.ToString());
            Console.WriteLine("---end---");
            return request;
        }

        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
            Console.WriteLine("---Reply---");
            Console.WriteLine(reply.ToString());
            Console.WriteLine("---end---");
        }
    }

Шаг 2. создать класс, который реализует один из интерфейсов поведения: IServiceBehavior, IEndpointBehavior, IOperationBehavior или IContractBehavior. У нас это IEndpointBehavior.

public class LogEndpointBehavior : IEndpointBehavior
    {
        public void Validate(ServiceEndpoint endpoint)
        {
        }

        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            clientRuntime.MessageInspectors.Add(new LogMessageInspector());
        }
    }

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

            ChannelFactory<IFilms> factory = new ChannelFactory<IFilms>("poxWcfService");
            //Add logging of message to console
            factory.Endpoint.Behaviors.Add(new LogEndpointBehavior());
            IFilms client = factory.CreateChannel();

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

1 комментарий:

  1. Было бы не плохо, посмотреть со стороны сервера, что приходит.

    ОтветитьУдалить