Tuesday 21 June 2011

WCF Framework 4.0 - Monitoring Service Performance by using Performance Counters

Let's say you created WCF service, decided host it in IIS and want monitor service performance. One of the options,which you can use without apply extra work is to use built-in framework functionality. I will be focused on Microsoft Framework 4.0 in this article. There is bunch of performance counters to monitor service calls but in this sample I will use number of "calls" and "calls duration" only.

Create project

I created simple WCF service project, which contains CustomerService.svc and OrderManagement.svc services, which can be used in E-Commerce solution.

CustomerService.svc service contains following operations:
GetCustomerProfile - suppose to return customer profile from back-end systems
CustomerExists - check if such customer exists

OrderManagementService.svc service contains just one operation:
GetOrders  - returns list of customer orders from back-end system

I will not be focused on implementation of these services. I created it just for sample purpose. I made random response delay in every service call. In GetCustomerProfile operation I set max response time to 2 seconds and in GetOrders operation I set max response time to 5 seconds.

I also created client, which is console application and makes all calls via data access layer. Console application is configurable and allows enter number of calls to WCF services.

here is sample of 2 seconds delay:

 int ms = new System.Random().Next(2000);
 System.Threading.Thread.Sleep(ms);

Here is my solution structure in VS:



Work with WCF performance counters

You have 3 options to monitor WCF calls in this project:
  • Service level
  • Endpoint level
  • Operation Level
you will find more details in this MSDN article:
http://msdn.microsoft.com/en-us/library/ms735098.aspx

Here are detailed steps for current project:

1) Enable WCF performance counters

I want to be able monitor calls on operation level, such as GetCustomerProfile. In this case I have to turn on monitoring in WCF service project by adding following entry in web.config in <system.serviceModel>:
  here it is
    <diagnostics performanceCounters="All">
    </diagnostics>
2) run perfmon tool, which is part of operation system from the run command or by running it via "Control Panel->Administrative Tools->Performance Monitor"

3) Add performance counter


You have 2 options here. If you want see real-time performance counter value you should select "Performance Monitor". If you want create baseline and keep history of performance counter values in time, you should select "Data Collector Sets->User Defined".
In most cases I prefer second option - once you added performance counters to data set collector set, you don't loose it anymore. You can even export data collection sets from one environment to another.
In this sample I will use first option  - "Performance Monitor".


4) Select Perfomance counters at service level

I want monitor total calls to CustomerProfileService.svc service - it will be sum of calls to GetCustomerProfile and CustomerExists operations. In this case I have to select "ServiceModelService 4.0.0.0". 4.0.0.0 is because I use Framework 4.0. But when you select it you will probably see no performance counters like shown below:



The solution is to register performance counters for your service. You can do it by making 1st call to your service or by running "WCF Test Client" right from Visual Studio (it is what I want to do).
4a) Select your WCF Service project as startup project and select CustomerProfileService.svc as startup file.


Press F5 (run in debug mode) you should see following screen:


Close WCF test client if you see screen above and go to the next step. If you have any exceptions, check this article -  It can help you:
Microsoft Framework 4.0 WCF Service and IIS 7.5 Application Pool permissions


4b) Open performance monitor tool. Repeat steps to add performance counter at service level. You should see now that performance couter for CustomerProfileService has been registered:


The pattern for the service name will be
ServiceName@ServiceBaseAddress

Select "Calls" and "Calls Duration" and click "Add" and click "OK" buttons.

If you want see performance counters for the "OrderManagementService.svc" repeat step 4a) but do it for OrderManagementService.svc.

5) Select performance counters at operation level
To understand what is the bottleneck of the created service you should monitor service activity at operation level. For example, if I want check response time for the GetCustomerProfile I have to use "ServiceModelOperation 4.0.0.0" performance counters category and select operation by following pattern:
(ServiceName).(ContractName).(OperationName)@(first endpoint listener address)



6) Monitor Performance counters
6a) I run test console application to hit wcf services:
I entered 100000 total hits to both svc services.

I am not listing source code for the console application, because I am focusing on performance monitor now.

6b) Switch to Performance Monitor Tool
You should see similar picture as me (shown below). You can select and deselect performance counters from graph by clicking on checkboxes. The most important function here is scale. It allows scale counter values in graph. You should select performance counter my right mouse click and select "Scale Selected Counters" in popup menu.


Values of the performance counters will be changed in time, so from time to time you will have to run scale to adjust graph.
To check number of calls at service level you should select Instance by pattern, which I describe in section 4b.



To check call duration for "GetCustomerProfile" you should select Instance by pattern as I described in section 5. Value for the duration is set in milliseconds. As you can see above, last call duration was 1.2 seconds:




6) Select performance counters at endpoint level
I mentioned at the beginning that will be focused at "calls" and "call duration" performance counters only. Endpoint performance counters enable you to look at data reflecting how an endpoint is accepting messages. They can be found under the ServiceModelEndpoint 4.0.0.0 performance object when viewing using the Performance Monitor. The instances are named using the following pattern:

(ServiceName).(ContractName)@(endpoint listener address)

Following picture shows message oriented performance counters and instance name for my CustomerProfileService:


Have good luck with finding bottlenecks in your services.

My computer Configuration:
CPU: Intel i5
Memory: 6Gb
OS: Windows 7 32 bit
Development Tool: Visual Studio 2010 Ultimate
IIS version: 7.5

4 comments:

  1. Thank You for the detailed article, It helped me.

    ReplyDelete
  2. Instead of using performance counters I would highly recommend using an application performance management tool like Stackify to help you find and fix application problems

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. When I click "ServiceModelOperation 4.0.0.0," it shows "<No Instances>."

    ServiceModelService 4.0.0.0 shows the service, but I can't see any of the operations in Performance Monitor.

    I have added <diagnostics performanceCounters="All"> underneath the <system.serviceModel> node of my XML .config file, so that's not the problem. (If I change it to "Off," then I see nothing under ServiceModelService 4.0.0.0, so I know that the .config file is being processed.)

    Any idea what's going on?

    ReplyDelete