Log4net And Action Filters

(ASP.NET MVC)


Log4net is very simple and open source logging framework that you can find it @ Log4Net page The log4net has logger and appender. 

Steps to integrate the log4net in asp.net mvc:

1. Install nuget package

 <package id="log4net" version="2.0.8" targetFramework="net461" />

2. Create new log4net section in configSections in web.config

<configSections>
     <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>

3. Define that section in web.config

 <configSections>
     <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>
  <log4net>
    <logger name="testingLogger">
      <level value="ALL" />
     <appender-ref ref="RollingFileAppender" />
    </logger>
     <logger name="testingErrorLogger">
      <level value="ALL" />
     <appender-ref ref="RollingErrorFileAppender" />
    </logger>
    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <file type="log4net.Util.PatternString" value="App_Data//.log" />
    <appendToFile value="true" />
    <rollingStyle value="Date" />
    <datePattern value="'testing_'yyyy-MM-dd" />
    <preserveLogFileNameExtension value="true" />
    <staticLogFileName value="false" />
    <layout type="log4net.Layout.PatternLayout">
        <!--<conversionPattern value="%date %level - [%ndc] - %message%newline%newline" />-->
    <conversionPattern value="%date %level - %message%newline" />
    </layout>
</appender>
  <appender name="RollingErrorFileAppender" type="log4net.Appender.RollingFileAppender">
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <file type="log4net.Util.PatternString" value="App_Data//.log" />
    <appendToFile value="true" />
    <rollingStyle value="Date" />
    <datePattern value="'testingerror_'yyyy-MM-dd" />
    <preserveLogFileNameExtension value="true" />
    <staticLogFileName value="false" />
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date %level - [%ndc] - %message%newline%newline" />   
    </layout>
</appender>
  </log4net>

As you see, The log4net section has two appenders and loggers that logs both error and log message. For more information about log4net configuration visit the  Log4Net.

4. Create the C# logger class

using log4net;
using System;
using System.Web;
namespace Common
{
    public static class Log
    {
        private static ILog infoLog = null;
        private static ILog errorLog = null;
        static Log()
        {
            infoLog = LogManager.GetLogger("testingLogger");
            errorLog = LogManager.GetLogger("testingErrorLogger");
        }
        public static void Info(string message)
        {
            try
            {
               HttpBrowserCapabilities browser= HttpContext.Current.Request.Browser;
                string userAgent = HttpContext.Current.Request.UserAgent;
                if (string.Compare(browser.Platform,"Unknown",StringComparison.OrdinalIgnoreCase) !=0)
                {
                    //using (NDC.Push(string.Format("Browser: {0}, Platform: {1}, Version: {2}, IP Address: {3}", browser.Type,
                    //browser.Platform, browser.Version,HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"].ToString())))
                    //{
                        infoLog.Info(message);
                    //}
                }
                else if(userAgent.Contains("Mobile"))
                {
                    //using (NDC.Push(string.Format("Browser: {0}, Platform: {1}, Version: {2}, IP Address: {3}, userAgent: {4}", browser.Type,
                    //browser.Platform, browser.Version, HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"].ToString(), userAgent.ToString())))
                    //{
                        infoLog.Info(message);
                    //}
                }
            }
            catch (Exception exc) {
                Error(exc, "Info", "Log");
            }
        }
        public static void Error(Exception excMessage, string action = null, string controller = null)
        {
            try
            {
                    string platform = HttpContext.Current.Request.Browser.Platform;
                    using (NDC.Push(string.Format("Browser: {0}, Platform: {1}, Version: {2}", HttpContext.Current.Request.UserAgent,
                       platform, HttpContext.Current.Request.Browser.Version)))
                    {
                        errorLog.Info(string.Format(@"Error has been occurred at {0} ACTION IN {1} CONTROLLER", action, controller));
                        errorLog.Error(excMessage.Message);
                        if(excMessage.StackTrace != null)
                    {
                        errorLog.Error(excMessage.StackTrace);
                    }
                    }
            }
            catch (Exception exc) {
                if (exc.StackTrace != null)
                {
                    infoLog.Info(string.Format(@"Error occurred at Error method in
                        Log.cs: {0} \n {1} ", exc.Message.ToString(), exc.StackTrace));
                }
                else
                {
                    infoLog.Info(string.Format(@"Error occurred at Error method in
                        Log.cs: {0}", exc.Message.ToString()));
                }
            }
        }
    }
}
5. Create the asp.net mvc custom action filter for logging
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Web.Mvc;
namespace Common
{
    public class LoggingFilterAttribute:ActionFilterAttribute
    {
        public string UserName { get; set; }
        public bool canLogParameters { get; set; }
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            try
            {
                string action = filterContext.ActionDescriptor.ActionName;
                string controller = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
                if (canLogParameters)
                {
                    IDictionary<string, object> parameters = filterContext.ActionParameters;
                    string paramsList = string.Empty;
                    foreach (KeyValuePair<string, object> p in parameters)
                    {
                        paramsList += string.Format("{0}:{1}", p.Key, JsonConvert.SerializeObject(p.Value)) + ", ";
                    }
                    Log.Info(string.Format(@"***{0}:{1}***", controller, action));
                    Log.Info(paramsList.Remove(paramsList.LastIndexOf(","), 1).Trim());
                }
                else
                {
                    Log.Info(string.Format(@"***{0}:{1}***", controller, action));
                }
               
            }
            catch(Exception exc)
            {
                Log.Error(exc, "OnActionExecuting", "LoggingFilterAttribute");
            }
            base.OnActionExecuting(filterContext);
        }
    }
}
6. Apply the  action filter either in  action method or controller class
        [Route("Get/{employee}/{id:int}")]
        [LoggingFilter(canLogParameters = true)]
        public ActionResult GetEmployee(string articleName, int id)
        {
            return View();
        }
  
        [HttpPost]
        [ValidateAntiForgeryToken]
        [LoggingFilter]
        public ActionResult AddEmployee(EmployeeViewModel emp)
        {
            bool result = EmpLogic.AddEmployee(emp);
            return RedirectToAction("ListEmployee", new { EmpID = emp.EmpID });
        }
      [LoggingFilter]
      public class DepartmentController : Controller
    {
     ......
     ......
   }

The logging filter has the optional parameter "canLogParameters", If you want to log the parameters of action method, you can set it to true.


Ratings


Average Rating: 0.00 by 0 users

11/4/2018
11/4/2018
Download PDF

Comments