[.Net]Framwork WebAPI添加接口请求监控
作者:互联网
思路:
通过重写 ActionFilterAttribute 拦截Action的请求及返回信息,实现对接口请求的监听。
最终效果如下:
全局启用需配置如下:
局部启用需配置如下:
源码如下:
1 /// <summary> 2 /// 统一的接口访问监控日志, 3 /// 全局启用-请添加 GlobalConfiguration.Configuration.Filters.Add(new TimingFilterAttribute()); 4 /// 局部启用(目前模式)-在Controller或者Action上添加Attribute注入即可 5 /// </summary> 6 public class TimingFilterAttribute : ActionFilterAttribute 7 { 8 private const string Key = "__action_recordtime__"; 9 private const string TimeKey = "__action_receivetime__"; 10 /// <summary> 11 /// 自定义参数 12 /// </summary> 13 public static string msg { get; set; } 14 public static string ReqParms { get; set; } 15 public TimingFilterAttribute() 16 { 17 msg = string.Empty; 18 } 19 20 /// <summary> 21 /// 初始化时填入类的说明 22 /// </summary> 23 /// <param name="message"></param> 24 public TimingFilterAttribute(string message) 25 { 26 msg = message; 27 } 28 public override void OnActionExecuting(HttpActionContext actionContext) 29 { 30 if (IsRecordTime(actionContext)) 31 { 32 return; 33 } 34 // ReqParms= GetRequestValues(actionContext); 35 var stopWatch = new Stopwatch(); 36 actionContext.Request.Properties[Key] = stopWatch; 37 actionContext.Request.Properties[TimeKey] = DateTime.Now.ToBinary(); 38 stopWatch.Start(); 39 } 40 41 public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) 42 { 43 if (!actionExecutedContext.Request.Properties.ContainsKey(Key) || !actionExecutedContext.Request.Properties.ContainsKey(TimeKey)) 44 { 45 return; 46 } 47 object beginTime = null; 48 if (!actionExecutedContext.Request.Properties.TryGetValue(TimeKey, out beginTime)) 49 { 50 return; 51 } 52 var stopWatch = actionExecutedContext.Request.Properties[Key] as Stopwatch; 53 if (stopWatch == null) 54 { 55 return; 56 } 57 stopWatch.Stop(); 58 59 DateTime starttime = DateTime.FromBinary(Convert.ToInt64(beginTime)); 60 HttpRequest request = HttpContext.Current.Request; 61 string token = string.Empty; 62 var appkey = string.Empty; 63 if (request.Headers.AllKeys.Contains("Token")) { token = request.Headers["Token"]; } 64 65 if (request.Headers.AllKeys.Contains("AppKey")) { appkey = request.Headers["AppKey"]; } 66 67 var actionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName; 68 var controllerName = actionExecutedContext.ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName; 69 70 var ip = request.UserHostAddress; 71 var UserHostName = request.UserHostName; 72 var paramaters = GetRequestValues(actionExecutedContext); 73 // var paramaters = ReqParms;//获取入参 74 var executeResult = GetResponseValues(actionExecutedContext);//获取response响应的结果 75 var comments = msg; 76 var RequestUri = request.Url.AbsoluteUri; 77 var MethodType= request.HttpMethod.ToString(); 78 Bondex.Core.BizTool.LogPlat.LogHelper.Info($"{controllerName}/{actionName}", "E帐通接口监控服务", "TimingFilterAttribute", $"", 79 $"当前接口路径:{RequestUri},请求方式:{MethodType},请求时间:{starttime.ToString("yyyy-MM-dd HH:mm:ss:fff")},返回时间{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff")},接口执行时间:{stopWatch.Elapsed};请求IP:{ip},请求DNS:{UserHostName},请求入参:{paramaters},返回值:{executeResult},备注:{comments}"); 80 81 } 82 /// <summary> 83 /// 读取request 的提交内容 84 /// </summary> 85 /// <param name="actionExecutedContext"></param> 86 /// <returns></returns> 87 public string GetRequestValues(HttpActionExecutedContext actionExecutedContext) 88 { 89 string result = String.Empty; 90 using (var stream = actionExecutedContext.Request.Content.ReadAsStreamAsync().Result) 91 { 92 if (stream.CanSeek) 93 { 94 stream.Position = 0; 95 } 96 result = actionExecutedContext.Request.Content.ReadAsStringAsync().Result; 97 } 98 99 return result; 100 } 101 102 /// <summary> 103 /// 读取action返回的result 104 /// </summary> 105 /// <param name="actionExecutedContext"></param> 106 /// <returns></returns> 107 public string GetResponseValues(HttpActionExecutedContext actionExecutedContext) 108 { 109 Stream stream = actionExecutedContext.Response.Content.ReadAsStreamAsync().Result; 110 Encoding encoding = Encoding.UTF8; 111 /* 112 这个StreamReader不能关闭,也不能dispose, 关了就傻逼了 113 因为你关掉后,后面的管道 或拦截器就没办法读取了 114 */ 115 var reader = new StreamReader(stream, encoding); 116 string result = reader.ReadToEnd(); 117 /* 118 这里也要注意: stream.Position = 0; 119 当你读取完之后必须把stream的位置设为开始 120 因为request和response读取完以后Position到最后一个位置,交给下一个方法处理的时候就会读不到内容了。 121 */ 122 stream.Position = 0; 123 return result; 124 } 125 /// <summary> 126 /// 判断是否拦截请求,记录接口信息 127 /// </summary> 128 /// <param name="actionContext"></param> 129 /// <returns></returns> 130 private static bool IsRecordTime(HttpActionContext actionContext) 131 { 132 return actionContext.ActionDescriptor.GetCustomAttributes<NoRecordTimeAttribute>().Any() || 133 actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<NoRecordTimeAttribute>().Any(); 134 } 135 } 136 137 [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true)] 138 public class NoRecordTimeAttribute : Attribute 139 { 140 141 }
标签:WebAPI,string,Request,request,Framwork,actionExecutedContext,var,Net,public 来源: https://www.cnblogs.com/chao0219/p/16442807.html