Потребовалось логгировать работу моего WCF-сервиса, чтобы видеть, какие запросы присылают клиенты с целью натыкать их носом в неправильно сформированные SOAP-сообщения. И оказалось, что Microsoft об этом уже позаботилась, и такой функционал включается в два счёта.

Все манипуляции производятся с конфигом, в коде сервиса ничего писать не придётся.

Как вам должно быть известно, WCF-сервис состоит из двух частей: сам сервис и его хост. В качестве хоста может быть IIS (то есть, веб-приложение), Windows-служба или просто десктопное приложение (как с интерфейсом, так и консольное). У меня WCF хостится в Windows-службе.

И вот изменениям подвергается конфиг хоста, а вовсе не конфиг WCF-модуля (как это может показаться логичным).

Нужно добавить такую секцию в теге <configuration>:

<system.diagnostics>
    <sources>
        <source name="System.ServiceModel"
                     switchValue="All"
                     propagateActivity="true">
            <listeners>
                <add name="traceListener" />
            </listeners>
        </source>
        <source name="System.ServiceModel.MessageLogging"
                     switchValue="All">
            <listeners>
                <add name="traceListener" />
            </listeners>
        </source>
    </sources>
    <sharedListeners>
        <add name="traceListener"
                type="System.Diagnostics.XmlWriterTraceListener"
                initializeData="service_messages.svclog" />
    </sharedListeners>
</system.diagnostics>

В атрибуте initializeData пишется путь к файлу и его имя. То есть, у меня лог будет писаться в текущий каталог исполняемого файла службы в файл с именем service_messages.svclog.

Добавить (если нет) секцию <system.serviceModel> с таким тегом внутри:

<diagnostics>
    <messageLogging
         logEntireMessage="true"
         logMalformedMessages="true"
         logMessagesAtServiceLevel="true"
         logMessagesAtTransportLevel="true"
         maxMessagesToLog="200"/>
</diagnostics>

Вот как теперь выглядит конфиг полностью:

<configuration>
    <configSections>
        ...
    </configSections>
    <startup> 
        ...
    </startup>
    <userSettings>
        <myservice.Properties.Settings>
            ...
        </myservice.Properties.Settings>
    </userSettings>

    <system.diagnostics>
        <sources>
            <source name="System.ServiceModel"
                         switchValue="All"
                         propagateActivity="true">
                <listeners>
                    <add name="traceListener" />
                </listeners>
            </source>
            <source name="System.ServiceModel.MessageLogging"
                         switchValue="All">
                <listeners>
                    <add name="traceListener" />
                </listeners>
            </source>
        </sources>
        <sharedListeners>
            <add name="traceListener"
                    type="System.Diagnostics.XmlWriterTraceListener"
                    initializeData="service_messages.svclog" />
        </sharedListeners>
    </system.diagnostics>
    
    <system.serviceModel>
        <diagnostics>
            <messageLogging
                 logEntireMessage="true"
                 logMalformedMessages="true"
                 logMessagesAtServiceLevel="true"
                 logMessagesAtTransportLevel="true"
                 maxMessagesToLog="200"/>
        </diagnostics>
    </system.serviceModel>
</configuration>

Теперь при работе сервиса поступающие запросы будут записываться в лог (service_messages.svclog в каталоге с исполняемым файлом службы), который можно просматривать приложением Service Trace Viewer Tool. И тут есть одна мелочь, которую я узнал очень не сразу, потому успел немного пригореть в процессе - просматривать лог можно только при остановленном сервисе, иначе вам будет выдавать сообщение типа “непредусмотренный конец файла” и какое-то ещё.

И можно смотреть SOAP-сообщения, в которых поступают запросы:

Microsoft Service Trace Viewer