在客户端请求接口时,经常会出现接口相应慢,接口等待超时,接口错误,为了这事相信不少后台开发者为此背锅,记下请求日志,拿出有力证据这才是关键。
1.接口请求错误记录
很多时候接口请求出现的500,404这些错误,请求当时出现如果客户端没有日志记录,有些问题是很难复现,虽然系统日志中也会记录,但是不够系统。
那么可以通过接下来的方式记录系统错误信息,这时我们可以在Global中添加Application_Error的处理:
void Application_Error(object sender, EventArgs e) { //获取错误信息 Exception lastError = Server.GetLastError(); int httpCode = 200; HttpException httpError = lastError as HttpException; if (httpError != null) { //获取错误代码 httpCode = httpError.GetHttpCode(); } // 在出现未处理的错误时运行的代码 Exception objErr = Server.GetLastError().GetBaseException(); string error = string.Empty; string errortime = string.Empty; string erroraddr = string.Empty; string errorinfo = string.Empty; string errorsource = string.Empty; string errortrace = string.Empty; string errorcode = string.Empty; error += "发生时间:" + System.DateTime.Now.ToString() + "<br>"; errortime = "发生时间:" + System.DateTime.Now.ToString(); error += "发生异常页: " + Request.Url.ToString() + "<br>"; erroraddr = "发生异常页: " + Request.Url.ToString(); error += "返回状态码: " + httpCode + "<br>"; errorcode = "返回状态码: " + httpCode; error += "异常信息: " + objErr.Message + "<br>"; errorinfo = "异常信息: " + objErr.Message; //error +="错误源:"+objErr.Source+"<br>"; //error += "堆栈信息:" + objErr.StackTrace + "<br>"; errorsource = "错误源:" + objErr.Source; errortrace = "堆栈信息:" + objErr.StackTrace; error += "--------------------------------------<br>"; Server.ClearError(); Application["error"] = error; //独占方式,因为文件只能由一个进程写入. System.IO.StreamWriter writer = null; try { lock (this) { // 写入日志 string year = DateTime.Now.Year.ToString(); string month = DateTime.Now.Month.ToString(); string path = string.Empty; string filename = DateTime.Now.Day.ToString() + ".txt"; path = Server.MapPath("~/App_Data/log/") + year + "/" + month; //如果目录不存在则创建 if (!System.IO.Directory.Exists(path)) { System.IO.Directory.CreateDirectory(path); } System.IO.FileInfo file = new System.IO.FileInfo(path + "/" + filename); //if (!file.Exists) // file.Create(); //file.Open(System.IO.FileMode.Append); writer = new System.IO.StreamWriter(file.FullName, true);//文件不存在就创建,true表示追加 writer.WriteLine("用户IP:" + Request.UserHostAddress); // if (Session["Identity"] != null) // { // writer.WriteLine("登录帐号:" System.Web.HttpContext.Current.Session["Identity"]).YongHuInfo.ACCOUNTID); // } writer.WriteLine(errortime); writer.WriteLine(erroraddr); writer.WriteLine(errorcode); writer.WriteLine(errorinfo); writer.WriteLine(errorsource); writer.WriteLine(errortrace); writer.WriteLine("--------------------------------------------------------------------------------------"); } } finally { if (writer != null) writer.Close(); } //服务端返回状态码 Response.StatusCode = 500; Response.AddHeader("errormsg", Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(objErr.Message))); }
2.接口请求记录
记录每一次请求接口的时间和参数,方便请求错误重现。
在Application_BeginRequest添加如下配置:
void Application_BeginRequest(object source, EventArgs e) { var requestUrl = DateTime.Now + "请求链接" + Request.Url.ToString() + "\r\n"; var requestData = DateTime.Now + "请求参数" + ApiSign.GetxtParams() + "\r\n"; // 写入日志 string year = DateTime.Now.Year.ToString(); string month = DateTime.Now.Month.ToString(); string path = string.Empty; string filename = DateTime.Now.Day.ToString() + "_request" + ".txt"; path = Server.MapPath("~/App_Data/log/") + year + "/" + month; string Filepath=path + "/" + filename; if (requestUrl.ToUpper().IndexOf("API/") != -1) { Task.Run(() =>{Ecio_Admin.Common.ToolKit.PrintText(requestUrl + requestData, Filepath, true);}); } }
当然这里有一个比较常用的日志文件记录方法,这里把单独封装了PrintText。
/// <summary> /// 本地打印文本记录 /// </summary> /// <param name="text">需要写入的值</param> /// <param name="path">文件路径</param> /// <param name="IsAppend">是否追加至最后一行</param> /// <returns>追加结果</returns> public static void PrintText(string text, string path, bool IsAppend) { try { if (!Directory.Exists(path.Split(new string[] { path.Substring(path.LastIndexOf('\\')) }, StringSplitOptions.RemoveEmptyEntries)[0])) Directory.CreateDirectory(path); if (!File.Exists(path)) { using (System.IO.StreamWriter Creat = File.CreateText(path)) { } } if (IsAppend) { using (System.IO.StreamWriter sw = new System.IO.StreamWriter(path, true)) { lock (sw) { sw.WriteLine(text); } } } else { System.IO.File.WriteAllText(path, text); } } catch { } }
3.记录接口请求时间
这里我是用了一个windows系统服务来轮询每一个接口的请求和响应时间,可以参考下面这个文章,建一个服务,然后测试接口响应时间。
http://www.cnblogs.com/loyung/p/6123317.html