First, a brief introduction to the project, our project is developed with VS2003, a project. The Web front-end Machine + Business processing (WebService layer) + database is arranged on different computers respectively.
Now Mister has a need to count the execution time of each page, and what WebService methods each call, the time of the call, and so on.
There are a lot of possible solutions, but I feel that using httpmodule+soapextension can not be done on the basis of changing the source code of the target system. Perhaps one day, Mister said, now do not need to count, I directly configure, no longer statistics on the line.
Because to invoke WebService, we use the write a soapextension, in its processmessage function, in the message. Stage is beforeserialize when recording a start time and collecting some data in the message. When Stage==afterdeserialize, collect some time and other data. Finally through Httpcontext.current.items[wsinvokemonitorkey] to obtain HttpModule object, the collected data in HttpModule inside.
In the HttpModule layer, we can collect data in the context of BeginRequest, PreRequestHandlerExecute, Presendrequestcontent, endrequest, and finally write into the log file by Log4net.
Concrete realization, should be very simple, master can skip.
First look at how to use it, just add a configuration in the web.config:
<configuration>
<system.web>
<add name="WSInvokeMonitorHttpModule" type="Hebmc.WebTools.WSInvokeMonitor.WSInvokeMonitorHttpModule,WSInvokeMonitor"/& gt;
<webServices>
<soapExtensionTypes>
<add type="Hebmc.WebTools.WSInvokeMonitor.SimpleWSInvokeMonitorExtension,WSInvokeMonitor&qu ot;
priority="1"
group="0" />
</soapExtensionTypes>
</webServices>
</system.web>
</configuration>
SoapExtension implementation:
SoapExtension
public class Simplewsinvokemonitorextension:soapextension
{
Private Const string Wsinvokemonitorkey = "__wsinvokemonitorkey__";
Private Wsinvokeinfo Invokeinfo = new Wsinvokeinfo ();
public override System.IO.Stream ChainStream (System.IO.Stream Stream)
{
return stream;
}
public override Object GetInitializer (Type servicetype)
{
return null;
}
public override Object GetInitializer (LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
{
return null;
}
public override void Initialize (object initializer)
{
}
public override void ProcessMessage (SoapMessage message)
{
If (message is soapclientmessage)
{
Switch (message. Stage)
{
Case Soapmessagestage.beforeserialize:
Acquisition Time
This.invokeInfo.BeginInvokeTime = DateTime.Now;
Collection WebService Method Name
This.invokeInfo.MethodName = message. Methodinfo.name;
Break
Case SoapMessageStage.AfterSerialize:
Break
Case SoapMessageStage.BeforeDeserialize:
Break
About to call methods
Case Soapmessagestage.afterdeserialize:
Acquisition Time
This.invokeInfo.EndInvokeTime = DateTime.Now;
PageInfo PageInfo = (PageInfo) Httpcontext.current.items[wsinvokemonitorkey];
if (pageInfo!= null)
{
Adding to a module record
Pageinfo.appendinvokeinfo (This.invokeinfo);
}
Break
After how to call
Default
throw new Exception ("No stage such as this");
}
}
else if (message is SoapServerMessage)
{
Switch (message. Stage)
{
Case SoapMessageStage.BeforeDeserialize:
Break
Case Soapmessagestage.afterdeserialize:
Break
Case Soapmessagestage.beforeserialize:
Break
Case SoapMessageStage.AfterSerialize:
Break
Default
throw new Exception ("No stage such as this");
}
}
}
}