Asp.Net MVC How to log all actions being called

You could create your own class which inherits from ActionFilterAttribute and then override the OnActionExecuting method.

Example

public class LogActionAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {

        var controller = filterContext.RequestContext.RouteData.Values["Controller"];
        var action = filterContext.RequestContext.RouteData.Values["Action"];

        //
        // Perform logging here
        //

        base.OnActionExecuting(filterContext);
    }
}

public class HomeController : Controller
{
    [LogAction]
    public ActionResult Index()
    {

        return View();
    }

}

Hope this helps!


You could try Audit.NET library with its Audit.MVC and the different data providers to store the logs on files, eventlog, sql, redis, mongo, and much more.

With the MVC extension you just need to decorate your controllers or actions with an attribute:

[Audit]
public class HomeController : Controller
{ ... }

Execute a static configuration to set the output of your logs:

Audit.Core.Configuration.Setup()
    .UseFileLogProvider(_ => _
        .Directory(@"C:\Logs"));

And it will provide the infrastructure to log the interactions with your MVC application.


Credit HeyMega for their answer. Here's an example of an expanded implementation I arrived at in MVC5.

public class LogActionAttribute : ActionFilterAttribute
{

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var controller = filterContext.RequestContext.RouteData.Values.ContainsKey("Controller") ? filterContext.RequestContext.RouteData.Values["Controller"].ToString() : null;
        var action = filterContext.RequestContext.RouteData.Values.ContainsKey("Action") ? filterContext.RequestContext.RouteData.Values["Action"].ToString() : null;
        var area = filterContext.RequestContext.RouteData.DataTokens.ContainsKey("Area") ? filterContext.RequestContext.RouteData.DataTokens["Area"].ToString() : null;
        var user = filterContext.RequestContext.HttpContext.User.Identity.GetUserId();

        Task.Run(() => Generic().AreaActionLog(user, area, controller, action));

        base.OnActionExecuting(filterContext);
    }
}

I chose to separate the method doing the actual logging into a separate process, if anything goes wrong with the Database interaction, or the DB interaction takes several seconds, the UI is uninterrupted.

You can then decorate the entire controller with [LogAction] attribute like so.

[LogAction]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Contact()
    {
        return View();
    }
}

Or selectively apply the attribute by decorating individual methods:

public class HomeController : Controller
{
    [LogAction]
    public ActionResult Index_Logs_Things()
    {
        return View();
    }
}

Hope this helps someone.