Журналирование входящих запросов в WCF-сервисе
Потребовалось логгировать работу моего 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-сообщения, в которых поступают запросы:
Social networks
Zuck: Just ask
Zuck: I have over 4,000 emails, pictures, addresses, SNS
smb: What? How'd you manage that one?
Zuck: People just submitted it.
Zuck: I don't know why.
Zuck: They "trust me"
Zuck: Dumb fucks