1. 程式人生 > 其它 >.net webapi 過濾器使用(記錄訪問日誌)

.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