Search code examples
c#.netloggingasp.net-web-api

.NET Web API - Add Logging


I'm looking for some help on the best way to handle API Logging. I'd like to log all requests and responses to either SQL or to a textfile if that's the best way. Currently I've been inserting a row into a logs table in SQL Server. I do that with a static method called LogAction, and I run it near the end of every Controller in my Web API. I also log exceptions that are caught as well. Is there a way to do this with an MVC Web API natively, or am I on the right track?

Currently it looks just like this:

// Log API Call
System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(request.GetType());
StringWriter s = new StringWriter();
x.Serialize(s, request);
Utilities.LogAction(Utilities.LogType.MAIN, false, response.ToString(), s.ToString(), "MainController: Successful");

Is there a way to get it to log all API actions natively? This feels wrong to me because if something happened between this static method and actually returning the response, then this log is no longer valid. What is the most effective way to log API actions?


Solution

  • For logging calls to API actions, I have used a custom Attribute like this:

    public class LogApiRequestAttribute : System.Web.Http.Filters.ActionFilterAttribute
    {
        /// <summary>
        /// For Web API controllers
        /// </summary>
        /// <param name="actionExecutedContext"></param>
        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            base.OnActionExecuted(actionExecutedContext);
    
            var request = actionExecutedContext.Request;
            var response = actionExecutedContext.Response;
            var actionContext = actionExecutedContext.ActionContext;
    
            // Log API Call
            ...
        }
    }
    

    You may need to check around actionExecutedContext to see if it has the Request and Response information you want. You may want to override the OnActionExecuting method instead or also.

    Then decorate your Web API Controller with the attribute:

    [LogApiRequest]
    public void Post(SomeThingInputModel thing)
    {
        // Controller code
        ...
    }