asp.net mvc 记录Action耗时 新建项目 安装Nlog 修改配置文件 新建过滤器类  修改控制器  修改FilterConfig  启动 查看

可能有些时候需要记录Action的执行时间来优化系统功能,这时可以用过滤器来实现。

asp.net mvc 记录Action耗时
新建项目
安装Nlog
修改配置文件
新建过滤器类
 修改控制器
 修改FilterConfig
 启动
查看

项目名称随便取

asp.net mvc 记录Action耗时
新建项目
安装Nlog
修改配置文件
新建过滤器类
 修改控制器
 修改FilterConfig
 启动
查看

身份验证:不进行身份验证

安装Nlog

这里使用NLog来输出日志,具体使用说明请看:https://github.com/nlog/NLog/wiki(相比log4net文档说明会好很多)

解决方案中右键,选择管理NuGet包

asp.net mvc 记录Action耗时
新建项目
安装Nlog
修改配置文件
新建过滤器类
 修改控制器
 修改FilterConfig
 启动
查看

在浏览中输入:"nlog",我使用是VS2015,其它版本类似

asp.net mvc 记录Action耗时
新建项目
安装Nlog
修改配置文件
新建过滤器类
 修改控制器
 修改FilterConfig
 启动
查看

asp.net mvc 记录Action耗时
新建项目
安装Nlog
修改配置文件
新建过滤器类
 修改控制器
 修改FilterConfig
 启动
查看

选择Nlog.Config的目的是顺便把配置文件也下载了

asp.net mvc 记录Action耗时
新建项目
安装Nlog
修改配置文件
新建过滤器类
 修改控制器
 修改FilterConfig
 启动
查看

选择确定

asp.net mvc 记录Action耗时
新建项目
安装Nlog
修改配置文件
新建过滤器类
 修改控制器
 修改FilterConfig
 启动
查看

安装时会输出相关信息,没有任何错误就说明成功了

修改配置文件

在ActionTime项目下应该可以看到NLog.config文件,配置文件内容如下:

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <!-- shortdate:2017-3-30 level:Error、Info...-->
  <variable name="logDirectory" value="${basedir}/Logs/${shortdate}/${level}"/>
  <targets>
    <target xsi:type="File" name="AllFile" fileName="${logDirectory}/All.log"
            layout="${longdate}        ■${level}${newline}    ▲${stacktrace}${newline}    ◇${callsite:className=True:fileName=True:includeSourcePath=True:methodName=True}${newline}    ◆${message}${newline}${newline}***************************************************************************"
            archiveFileName="${logDirectory}/archives/All_${shortdate}.{#####}.log"
            archiveAboveSize="1024000"
            archiveNumbering="Sequence"
            concurrentWrites="true"
            keepFileOpen="false"/>
  </targets>
  <rules>
    <logger name="*" minlevel="Trace" writeTo="AllFile" />
  </rules>
</nlog>

此配置会在项目下新建Logs目录,所有日志文件都存放在里面

例:Logs2017-03-30InfoAll.Log

新建过滤器类

接着在ActimTime项目中新建一个目录Filters,此目录用来存放自定义过滤器类

在Filters目录下新建一个类TimingActionFilter

public class TimingActionFilter : ActionFilterAttribute
    {
        
        private static readonly Logger Log = LogManager.GetCurrentClassLogger(typeof(TimingActionFilter));

        //创建字典来记录开始时间,key是访问的线程Id.
        private readonly Dictionary<int, DateTime> _start = new Dictionary<int, DateTime>();

        //创建字典来记录当前访问的页面Url.
        private readonly Dictionary<int, string> _url = new Dictionary<int, string>();

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            //过滤掉ChildAction, 因为ChildAction实际上不是一个单独的页面
            if (filterContext.IsChildAction) return;

            var currentThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId;

            try
            {
                _start.Add(currentThreadId, DateTime.Now);
                _url.Add(currentThreadId, filterContext.HttpContext.Request.Url == null
                    ? string.Empty
                    : filterContext.HttpContext.Request.Url.AbsoluteUri);
            }
            catch (Exception ex)
            {
                Log.Error(ex.ToString());
            }
        }

        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            var currentThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId;
            if (!_start.ContainsKey(currentThreadId)) return;

            try
            {

                //计算出当前页面访问耗时
                var timeSpan = (DateTime.Now - _start[currentThreadId]).TotalMilliseconds;
                if (timeSpan > 500)//如果耗时超过500毫秒,就是用log4net打印出,具体是哪个页面访问超过了500豪秒,具体使用了多长时间。
                {
                    Log.Info(string.Format("运行时间超过500毫秒,共花费{1}毫秒.  URL: {0}", _url[currentThreadId], timeSpan));
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex.ToString());
            }
            finally
            {
                _start.Remove(currentThreadId);
                _url.Remove(currentThreadId);
            }
        }
    }

 修改控制器

打开HomeController,修改Index为如下:

public ActionResult Index()
        {
            Thread.Sleep(1000);//添加延时
            return View();
        }

 修改FilterConfig

再打开FilterConfig文件,修改代码如下:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
            filters.Add(new TimingActionFilter());//自己定义的过滤器
        }

 启动

现在基本工作已经完成,按F5启动项目,可以看到在项目目录下有个Logs目录

asp.net mvc 记录Action耗时
新建项目
安装Nlog
修改配置文件
新建过滤器类
 修改控制器
 修改FilterConfig
 启动
查看

查看

打开日志文件内容为如下,一般这种情况把日志写入数据库会比较好分析

asp.net mvc 记录Action耗时
新建项目
安装Nlog
修改配置文件
新建过滤器类
 修改控制器
 修改FilterConfig
 启动
查看

Demo:点击下载