• ASP.NET MVC4中加入Log4Net日志记录功能


    前言

    在之前的.NET中,微软还没有提供过像样的日志框架,目前能用的一些框架比如Log4Net、NLog、CommonLogging等,虽然多多少少使用起来有点费劲,但这里还是简单分享一下Log4Net的初步使用方法。

    在项目中的配置

    第一步:首先在项目用引用Log4Net.dll.[管理NuGet程序包中直接搜索就可以啦]

    第二步:Web.config文件中进行添加confIGsections的节点

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

    第三步:在configSections下添加Log4Net配置节点[这里将日志分类了,以便于理解与查看对应的日志信息]

    复制代码
    <log4net>
        <!--错误日志-->
        <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
          <file value="log\LogError\" />
          <appendToFile value="true" />
          <rollingStyle value="Date" />
          <datePattern value="yyyy\yyyyMM\yyyyMMdd'.txt'" />
          <staticLogFileName value="false" />
          <param name="MaxSizeRollBackups" value="100" />
          <layout type="log4net.Layout.PatternLayout">
            <!--每条日志末尾的文字说明-->
            <!--输出格式-->
            <!--样例:2008-03-26 13:42:32,111 [10] INFO  Log4NetDemo.MainClass [(null)] - info-->
            <conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别:  %-5level %n错误描述:%message%newline %n" />
          </layout>
        </appender>
    
        <!--Info日志-->
        <appender name="InfoAppender" type="log4net.Appender.RollingFileAppender">
          <param name="File" value="Log\LogInfo\" />
          <param name="AppendToFile" value="true" />
          <param name="MaxFileSize" value="10240" />
          <param name="MaxSizeRollBackups" value="100" />
          <param name="StaticLogFileName" value="false" />
          <param name="DatePattern" value="yyyy\yyyyMM\yyyyMMdd'.txt'" />
          <param name="RollingStyle" value="Date" />
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别:  %-5level %n日志描述:%message%newline %n" />
          </layout>
        </appender>
    
        <!--监控日志-->
        <appender name="MonitorAppender" type="log4net.Appender.RollingFileAppender">
          <param name="File" value="Log\LogMonitor\" />
          <param name="AppendToFile" value="true" />
          <param name="MaxFileSize" value="10240" />
          <param name="MaxSizeRollBackups" value="100" />
          <param name="StaticLogFileName" value="false" />
          <param name="DatePattern" value="yyyy\yyyyMM\yyyyMMdd'.txt'" />
          <param name="RollingStyle" value="Date" />
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别:  %-5level %n跟踪描述:%message%newline %n" />
          </layout>
        </appender>
    
        <!--Error日志-->
        <logger name="LogError">
          <level value="ERROR" />
          <appender-ref ref="RollingLogFileAppender" />
        </logger>
    
        <!--Info日志-->
        <logger name="LogInfo">
          <level value="INFO" />
          <appender-ref ref="InfoAppender" />
        </logger>
    
        <!--监控日志-->
        <logger name="LogMonitor">
          <level value="Monitor" />
          <appender-ref ref="MonitorAppender" />
        </logger>
      </log4net>
    复制代码
    View Code

      在框架的体系里,所有的日志对象都是根日志(root logger)的后代。 因此如果一个日志对象没有在配置文件里显式定义,则框架使用根日志中定义的属性。在<root>标签里,可以定义level级别值和Appender的列表。如果没有定义LEVEL的值,则缺省为DEBUG。可以通过<appender-ref>标签定义日志对象使用的Appender对象。<appender-ref>声明了在其他地方定义的Appender对象的一个引用。在一个logger对象中的设置会覆盖根日志的设置。而对Appender属性来说,子日志对象则会继承父日志对象的Appender列表。这种缺省的行为方式也可以通过显式地设定<logger>标签的additivity属性为false而改变。

    在项目中建立自定义Log日志

    第四步:在文件里配置以下类:ApiTrackerFilter.cs[Api接口日志],TrackerFilter.cs[基本日志类],LoggerHelper.cs[日志信息处理类],MonitorLog.cs[监控日志类](对于监控日志,则根据个人需求是否建立),其中的BookException是自定义的错误,可以省略。

    复制代码
    public class LoggerHelper
        {
            private static readonly log4net.ILog LogInfo = log4net.LogManager.GetLogger("LogInfo");
            private static readonly log4net.ILog LogError = log4net.LogManager.GetLogger("LogError");
            private static readonly log4net.ILog LogMonitor = log4net.LogManager.GetLogger("LogMonitor");
    
            /// <summary>
            /// 记录Error日志
            /// </summary>
            /// <param name="errorMsg"></param>
            /// <param name="ex"></param>
            public static void Error(string errorMsg, Exception ex = null)
            {
                if (ex != null)
                {
                    LogError.Error(errorMsg, ex);
                }
                else
                {
                    LogError.Error(errorMsg);
                }
            }
    
            /// <summary>
            /// 记录Info日志
            /// </summary>
            /// <param name="msg"></param>
            /// <param name="ex"></param>
            public static void Info(string msg, Exception ex = null)
            {
                if (ex != null)
                {
                    LogInfo.Info(msg, ex);
                }
                else
                {
                    LogInfo.Info(msg);
                }
            }
    
            /// <summary>
            /// 记录Monitor日志
            /// </summary>
            /// <param name="msg"></param>
            public static void Monitor(string msg)
            {
                LogMonitor.Info(msg);
            }
        }
    复制代码
    LoggerHelper.cs
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
        public class TrackerFilter : ActionFilterAttribute, IExceptionFilter
        {
            private readonly string key = "_thisOnActionMonitorLog_";
    
            #region Action时间监控
            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                MonitorLog monLog = new MonitorLog();
                monLog.ExecuteStartTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.ffff", DateTimeFormatInfo.InvariantInfo));
                monLog.ControllerName = filterContext.RouteData.Values["controller"] as string;
                monLog.ActionName = filterContext.RouteData.Values["action"] as string;
                filterContext.Controller.ViewData[this.key] = monLog;
            }
    
            public override void OnActionExecuted(ActionExecutedContext filterContext)
            {
                MonitorLog monLog = filterContext.Controller.ViewData[this.key] as MonitorLog;
                monLog.ExecuteEndTime = DateTime.Now;
                monLog.FormCollections = filterContext.HttpContext.Request.Form;//form表单提交的数据
                monLog.QueryCollections = filterContext.HttpContext.Request.QueryString;//Url 参数
                LoggerHelper.Monitor(monLog.GetLogInfo());
            }
            #endregion
    
            #region View 视图生成时间监控
            public override void OnResultExecuting(ResultExecutingContext filterContext)
            {
                MonitorLog monLog = filterContext.Controller.ViewData[this.key] as MonitorLog;
                monLog.ExecuteStartTime = DateTime.Now;
            }
    
            public override void OnResultExecuted(ResultExecutedContext filterContext)
            {
                MonitorLog monLog = filterContext.Controller.ViewData[this.key] as MonitorLog;
                monLog.ExecuteEndTime = DateTime.Now;
                LoggerHelper.Monitor(monLog.GetLogInfo(MonitorLog.MonitorType.View));
                filterContext.Controller.ViewData.Remove(this.key);
            }
            #endregion
    
            #region 错误日志
            public void OnException(ExceptionContext filterContext)
            {
                if (!filterContext.ExceptionHandled)
                {
                    string controllerName = string.Format("{0}Controller", filterContext.RouteData.Values["controller"] as string);
                    string actionName = filterContext.RouteData.Values["action"] as string;
                    string errorMsg = string.Format("在执行 controller[{0}] 的 action[{1}] 时产生异常", controllerName, actionName);
                    LoggerHelper.Error(errorMsg, filterContext.Exception);
                }
            }
            #endregion
        }
    TrackerFilter.cs
        /// <summary>
        /// 监控日志对象
        /// </summary>
        public class MonitorLog
        {
            public MonitorLog()
            {
                this.Watch = new Stopwatch();
                this.Watch.Start();
            }
    
            /// <summary>
            /// 监控类型
            /// </summary>
            public enum MonitorType
            {
                /// <summary>
                /// Action
                /// </summary>
                Action = 1,
    
                /// <summary>
                /// 视图
                /// </summary>
                View = 2
            }
    
            public string ControllerName { get; set; }
    
            public string ActionName { get; set; }
    
            public Stopwatch Watch { get; set; }
    
            public DateTime ExecuteStartTime { get; set; }
    
            public DateTime ExecuteEndTime { get; set; }
    
            /// <summary>
            /// Form 表单数据
            /// </summary>
            public NameValueCollection FormCollections { get; set; }
    
            /// <summary>
            /// URL 参数
            /// </summary>
            public NameValueCollection QueryCollections { get; set; }
    
            /// <summary>
            /// 文本流
            /// </summary>
            public string Raw { get; set; }
    
            /// <summary>
            /// 获取监控指标日志
            /// </summary>
            /// <param name="mtype"></param>
            /// <returns></returns>
            public string GetLogInfo(MonitorType mtype = MonitorType.Action)
            {
                this.Watch.Stop();
                string actionView = "Action执行时间监控:";
                string action = "Action";
                if (mtype == MonitorType.View)
                {
                    actionView = "View视图生成时间监控:";
                    action = "View";
                }
                string msgContent = string.Format(
                    @"
          {0}
          ControllerName:{1}Controller
          {2}Name:{3}
          开始时间:{4}
          结束时间:{5}
          总 时 间:{6}秒",
                    actionView,
                    this.ControllerName,
                    action,
                    this.ActionName,
                    this.ExecuteStartTime,
                    this.ExecuteEndTime,
                    this.Watch.ElapsedMilliseconds);
    
                if (!string.IsNullOrEmpty(this.Raw))
                {
                    msgContent += @"
            Raw:" + this.Raw;
                }
                else if (this.FormCollections != null)
                {
                    msgContent += @"
            Form:" + this.GetCollections(this.FormCollections);
                }
                else if (this.QueryCollections != null)
                {
                    msgContent += @"
            Query:" + this.GetCollections(this.QueryCollections);
                }
    
                return msgContent;
            }
    
            /// <summary>
            /// 获取Post 或Get 参数
            /// </summary>
            /// <param name="collections"></param>
            /// <returns></returns>
            public string GetCollections(NameValueCollection collections)
            {
                string parameters = string.Empty;
                if (collections == null || collections.Count == 0)
                {
                    return parameters;
                }
                parameters = collections.Keys.Cast<string>()
                    .Aggregate(parameters, (current, key) => current + string.Format("{0}={1}&", key, collections[key]));
                if (!string.IsNullOrWhiteSpace(parameters) && parameters.EndsWith("&"))
                {
                    parameters = parameters.Substring(0, parameters.Length - 1);
                }
                return parameters;
            }
    MonitorLog.cs
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
        public class ApiTrackerFilter : ActionFilterAttribute
        {
            private readonly string key = "_thisOnApiActionMonitorLog_";
    
            public override void OnActionExecuting(HttpActionContext actionContext)
            {
                var monLog = new MonitorLog();
                monLog.ExecuteStartTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.ffff", DateTimeFormatInfo.InvariantInfo));
    
                monLog.ControllerName = actionContext.ActionDescriptor.ControllerDescriptor.ControllerName;
                monLog.ActionName = actionContext.ActionDescriptor.ActionName;
                actionContext.Request.Properties[this.key] = monLog;
            }
    
            public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
            {
                if (actionExecutedContext.Exception != null)
                {
                    string controllerName = string.Format(
                        "{0}Controller",
                        actionExecutedContext.ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName);
                    string actionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName;
                    string errorMsg = string.Format("在执行 controller[{0}] 的 action[{1}] 时产生异常", controllerName, actionName);
                    if (actionExecutedContext.Exception is BookException)
                    {
                        LoggerHelper.Info(errorMsg, actionExecutedContext.Exception);
                    }
                    else
                    {
                        LoggerHelper.Error(errorMsg, actionExecutedContext.Exception);
                    }
                }
    
                if (!actionExecutedContext.Request.Properties.ContainsKey(this.key))
                {
                    return;
                }
    
                var monLog = actionExecutedContext.Request.Properties[this.key] as MonitorLog;
                if (monLog != null)
                {
                    monLog.ExecuteEndTime = DateTime.Now;
    
                    monLog.Raw = actionExecutedContext.Request.Content.ReadAsStringAsync().Result;
                    LoggerHelper.Monitor(monLog.GetLogInfo());
                }
            }
        }
    ApiTrackerFilter.cs

    在Global.asax文件中配置以及在MVC的FilterConfig过滤器中配置信息

    经过这么多的准备工作,终于最后一步:

    1.Global.axax中配置

    复制代码
    protected void Application_Start(object sender, EventArgs e)
            {
    
                AreaRegistration.RegisterAllAreas();
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                log4net.Config.XmlConfigurator.Configure();
    
                GlobalConfiguration.Configuration.Filters.Add(new Log.ApiTrackerFilter());
                BundleConfig.RegisterBundles(BundleTable.Bundles);
            }
    复制代码

    2.在FilterConfig过滤器中配置信息

    复制代码
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
            {
                //监控日志
                filters.Add(new Log.TrackerFilter());
    
                filters.Add(new HandleErrorAttribute());
            }
    复制代码

    至此,所有都成功了,最后运行的结果可以在项目根目录下查看相应日期的Log日志信息。

  • 相关阅读:
    gridview 鼠标经过变色函数
    两种添加数据到WEB DropDownList 控件的方法
    gridview 鼠标经过变色函数
    两种添加数据到WEB DropDownList 控件的方法
    gridview 鼠标经过变色函数
    gridview 鼠标经过变色函数
    gridview 数据绑定函数
    两种添加数据到WEB DropDownList 控件的方法
    gridview 鼠标经过变色函数
    我们的软件出了什么问题《敏捷软件开发:原则、模式与实践》(一)
  • 原文地址:https://www.cnblogs.com/shiyh/p/8919650.html
Copyright © 2020-2023  润新知