Tuesday, September 29, 2009 7:03 PM
lukaashek
WCF Simple Charting Extensibility
Už je to nějakou dobu (myslím si, že to bylo v době vydání charting controlu pro .NET) co jsem si napsal takové rozšíření pro WCF, které sbíralo údaje o tom kdy a kolikrát byla na službe zavolána konkrétní metoda a následně vizualizovalo pomocí těchto grafů buď ve WinForm či WebForm aplikaci. O možnostech rozšíření si můžete přečíst na 1 a 2.
Moje rozšíření vypadá následovně:
public class MessageInspector : IDispatchMessageInspector
{
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
DateTime date = DateTime.Now;
var path = string.Format("{0}_{1}.xml", date.Month, date.Year);
string uri = Path.Combine(ConfigurationManager.AppSettings["reportsDir"], path);
DailyReport report = new DailyReport(uri, date.Day);
var action = request.Headers.Action.Split('/');
report.UpdateCalls(action[action.Length - 1]);
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
}
}
Ve třídě MessageInspector provedu implementaci metody AfterReceiveRequest, tedy jakmile dorazí požadavek na server, získám si aktuální měsíc a rok a podle toho otevřu konkrétní xml soubor (strukturu xml souboru uvedu později). Dále si zjistím název operace, která se volá a inkrementuju počet volání.
public class MessageEndpointBehavior : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
new DailyReport(endpointDispatcher.DispatchRuntime.Operations.Select(x => x.Name), DateTime.Now);
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new MessageInspector());
}
public void Validate(ServiceEndpoint endpoint)
{
}
}
Třída MessageEndpointbehavior mi zaregistruje mého message inspectora a zárověn vytvoří defaultní strukturu pro daný měsíc. Z vlasnosti endpointDispatcher.DispatchRuntime.Operations si získám seznam všech operací, které mi služba nabízí a vytvořím strukturu xml, která vypadá následovně:
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<WCFSimpleChart month="9" year="2009">
<days>
<day no="1">
<operations>
<operation name="GetProducts">
<calls>0</calls>
</operation>
</operations>
</day>
<day no="2">
<operations>
<operation name="GetProducts">
<calls>0</calls>
</operation>
</operations>
</day>
</days>
</WCFSimpleChart>
V atributu je uveden měsíc a rok, dále pokračuje elementem days, kde jsou jednotlivé dny daného měsíce a každý den má element operations, kde jsou jednotlivé operace a počet jejich volání v tom konkrétním dni.
Návod na nasazení rozšíření naleznete již ve zminovaných článcích v úvodu tohoto článku.
Rozšíření mám tedy hotové, a ted jak vypadá moje WinForm aplikace, která bude data vizualizovat. Ukážu jen zde takový nástřel pár řádků a výsledný obrázek jak to vypadá, ale kdo by měl zájem to studovat více, tak ať se mi ozve a já mu to pošlu (Nechci to zde uvádět, protože jsem si s stím hrál jedno odpoledne a hodně věcí nefunguje)
string uri = "\9_2009.xml";
//DailyReport report = new DailyReport(uri, 3);
WeeklyReport report = new WeeklyReport(uri, new Week(DateTime.Parse("24.9.2009"), true));
System.Windows.Forms.DataVisualization.Charting.Chart chart1 = report.GenerateWinReport();
chart1.Dock = DockStyle.Fill;
this.Controls.Add(chart1);
V konstruktoru formuláře řeknu, že si chci vygenerovat týdenní report a předám mu uri na xml dokument a počáteční datum týdne (druhý parametr slouží pro rozpoznání jestli se má zobrazit celý týden – 7 dní, nebo jenom “pracovní” – tedy 5 dní). No a nakonec zavolám metodu GenerateWinReport, která vytvoří jednoduchý graf (viz. obrázek):
To je vše a myslím si, že kdyby se na tom zapracovalo tak by to mohla být docela zajímavá utilitka pro vizualizaci vytíženosti WCF služeb :-)
Lukáš