Blogger Widgets
  • Sharing Photos using SignalR
  • TFS Extenstion - allows copy work items between projects
  • Displaying jquery progressbar with ajax call on a modal dialog
  • Managing windows services of a server via a website
  • Exploring technologies available to date. TechCipher is one place that any professional would like to visit, either to get an overview or to have better understanding.

Search This Blog

Tuesday, 25 September 2012

Measuring performance using Fiddler API

Having used Fiddler as one of the most useful tool as a developer, would it not be easy to actually use Fiddler to measure up website performance, throughput etc. Well!! FiddlerCore API can be used to achieve this. Refer to FiddlerCode API for some samples.

Pretty cool. I have been using DevExpress ASP.NET controls for quite sometime now and I wanted to measure the performance and throughput for some of very interesting controls such as aspxcallbackpanel & aspxcallback.

All I want is a small windows app with a single form having a grid that show all of the interactions to and from the website I wanted to test. So here is how it looks when comparing performance against 30 secs max.

Steps 1. Initialize and associate all relevant events and flags for Fiddler API.
public Form1()
        {
            InitializeComponent();

            oAllSessions = new List();
            Fiddler.FiddlerApplication.OnNotification += delegate(object sender, NotificationEventArgs oNEA) { Console.WriteLine("** NotifyUser: " + oNEA.NotifyString); };
            Fiddler.FiddlerApplication.Log.OnLogString += delegate(object sender, LogEventArgs oLEA) { Console.WriteLine("** LogString: " + oLEA.LogString); };
            Fiddler.FiddlerApplication.BeforeRequest += delegate(Fiddler.Session oS)
            {
                oS.bBufferResponse = false;
                Monitor.Enter(oAllSessions);
                if (oS.fullUrl.StartsWith(sSecureEndpointHostname))
                {
                    oAllSessions.Add(oS);
                }
                Monitor.Exit(oAllSessions);
            };
            Fiddler.FiddlerApplication.AfterSessionComplete += delegate(Fiddler.Session oS)
            {
                if (bUpdateTitle)
                {
                    this.Text = ("Session list contains: " + oAllSessions.Count.ToString() + " sessions");
                }
            };
            Fiddler.CONFIG.IgnoreServerCertErrors = false;
            oFCSF = FiddlerCoreStartupFlags.Default;
        }
2. Now write code to handle start/stop monitoring of fiddler sessions
 private void btnStartStop_Click(object sender, EventArgs e)
        {
            test = new Random(120);
            if (btnStartStop.Text == "Start")
            {                
                Uri uri = new Uri(txtWebSite.Text);
                iSecureEndpointPort = uri.Port;                
                btnStartStop.Text = "Stop";
                tmrAnalyse.Enabled = true;
                tmrAnalyse.Interval = 5000;
                sSecureEndpointHostname = uri.AbsoluteUri;

                lstAnalysisData.Items.Clear();
                dgSessions.Rows.Clear();


                Fiddler.FiddlerApplication.Startup(8877, oFCSF);                
            }
            else
            {                
                Fiddler.FiddlerApplication.Shutdown();
                btnStartStop.Text = "Start";
                tmrAnalyse.Enabled = false;
            }
        }
3. code snippets for add/update session data onto grid
private void AddSession(Session oS, Dictionary whoData, int timeTaken)
        {
            DataGridViewRow row = new DataGridViewRow();
            dgSessions.Rows.Add(row);

            DataGridViewCell cell1 = new DataGridViewTextBoxCell();
            cell1.Value = oS.id;
            row.Cells["SessionID"] = cell1;

            DataGridViewCell cell2 = new DataGridViewTextBoxCell();
            cell2.Value = Ellipsize(oS.fullUrl, 60);
            row.Cells["URL"] = cell2;

            DataGridViewCell cell3 = new DataGridViewTextBoxCell();
            cell3.Value = oS.oRequest.headers.HTTPMethod;
            row.Cells["HttpMethod"] = cell3;

            DataGridViewCell cell4 = new DataGridViewTextBoxCell();
            cell4.Value = oS.responseCode;
            row.Cells["RresponseCode"] = cell4;

            DataGridViewCell cell5 = new DataGridViewTextBoxCell();
            cell5.Value = oS.oResponse.MIMEType;
            row.Cells["MIMEType"] = cell5;

            DataGridViewCell cell6 = new DataGridViewTextBoxCell();
            DataGridViewCell cell7 = new DataGridViewTextBoxCell();
            

            if (whoData.ContainsKey(NotFound))
            {
                cell6.Value = "Not found";
                cell7.Value = "Not found";                
            }
            else
            {
                cell6.Value = whoData[DataColumn1];
                cell7.Value = whoData[DataColumn2];
            }

            row.Cells["Data1"] = cell6;
            row.Cells["Data2"] = cell7;

            DataGridViewCell cell8 = new DataGridViewTextBoxCell();
            cell8.Value = timeTaken;
            row.Cells["Data3"] = cell8;

        }

        private int FindRow(Session oS)
        {
            int rowId = -1;
            for (int i = 0; i < dgSessions.Rows.Count; i++)
            {
                DataGridViewRow row = dgSessions.Rows[i];
                if (row.Cells[0].Value != null)
                {
                    if (row.Cells[0].Value.ToString() == oS.id.ToString())
                    {
                        rowId = i;
                        break;
                    }
                }
                else
                {
                    rowId = i;
                    break;
                }
            }
            return rowId;
        }

        private void UpdateSession(int rowId, Session oS, Dictionary whoData, int timeTaken)
        {
            DataGridViewRow row = dgSessions.Rows[rowId];
            row.Cells["SessionID"].Value = oS.id;
            row.Cells["URL"].Value = Ellipsize(oS.fullUrl, 60);
            row.Cells["HttpMethod"].Value = oS.oRequest.headers.HTTPMethod;
            row.Cells["RresponseCode"].Value = oS.responseCode;
            row.Cells["MIMEType"].Value = oS.oResponse.MIMEType;
            row.Cells["Data1"].Value = whoData[DataColumn1];
            row.Cells["Data2"].Value = whoData[DataColumn2];
            row.Cells["Data3"].Value = timeTaken;
        }
4. code snippet for updating grid every 5 secs
private void WriteSessionList()
        {
            try
            {
                Monitor.Enter(oAllSessions);
                foreach (Session oS in oAllSessions)
                {
                    WriteSession(oS);
                }
            }
            catch (Exception ex)
            {
                lstAnalysisData.Items.Add("Exception " + ex.Message);
            }
            finally
            {
                Monitor.Exit(oAllSessions);
            }
        }

        private void tmrAnalyse_Tick(object sender, EventArgs e)
        {           
            WriteSessionList();
        }
That's it all in place now. Some of the tiny bits were missed out in the intention highlight more important bits. Download FidderAPI.rar for more details. This is common code and can be used for any website or web applications. Mostly useful to verify throughput/speed for websites that utilises any of the following controls or JavaScript plugins :-
- asp:UpdatePanel (ASP.NET ajax control)
- $.ajax (JQuery ajax call to webservice/webpage)
- ActionResult (ASP.NET MVC action) etc.

Some people worry that artificial intelligence will make us feel inferior, but then, anybody in his right mind should have an inferiority complex every time he looks at a flower. ~Alan C. Kay

1 comments:

Copyright © 2013 Template Doctor . Designed by Malith Madushanka - Cool Blogger Tutorials | Code by CBT | Images by by HQ Wallpapers