.net webapi 过滤器使用(记录访问日志)

常用的过滤器有三种:OnAuthorization、ActionFilterAttribute、ExceptionFilterAttribute

本文件主要记录使用ActionFilterAttribute记录接口的访问日志,包括请求参数、响应结果,耗时等

直接上代码:

  1 using Newtonsoft.Json;
  2 using System;
  3 using System.Collections.Generic;
  4 using System.IO;
  5 using System.Linq;
  6 using System.Text;
  7 using System.Web;
  8 using System.Web.Http.Controllers;
  9 using System.Web.Http.Filters;
 10 using WebApi.Models;
 11 
 12 namespace WebApi.App_Start
 13 {
 14     /// <summary>
 15     /// 在Action方法运行之前调用
 16     /// 1、所有请求流水先写TXT日志
 17     /// 2、再启动作业程序把日志转存到指定位置
 18     /// 3、分析日志进指定表,并删除日志
 19     /// </summary>
 20     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
 21     public class WebApiTrackerAttribute : ActionFilterAttribute
 22     {
 23         private readonly string Key = "_thisWebApiOnActionMonitorLog_";
 24         public override void OnActionExecuting(HttpActionContext actionContext)
 25         {
 26             base.OnActionExecuting(actionContext);
 27             WebApiMonitorLog MonLog = new WebApiMonitorLog();
 28             MonLog.ExecuteStartTime = DateTime.Now;
 29             //获取Action 参数
 30             MonLog.ActionParams = actionContext.ActionArguments;
 31             MonLog.HttpRequestHeaders = actionContext.Request.Headers.ToString();
 32             MonLog.HttpMethod = actionContext.Request.Method.Method;
 33 
 34             actionContext.Request.Properties[Key] = MonLog;
 35             var form = System.Web.HttpContext.Current.Request.Form;
 36             #region 如果参数是实体对象,获取序列化后的数据
 37             Stream stream = actionContext.Request.Content.ReadAsStreamAsync().Result;
 38             Encoding encoding = Encoding.UTF8;
 39             stream.Position = 0;
 40             string responseData = "";
 41             using (StreamReader reader = new StreamReader(stream, encoding))
 42             {
 43                 responseData = reader.ReadToEnd().ToString();
 44             }
 45             if (!string.IsNullOrWhiteSpace(responseData) && !MonLog.ActionParams.ContainsKey("__EntityParamsList__"))
 46             {
 47                 MonLog.ActionParams["__EntityParamsList__"] = responseData;
 48             }
 49             #endregion
 50         }
 51 
 52         /// <summary>
 53         /// 在Action方法运行之后调用
 54         /// </summary>
 55         /// <param name="actionExecutedContext"></param>
 56         public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
 57         {
 58             //加上按线程数存
 59             int thread = 0;
 60             try
 61             {
 62                 thread = System.Threading.Thread.CurrentThread.ManagedThreadId;
 63             }
 64             catch
 65             {
 66                 thread = 0;
 67             }
 68             WebApiMonitorLog MonLog = actionExecutedContext.Request.Properties[Key] as WebApiMonitorLog;
 69             MonLog.ExecuteEndTime = DateTime.Now;
 70             MonLog.ActionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName;
 71             MonLog.ControllerName = actionExecutedContext.ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName;
 72             MonLog.Response = actionExecutedContext.Response.Content.ReadAsStringAsync().Result;
 73             //Aisidi.Log.LogBuilder.Write(MonLog.ControllerName + "_" + System.DateTime.Now.Hour, MonLog.GetLoginfo());
 74             //高并发,用线程写法
 75 
 76             string pathtxt = HttpContext.Current.Server.MapPath("/WebApiLog/");
 77             //TODO 写日志(txt格式)
 78 
 79 
 80             //Aisidi.Log.LogBuilder.Write(MonLog.ControllerName + "_" + System.DateTime.Now.Hour + "_ThreadNum_" + thread, MonLog.GetLoginfo());
 81             if (actionExecutedContext.Exception != null)
 82             {
 83                 string apiname = "";
 84                 string Msg = string.Format(@"
 85                 请求【{0}Controller】的【{1}】产生异常:
 86                 Action参数:{2}
 87                 Http请求头:{3}
 88                 客户端IP:{4},
 89                 HttpMethod:{5}", MonLog.ControllerName, MonLog.ActionName, MonLog.GetCollections(MonLog.ActionParams, out apiname), MonLog.HttpRequestHeaders, MonLog.GetIP(), MonLog.HttpMethod);
 90 
 91                 //TODO 写日志(txt格式)
 92             }
 93         }
 94     }
 95     /// <summary>
 96     /// 监控日志对象
 97     /// </summary>
 98     public class WebApiMonitorLog
 99     {
100         public string ControllerName
101         {
102             get;
103             set;
104         }
105         public string ActionName
106         {
107             get;
108             set;
109         }
110 
111         public DateTime ExecuteStartTime
112         {
113             get;
114             set;
115         }
116         public DateTime ExecuteEndTime
117         {
118             get;
119             set;
120         }
121         /// <summary>
122         /// 请求的Action 参数
123         /// </summary>
124         public Dictionary<string, object> ActionParams
125         {
126             get;
127             set;
128         }
129         /// <summary>
130         /// Http请求头
131         /// </summary>
132         public string HttpRequestHeaders
133         {
134             get;
135             set;
136         }
137 
138         /// <summary>
139         /// 请求方式
140         /// </summary>
141         public string HttpMethod
142         {
143             get;
144             set;
145         }
146         /// <summary>
147         /// 请求的IP地址
148         /// </summary>
149         public string IP
150         {
151             get;
152             set;
153         }
154 
155         public string Response { get; set; }
156 
157         public string GetLoginfo()
158         {
159             string apiname = "";
160             string reqcontent = GetCollections(ActionParams, out apiname);
161             if (reqcontent.ToLower().Contains("apiname"))
162             {
163                 apiname = JsonConvert.DeserializeObject<ApiRequest>(apiname).apiname;
164             }
165             string arguments = JsonConvert.SerializeObject(new webapi_logtxt
166             {
167                 reqtime = ExecuteStartTime,
168                 rsptime = ExecuteEndTime,
169                 dealtime = (ExecuteEndTime - ExecuteStartTime).TotalSeconds.ToString(),
170                 reqcontent = reqcontent,
171                 rspcontent = Response,
172                 apiname = apiname
173             });
174             return arguments;
175         }
176 
177         /// <summary>
178         /// 获取Action 参数
179         /// </summary>
180         /// <param name="Collections"></param>
181         /// <returns></returns>
182         public string GetCollections(Dictionary<string, object> Collections, out string apiname)
183         {
184             apiname = "";
185             string Parameters = string.Empty;
186             if (Collections == null || Collections.Count == 0)
187             {
188                 return Parameters;
189             }
190             foreach (string key in Collections.Keys)
191             {
192                 Parameters += string.Format("{0}={1}&", key, Collections[key]);
193                 if (key == "__EntityParamsList__")
194                 {
195                     apiname = Collections[key].ToString();
196                 }
197             }
198             if (!string.IsNullOrWhiteSpace(Parameters) && Parameters.EndsWith("&"))
199             {
200                 Parameters = Parameters.Substring(0, Parameters.Length - 1);
201             }
202             return Parameters;
203         }
204 
205         /// <summary>
206         /// 获取IP
207         /// </summary>
208         /// <returns></returns>
209         public string GetIP()
210         {
211             string ip = string.Empty;
212             if (!string.IsNullOrEmpty(System.Web.HttpContext.Current.Request.ServerVariables["HTTP_VIA"]))
213                 ip = Convert.ToString(System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]);
214             if (string.IsNullOrEmpty(ip))
215                 ip = Convert.ToString(System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]);
216             return ip;
217         }
218     }
219     public class webapi_logtxt
220     {
221         /// <summary>
222         /// 请求时间
223         /// </summary>
224         public DateTime reqtime { get; set; }
225         /// <summary>
226         /// 响应时间
227         /// </summary>
228         public DateTime rsptime { get; set; }
229         /// <summary>
230         /// 处理时长
231         /// </summary>
232         public string dealtime { get; set; }
233         /// <summary>
234         /// 请求内容
235         /// </summary>
236         public string reqcontent { get; set; }
237         /// <summary>
238         /// 响应内容
239         /// </summary>
240         public string rspcontent { get; set; }
241         /// <summary>
242         /// 接口方法名称
243         /// </summary>
244         public string apiname { get; set; }
245     }
246 }
View Code

 

