net 记录controller Action耗时

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

第1个例子

using System;
using System.Diagnostics;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http.Controllers;
using System.Web.Mvc;

namespace Mall.Site
{

/// <summary>
/// 执行耗时监测
/// </summary>
public class StopwatchFilter : ActionFilterAttribute
{
Stopwatch wat = new Stopwatch();
Stopwatch swAsync = new Stopwatch();

public override void OnActionExecuted(ActionExecutedContext filterContext)
{
swAsync.Stop();
if (swAsync.ElapsedMilliseconds>0)
{
string msg = string.Format("页面{0},线程id={1},Action执行时间{2}毫秒", filterContext.HttpContext.Request.RawUrl, Thread.CurrentThread.ManagedThreadId, swAsync.ElapsedMilliseconds);
FrameWork.log4net.LogHelper.LogInfo(msg);
} 
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
swAsync.Reset();
swAsync.Start();
}


public override void OnResultExecuted(ResultExecutedContext filterContext)
{
wat.Stop();
if (wat.ElapsedMilliseconds>0)
{ 
string msg = string.Format("页面{0},线程id={1},View执行时间{2}毫秒", filterContext.HttpContext.Request.RawUrl, Thread.CurrentThread.ManagedThreadId, wat.ElapsedMilliseconds);
FrameWork.log4net.LogHelper.LogInfo(msg);
} 
}
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
wat.Reset();
wat.Start();
} 
}
}
View Code

 

https://blog.csdn.net/u011511086/article/details/78710980?utm_source=copy 

 

第2个例子方法.

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

修改配置文件

在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>
View Code

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

例:Logs\2017-03-30\Info\All.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);
            }
        }
    }
View Code

 修改控制器

打开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());//自己定义的过滤器
        }

 

https://www.cnblogs.com/shensigzs/p/6645631.html

 

posted @ 2019-02-18 17:54  bxzjzg  阅读(272)  评论(0编辑  收藏  举报