Eminem
Eminem

Reputation: 7484

Asp.Net MVC How to log all actions being called

I need to be able to log all actions that are called from my asp.net mvc application. How and what would be the best way to achieve this? Where I log it to whether it be the console or log file doesn't matter.

Upvotes: 15

Views: 19512

Answers (3)

Richard
Richard

Reputation: 391

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.

Upvotes: 7

heymega
heymega

Reputation: 9411

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!

Upvotes: 29

thepirat000
thepirat000

Reputation: 13124

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.

Upvotes: 4

Related Questions