编写作业,定时去分析上面日志(只动过时日志),高并发控制,防止异常,估不建议在正常接口中进行操作数据库或分析作业日志

 1 public void ReadFildWebApiLog()
 2         {
 3             //读取文件(1小时之前的文件)
 4             //检验临时文件夹的文件是否超过1小时
 5             string webLogTxt = System.Configuration.ConfigurationManager.AppSettings["WebApiLogFilePath"];
 6             if (!string.IsNullOrEmpty(webLogTxt))
 7             {
 8                 IsoDateTimeConverter timeFormat = new IsoDateTimeConverter();
 9                 timeFormat.DateTimeFormat = "yyyy-MM-dd HH:mm:ss.fff";
10                 List<string> webLogTxtList = new FileUtilHelper().GetFiles(webLogTxt, -60);
11                 string content = "";
12                 List<webapi_log> webapi_logList = null;
13                 List<ishop_webapi_log> ishop_webapi_logList = null;
14                 List<ishop_webapi_log_dtl> ishop_webapi_log_dtlList = null;
15                 foreach (var weblog in webLogTxtList)
16                 {
17                     ishop_webapi_logList = new List<ishop_webapi_log>();
18                     ishop_webapi_log_dtlList = new List<ishop_webapi_log_dtl>();
19                     webapi_logList = new List<webapi_log>();
20                     content = System.IO.File.ReadAllText(webLogTxt + weblog);
21                     var contentList = content.Split('\n');
22                     foreach (var con in contentList)
23                     {
24                         if (!string.IsNullOrEmpty(con))
25                         {
26                             webapi_logList.Add(JsonConvert.DeserializeObject<webapi_log>(con));
27                         }
28                     }
29                     foreach (var log in webapi_logList)
30                     {
31                         string logid = Guid.NewGuid().ToString();
32                         string logdtlid = Guid.NewGuid().ToString();
33                         ishop_webapi_logList.Add(new ishop_webapi_log
34                         {
35                             id = logid,
36                             apiname = log.apiname,
37                             controllers = weblog.Split('_')[0].ToString(),
38                             createtime = System.DateTime.Now,
39                             dealtime = log.dealtime,
40                             reqtime = log.reqtime,
41                             rsptime = log.rsptime
42                         });
43                         ishop_webapi_log_dtlList.Add(new ishop_webapi_log_dtl
44                         {
45                             id = logdtlid,
46                             refid = logid,
47                             reqcontent = log.reqcontent,
48                             rspcontent = log.rspcontent
49                         });
50                     }
51                     //存储数据库
52                     if (ishop_webapi_logDal.BatchAdd_SQL(ishop_webapi_logList, "ishop_webapi_log", ishavekey: false) > 0 && ishop_webapi_log_dtlDal.BatchAdd_SQL(ishop_webapi_log_dtlList, "ishop_webapi_log_dtl", ishavekey: false) > 0)
53                     {
54 
55                         //删除文件
56                         System.IO.File.Delete(webLogTxt + weblog);
57                     }
58                 }
59             }
60 
61         }
View Code

 

posted @ 2021-07-08 15:56  繒經最羙  阅读(939)  评论(0编辑  收藏  举报