• log4net 记录MVC监控日志


    原文:http://www.cnblogs.com/lc-chenlong/p/4228639.html

    由于MVC自身的特点,可以让我们记录每一个Controller下Action的执行时间以及View视图渲染完成的时间,本文采用log4net记录MVC每个Action的执行时间和View视图渲染完成时间,以及请求Action时post或get的数据。这样通过日志记录的时间方便我们定位哪一个Action和View执行的时间过长,进而采取优化的手段。

    监控日志监控的指标如下图

    监控程序实现

      改监控程序主要继承ActionFilterAttribute类,并重写其中的OnActionExecuted、OnActionExecuting、OnResultExecuted、OnResultExecuting几个方法实现。

    1、监控日志对象
    复制代码
    /// <summary>
        /// 监控日志对象
        /// </summary>
        public class MonitorLog
        {
            public string ControllerName
            {
                get;
                set;
            }
            public string ActionName
            {
                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 enum MonitorType
            {
                Action = 1,
                View = 2
            }
            /// <summary>
            /// 获取监控指标日志
            /// </summary>
            /// <param name="mtype"></param>
            /// <returns></returns>
            public string GetLoginfo(MonitorType mtype = MonitorType.Action)
            {
                string ActionView = "Action执行时间监控:";
                string Name = "Action";
                if (mtype == MonitorType.View)
                {
                    ActionView = "View视图生成时间监控:";
                    Name = "View";
                }
                string Msg = @"
                {0}
                ControllerName:{1}Controller
                {8}Name:{2}
                开始时间:{3}
                结束时间:{4}
                总 时 间:{5}秒
                Form表单数据:{6}
                URL参数:{7}
                        ";
                return string.Format(Msg,
                    ActionView,
                    ControllerName, 
                    ActionName,
                    ExecuteStartTime,
                    ExecuteEndTime, 
                    (ExecuteEndTime - ExecuteStartTime).TotalSeconds,
                    GetCollections(FormCollections),
                    GetCollections(QueryCollections),
                    Name);
            }
    
            /// <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;
                }
                foreach (string key in Collections.Keys)
                {
                    Parameters += string.Format("{0}={1}&", key, Collections[key]);
                }
                if (!string.IsNullOrWhiteSpace(Parameters) && Parameters.EndsWith("&"))
                {
                    Parameters = Parameters.Substring(0, Parameters.Length - 1);
                }
                return Parameters;
            }
    
        }
    复制代码

    2、监控类

    复制代码
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
        public class StatisticsTrackerAttribute : 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[Key] = MonLog;
            }
    
            public override void OnActionExecuted(ActionExecutedContext filterContext)
            {
                MonitorLog MonLog = filterContext.Controller.ViewData[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[Key] as MonitorLog;
                MonLog.ExecuteStartTime = DateTime.Now;
               
            }
            public override void OnResultExecuted(ResultExecutedContext filterContext)
            {
                MonitorLog MonLog = filterContext.Controller.ViewData[Key] as MonitorLog;
                MonLog.ExecuteEndTime = DateTime.Now;
                LoggerHelper.Monitor(MonLog.GetLoginfo(MonitorLog.MonitorType.View));
                filterContext.Controller.ViewData.Remove(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
    
        }
    复制代码

    3、引用监控

    我们可以在每个Controller类上或Action上直接引用 [StatisticsTracker]即可完成对该Controller或Action的监控。

    我们也可以在FilterConfig.cs中注册全局监控,这样我们就可以监控每一个Controller中的Action,代码如下:

    复制代码
    public class FilterConfig
        {
            public static void RegisterGlobalFilters(GlobalFilterCollection filters)
            {
                filters.Add(new HandleErrorAttribute());
                //监控引用
                filters.Add(new StatisticsTrackerAttribute());
            }
        }
    复制代码

    LoggerHelper

      log文件的记录采用log4net,log4net是.Net下一个非常优秀的开源日志记录组件。log4net记录日志的功能非常强大。具体配置如下。

    1、log4net配置文件

      log4Net的配置文件名称为log4net.config,具体配置如下。

     log4net.config

    2、注册log4net配置文件

      在Global.asax中注册log4net配置文件,代码如下

    复制代码
    protected void Application_Start()
            {
                //注册 log4net
                log4net.Config.XmlConfigurator.Configure(
                   new System.IO.FileInfo(AppDomain.CurrentDomain.BaseDirectory + "\Config\log4net.config")
               );
                AreaRegistration.RegisterAllAreas();
    
                WebApiConfig.Register(GlobalConfiguration.Configuration);
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                BundleConfig.RegisterBundles(BundleTable.Bundles);
            }
    复制代码

    3、LoggerHelper.cs

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace Monitor.Models.ActionFilters
    {
        public class LoggerHelper
        {
            static readonly log4net.ILog loginfo = log4net.LogManager.GetLogger("loginfo");
            static readonly log4net.ILog logerror = log4net.LogManager.GetLogger("logerror");
            static readonly log4net.ILog logmonitor = log4net.LogManager.GetLogger("logmonitor");
    
            public static void Error(string ErrorMsg, Exception ex = null)
            {
                if (ex != null)
                {
                    logerror.Error(ErrorMsg, ex);
                }
                else
                {
                    logerror.Error(ErrorMsg);
                }
            }
    
            public static void Info(string Msg)
            {
                loginfo.Info(Msg);
            }
    
            public static void Monitor(string Msg)
            {
                logmonitor.Info(Msg);
            }
        }
    }
    复制代码

    4.log4net日志生成的文件目录结构如下图

    目录结构我们区分开了错误日志、Info日志、监控日志,并且会按照日期生成日志,方便我们查看。

     源代码

  • 相关阅读:
    ring0 ShadowSSDTHook
    ring0 恢复SSDTHook
    Go的CSP并发模型
    [转]An overview of Openvswitch implementation
    堆排序
    集群 分布式
    云介绍
    云分层
    happens-before
    Java异常
  • 原文地址:https://www.cnblogs.com/lizhigang/p/7285337.html
Copyright © 2020-2023  润新知