使用过滤器记录api接口访问时长并记录日志
using ERP.Helper; using ERP.Models.User; using System; using System.Diagnostics; using System.Web; using System.Web.Http.Controllers; using System.Web.Http.Filters; using ActionFilterAttribute = System.Web.Http.Filters.ActionFilterAttribute; using Logger = ERP.Helper.Log.Logger; namespace ERP.Services { public class PerformanceActionAttribute : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext filterContext) { //在Action执行前执行 GetTimer("action").Start(); } public override void OnActionExecuted(HttpActionExecutedContext Context) { //在Action执行之后执行 var actionTimer = GetTimer("action"); actionTimer.Stop(); var userName = ""; //var ip = Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(p => p.AddressFamily.ToString() == "InterNetwork")?.ToString(); var ip = IpHelper.GetUserIp(); var url = Context.Request.RequestUri.ToString(); var extime = actionTimer.ElapsedMilliseconds + "ms"; Logger.RecordEmailLog(userName,ip,url, extime ); //在这里显示给用户的时间只是action的执行时间,如果在view中有执行调用代码的部分,则时间不会 //记录在内,所以这里的时间不是很准,但是这个时间可以很自由的被view中的代码调用显示,使得界面可以按照 //自己的意愿进行显示 } private Stopwatch GetTimer(string name) { string key = "__timer__" + name; if (HttpContext.Current.Items.Contains(key)) { return (Stopwatch)HttpContext.Current.Items[key]; } var result = new Stopwatch(); HttpContext.Current.Items[key] = result; return result; } } }
- OnActionExecuting方法会在每个Action执行之前被调用,该方法中通过调用GetTimer方法创建一个计时器并启动计时。
- OnActionExecuted方法会在每个Action执行之后被调用,该方法中通过调用GetTimer方法获取之前创建的计时器,并停止计时。
- 获取到请求的相关信息,如用户名、IP地址、URL和Action的执行时间。
- 最后调用Logger.RecordEmailLog方法将这些信息记录下来。
GetTimer方法用于获取一个计时器实例,该方法会根据name参数生成一个唯一的键名,并将计时器对象存储在HttpContext.Current.Items中,确保每个请求都有独立的计时器。