Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to trace each request ASP.NET Web API with NLog

I created a simple REST API with ASP.NET Web API. For testing purpose I would like to add some tracing. So I added NLog to my project. At this moment my logging is like this:

// POST api/values
public void Post([FromBody]string value)
{
    logger.Trace("Request: {0} api/values", Request.Method); 
    _repository.insert(value);
    logger.Trace("Response: {0} api/values", Request.Method); 
}

In every method I added a logger.Trace at the top then bottom of my methods. I have 2 issue with this method:

  1. I nee to remember to add these line to each of my methods
  2. I don't know how to add the JSON body to my trace

Point 1 is not a real issue for now (see bellow) but I quickly need something to check every JSON body my API receive.

I already tried this

// POST api/values
public void Post([FromBody]string value)
{
    logger.Trace("Request: {0} api/values {1}", Request.Method, Request.Body); 
    _repository.insert(value);
    logger.Trace("Response: {0} api/values", Request.Method); 
}

But there is no Body property on Request.

I also found an interesting documentation for my point 1:http://weblogs.asp.net/fredriknormen/log-message-request-and-response-in-asp-net-webapi

like image 209
Bastien Vandamme Avatar asked Aug 19 '16 06:08

Bastien Vandamme


2 Answers

That's what you have action filters for...to do something before/after an action method is a executing/executed

public class MyCustomFilter : System.Web.Http.Filters.ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        //Do something here before an action method starts executing
    }

    public override void OnActionExecuted(System.Web.Http.Filters.HttpActionExecutedContext context)
    {
        //Do something here after an action method finished executing
    }
}

Then, you'll need to plug this filter in the asp.net pipeline...when the application starts, whether you use owin/katana or global.asax it doesn't matter...

GlobalConfiguration.Configuration.Filters.Add(new MyCustomFilter());

The line above will add that filter to all action methods. If you want to turn tracing off for some action methods, simply add a flag/switch property to the action filter so that you can switch tracing off for some actions...

public class MyCustomFilter : System.Web.Http.Filters.ActionFilterAttribute
{
    public bool DisableTracing{get;set;}

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if(!DisableTracing){
               //Do something here before an action method starts executing
        }
    }

    public override void OnActionExecuted(System.Web.Http.Filters.HttpActionExecutedContext context)
    {
        if(!DisableTracing){
               //Do something here before an action method starts executing
        }
    }
}

And now you can turn it of on controller action...

[MyCustomFilter(DisableTracing = true)]
public IHttpActionResult MyAction(int id){}

Update

To read the JSON object from the request's body simply read the content of the request as below...

 request.Content.ReadAsStringAsync().Result;
like image 57
Leo Avatar answered Oct 21 '22 01:10

Leo


The solution of Leo seems correct for MVC but for Http REST API I had to implement the solution from http://www.c-sharpcorner.com/UploadFile/1492b1/restful-day-sharp6-request-logging-and-exception-handingloggin/

public class HttpLoggingFilterAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
    public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext filterContext)
    {
        //Do something here
    }

    public override void OnActionExecuted(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext)
    {
        //Do something here
    }
}

After testing both method on my code I can tell the code from Leo is performed on an page refresh bit not on simple REST request.

like image 41
Bastien Vandamme Avatar answered Oct 21 '22 01:10

Bastien Vandamme