web api 记录请求
2018-06-22 06:05:10来源:未知 阅读 ()
前段时间在开发一个协议站点供客户端(Android/IOS)使用,因业务需要统计各协议的调用频率。将记录以日志的形式记录在日志系统中。
简单分析了一下,技术方案大致分为两种:
方案A:每个业务模块需要埋点的协议单独埋点。
方案B:封装一个HttpModule。记录所有的请求。
方案A与方案B的优缺点就不在分析了。在我们的项目有两个个小组做类似的协议站点,我们采用的是方案B。而另外的一个小组采用方案A。
在此我重点说一下采用的方案B的理由:
1、麻烦一个人,一个人开发完毕后,其他人不再去花时间增加记录。统一记录。
2、方便排错,还可以做请求参数与输出参数的记录,也不用在业务中记录返回的值。业务开发只关心业务即可。记录业务中的常规日志即可。
代码比较简单。与协议之间走的是Post请求发送Json串。请求串全在Request.InputStream中。两个文件一个处理请求(Handle.cs),一个获取数据(CatchTextStream.cs)
Handle.cs
using System; using System.IO; using System.Web; using Logs; namespace HttpModule.Api { public class Handle : IHttpModule { private string json = string.Empty; private string requestItemKey = "request.json"; private string responseItemKey = "response.json"; void IHttpModule.Dispose() { } void IHttpModule.Init(HttpApplication context) { context.BeginRequest += new EventHandler(beginRequest); context.EndRequest += new EventHandler(endRequest); } private void beginRequest(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; var context = application.Context; if (context == null) { return; } //排除不需要的链接 if (context.Request.InputStream.Length > 0) { context.Response.Filter = new CatchTextStream(context.Response.Filter, responseItemKey); context.Request.InputStream.Position = 0; //设置流的位置 StreamReader reader = new StreamReader(context.Request.InputStream); //request请求流 string json = reader.ReadToEnd(); context.Request.InputStream.Seek(0, SeekOrigin.End);//重置流读取位置,如果不重置在方法中无法获取json串 context.Request.RequestContext.HttpContext.Items[requestItemKey] = json; } else//只记录请求参数 { _log.Info("请求url:" + context.Request.Url); } } private void endRequest(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; var context = application.Context; if (context.Request.RequestContext.HttpContext.Items.Contains(requestItemKey)) { string requestJson = context.Request.RequestContext.HttpContext.Items[requestItemKey].ToString(); string responseJson = context.Request.RequestContext.HttpContext.Items[responseItemKey].ToString(); //当前请求状态 返回值中带code:0表示协议请求成功 status=日志系统使用标识,1=请求正常返回,0=请求异常 int status = responseJson.Contains("\"code\":\"0\"") ? 1 : 0; writeLog(context.Request.Url.LocalPath, requestJson, "return=" + responseJson, status); } } private void writeLog(string url, string parms, string msg, int status) { var entity = new Logs.LogRecord("站点名称", LogLevelType.Monitor, url) { ParasNameValue = parms, ErrMessage = msg, Status = status }; Logs.LogNetHelper.WriteLog(entity); } } }
注:Logs包为公司项目封装的通用记录方法。
CatchTextStream.cs
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Web; namespace HttpModule.Api { class CatchTextStream : Stream { private Stream output; private List<byte> _listByte = new List<byte>(); private string _itemKey; public CatchTextStream(Stream s, string itemKey) { _itemKey = itemKey; output = s; } public override bool CanRead { get { return output.CanRead; } } public override bool CanSeek { get { return output.CanSeek; } } public override bool CanWrite { get { return output.CanWrite; } } public override void Flush() { output.Flush(); if (_listByte.Any()) { var utf8 = Encoding.UTF8; string json = utf8.GetString(_listByte.ToArray(), 0, _listByte.Count); HttpContext.Current.Request.RequestContext.HttpContext.Items[_itemKey] = json; } } public override long Length { get { return output.Length; } } public override long Position { get { return output.Position; } set { output.Position = value; } } public override int Read(byte[] buffer, int offset, int count) { return output.Read(buffer, offset, count); } public override long Seek(long offset, SeekOrigin origin) { return output.Seek(offset, origin); } public override void SetLength(long value) { output.SetLength(value); } public override void Write(byte[] buffer, int offset, int count) { output.Write(buffer, offset, count); if (HttpContext.Current != null) { if (HttpContext.Current.Request.RequestContext.HttpContext.Items.Contains(_itemKey)) { var temp = buffer.Skip(offset).Take(count); _listByte.AddRange(temp); } } } } }
接下来在Web.config配置Modules即可。
<modules runAllManagedModulesForAllRequests="true"> <!--记录请求日志--> <add name="apilog" type="HttpModule.Api.Handle,HttpModule.Api" /> </modules>
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- Asp.net MVC SignalR来做实时Web聊天实例代码 2020-03-29
- Asp.Net中WebForm的生命周期 2020-03-29
- ASP.NET使用WebService实现天气预报功能 2020-01-20
- 浅谈ASP.Net Core WebApi几种版本控制对比 2019-12-10
- 详解Visual之Web Essentials的使用方法 2019-11-27
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash