2

I just herited of a very bad Web API code in C#. I need to improve it but I don't know where to start. There are plenty of classes and the code is a nightmare. I also think part of code is never used.

I would like to count the number of time each request is called and what time each request last. I would like to log all my result in a table. In one or two days I could have a clear view of what I the most used and what take time. Client are complaining about that.

I use Nlog for log and a simple Stopwatch to calculation of performance. What do you suggest? I know it's better to use Filter and attribute for traces but how can I log and trace performance like this?

// GET api/Item/5
public Item GetItem(string id)
{
    // I don't use string.Format in my real code. This is just for this example.
    logger.Trace(string.Format("Request: GET api/Item/{0}", id));
    Stopwatch sw = new Stopwatch();
    sw.Start();

    Item item = context.Items.Single(i => i.Code == id);

    sw.Stop();
    logger.Trace(string.Format("Response: GET api/values/{0}\r\nElpased={1}\r\rn{2}", id, sw.Elapsed, response));

I found previous information here

Thanks to

http://weblogs.asp.net/fredriknormen/log-message-request-and-response-in-asp-net-webapi

Exact time measurement for performance testing

Of course all these Trace and performance jobs will be activated or deactivated from my config file. For NLog it's built in. For the Stopwatch I plan to build something. I don't plan to keep this alive all the time on production

Community
  • 1
  • 1
Bastien Vandamme
  • 17,659
  • 30
  • 118
  • 200
  • Resharper won't help here. Resharper cannot detect unused request on runtime. – Bastien Vandamme Jun 27 '16 at 07:19
  • Attribute base logging Check this http://stackoverflow.com/questions/13655541/wcf-service-attribute-to-log-method-calls-and-exceptions – LifeOfPi Jun 27 '16 at 07:25
  • Ok, Read my question Offir Pe'er. It's about writing code, not using a tool. – Bastien Vandamme Jun 27 '16 at 07:33
  • As controllers are created per request you could create a master controller which starts the logging in it's constructor and finish it in a deconstructor. Then you dont have to add loggin code in each method and still get a view on the overhaul performance. – Marcus Höglund Jun 27 '16 at 07:35
  • @Prathyush This where I'm lost. Each article I read suggest different approach. Use ActionFilter, now use IOperationInvoker, use DelegatingHandler,... Seriously I still prefer writing my log manually at the beginning and end of each of my methods. – Bastien Vandamme Jun 27 '16 at 07:36
  • @B413, depends upon comfort and understand of the any approach you can decide which approach is correct in given time frame. As in past I had also faced the same scenario and at last ending manual logging what you have mentioned. Before reaching star lets reach moon first ;) – LifeOfPi Jun 27 '16 at 08:12

3 Answers3

4

You can use DelegatingHandler.

A base type for HTTP handlers that delegate the processing of HTTP response messages to another handler, called the inner handler.

enter image description here

Injecting in pipeline allows to capture place before and after request processing in your controller.

public class MonitoringDelegate : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
    var watcher = Stopwatch.StartNew();
    var response = await base.SendAsync(request, cancellationToken);
    watcher.Stop();

    //log/store duration using watcher.ElapsedMilliseconds

    return response;
    }
}
Set
  • 47,577
  • 22
  • 132
  • 150
0

Just adding to @set answer, you should register the delegate.

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.MessageHandlers.Add(new MonitoringDelegate ());

        
    }
}
Hasan Shouman
  • 2,162
  • 1
  • 20
  • 26
-3

Have a look at profilers. This more general approach. We use Ants performance profiler.