巧用ActionFilterAttribute实现API日志的记录
背景
上回提到开发web api的时候,一般是需要记录api的输入输出信息,方便后续排查问题;使用的是委托的形式进行记录日志。
使用Func<T, TResult> 委托实现API日志的记录
这次我们使用另外一种方式,Filter来记录输入输出日志。
实现方式
1、首先在进入action的时候,定义OnActionExecuting。
public override void OnActionExecuting(ActionExecutingContext context){base.OnActionExecuting(context);// 后续添加了获取请求的请求体,如果在实际项目中不需要删除即可long contentLen = context.HttpContext.Request.ContentLength == null ? 0 : context.HttpContext.Request.ContentLength.Value;if (contentLen > 0){// 读取请求体中所有内容System.IO.Stream stream = context.HttpContext.Request.Body;if (context.HttpContext.Request.Method == "POST"){stream.Position = 0;}byte[] buffer = new byte[contentLen];stream.Read(buffer, 0, buffer.Length);// 转化为字符串RequestBody = System.Text.Encoding.UTF8.GetString(buffer);}ActionArguments = Newtonsoft.Json.JsonConvert.SerializeObject(context.ActionArguments);Stopwatch = new Stopwatch();Stopwatch.Start();}
2、定义Stopwatch ,计算方法的耗时。
private string ActionArguments { get; set; }/// <summary>/// 请求体中的所有值/// </summary>private string RequestBody { get; set; }private Stopwatch Stopwatch { get; set; }
3、结束的时候,把信息打印出来OnActionExecuted。
public override void OnActionExecuted(ActionExecutedContext context){base.OnActionExecuted(context);Stopwatch.Stop();string url = context.HttpContext.Request.Host + context.HttpContext.Request.Path + context.HttpContext.Request.QueryString;string method = context.HttpContext.Request.Method;string controller = context.Controller.ToString();string action = context.ActionDescriptor.DisplayName;string token = "";if (context.HttpContext.Request != null && context.HttpContext.Request.Headers != null && context.HttpContext.Request.Headers["Authorization"].Count > 0){token = context.HttpContext.Request.Headers["Authorization"];}string qs = ActionArguments;dynamic result = context?.Result?.GetType()?.Name == "EmptyResult" ? new { Value = "无返回结果" } : context?.Result as dynamic;string res = "在返回结果前发生了异常";try{if (result != null){res = Newtonsoft.Json.JsonConvert.SerializeObject(result.Value);}}catch (System.Exception){res = "日志未获取到结果,返回的数据无法序列化";}NLogger.Info($"地址:{url} \n " +$"controller:{controller} \n " +$"action:{action} \n " +$"token:{token} \n " +$"方式:{method} \n " +$"请求体:{RequestBody} \n " +$"参数:{qs}\n " +$"结果:{res}\n " +$"耗时:{Stopwatch.Elapsed.TotalMilliseconds} 毫秒(指控制器内对应方法执行完毕的时间)");}
4、控制器调用LogAttribute。
/// <summary>////// </summary>[Produces("application/json")][LogAttribute][CustomExceptionFilterAttribute]public class DefaultController : Controller{}
完整代码
using CompanyName.ProjectName.Core;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Diagnostics;namespace CompanyName.ProjectName.HttpApi.Host.Code
{/// <summary>/// 拦截器/// </summary>public class LogAttribute : ActionFilterAttribute{private string ActionArguments { get; set; }/// <summary>/// 请求体中的所有值/// </summary>private string RequestBody { get; set; }private Stopwatch Stopwatch { get; set; }/// <summary>////// </summary>/// <param name="context"></param>public override void OnActionExecuting(ActionExecutingContext context){base.OnActionExecuting(context);// 后续添加了获取请求的请求体,如果在实际项目中不需要删除即可long contentLen = context.HttpContext.Request.ContentLength == null ? 0 : context.HttpContext.Request.ContentLength.Value;if (contentLen > 0){// 读取请求体中所有内容System.IO.Stream stream = context.HttpContext.Request.Body;if (context.HttpContext.Request.Method == "POST"){stream.Position = 0;}byte[] buffer = new byte[contentLen];stream.Read(buffer, 0, buffer.Length);// 转化为字符串RequestBody = System.Text.Encoding.UTF8.GetString(buffer);}ActionArguments = Newtonsoft.Json.JsonConvert.SerializeObject(context.ActionArguments);Stopwatch = new Stopwatch();Stopwatch.Start();}/// <summary>////// </summary>/// <param name="context"></param>public override void OnActionExecuted(ActionExecutedContext context){base.OnActionExecuted(context);Stopwatch.Stop();string url = context.HttpContext.Request.Host + context.HttpContext.Request.Path + context.HttpContext.Request.QueryString;string method = context.HttpContext.Request.Method;string controller = context.Controller.ToString();string action = context.ActionDescriptor.DisplayName;string token = "";if (context.HttpContext.Request != null && context.HttpContext.Request.Headers != null && context.HttpContext.Request.Headers["Authorization"].Count > 0){token = context.HttpContext.Request.Headers["Authorization"];}string qs = ActionArguments;dynamic result = context?.Result?.GetType()?.Name == "EmptyResult" ? new { Value = "无返回结果" } : context?.Result as dynamic;string res = "在返回结果前发生了异常";try{if (result != null){res = Newtonsoft.Json.JsonConvert.SerializeObject(result.Value);}}catch (System.Exception){res = "日志未获取到结果,返回的数据无法序列化";}NLogger.Info($"地址:{url} \n " +$"controller:{controller} \n " +$"action:{action} \n " +$"token:{token} \n " +$"方式:{method} \n " +$"请求体:{RequestBody} \n " +$"参数:{qs}\n " +$"结果:{res}\n " +$"耗时:{Stopwatch.Elapsed.TotalMilliseconds} 毫秒(指控制器内对应方法执行完毕的时间)");}}
}
巧用ActionFilterAttribute实现API日志的记录相关推荐
- 使用FuncT, TResult 委托实现API日志的记录
问题 平常我们开发web api的时候,一般是需要记录api的输入输出信息,方便后续排查问题:那么我们一般怎么做的,一般是我们在一个公共地方的写个公共方法控制输入输出.这时候Func<T, TR ...
- 【Go API 开发实战 7】基础 3:记录和管理 API 日志
记录和管理 API 日志 本节核心内容 Go 日志包数量众多,功能不同.性能不同,本教程介绍一个笔者认为比较好的日志库,并给出原因 介绍如何初始化日志包 介绍如何调用日志包 介绍如何转存(rotate ...
- ASP.NET Core 实战:使用 NLog 将日志信息记录到 MongoDB
在项目开发中,日志系统是系统的一个重要组成模块,通过在程序中记录运行日志.错误日志,可以让我们对于系统的运行情况做到很好的掌控.同时,收集日志不仅仅可以用于诊断排查错误,由于日志同样也是大量的数据,通 ...
- .NET WebAPI 用ExceptionFilterAttribute实现错误(异常)日志的记录(log4net做写库操作)...
好吧,还是那个社区APP,非管理系统,用户行为日志感觉不是很必要的,但是,错误日志咱还是得记录则个.总不能上线后报bug了让自己手足无措吧,虽然不管有木有错误日志报bug都是件很头疼的事... 我们知 ...
- Dynamics CRM2016 Web API之创建记录
前篇介绍了通过primary key来查询记录,那query的知识点里面还有很多需要学习的,这个有待后面挖掘,本篇来简单介绍下用web api的创建记录. 直接上代码,这里的entity的属性我列了几 ...
- .NET WebAPI 用ExceptionFilterAttribute实现错误(异常)日志的记录(log4net做写库操作)
.NET WebAPI 用ExceptionFilterAttribute实现错误(异常)日志的记录(log4net做写库操作) 参考文章: (1).NET WebAPI 用ExceptionFilt ...
- 4.36域名重定向4.37用户认证4.38Nginx访问日志4.39日志不记录静态文件4.40日志切割...
2019独角兽企业重金招聘Python工程师标准>>> 域名重定向 用户认证 Nginx访问日志 日志不记录静态文件 日志切割 域名重定向 配置第二个域名: vi /etc/ngin ...
- outlook 未安装信息服务器,Outlook Web Access 未初始化并且在客户端访问服务器上的应用程序日志中记录了事件 ID 64...
Outlook Web Access 未初始化并且在客户端访问服务器上的应用程序日志中记录了事件 ID 64 07/04/2014 本文内容 上一次修改主题: 2007-10-17 尝试访问 Micr ...
- Linux centos7 VMware Apache访问日志不记录静态文件、访问日志切割、静态元素过期时间...
一.Apache访问日志不记录静态文件 网站大多元素为静态文件,如图片.css.js等,这些元素可以不用记录 vim /usr/local/apache2.4/conf/extra/httpd-vho ...
最新文章
- 不显示圆点_10个应用隐藏的彩蛋,细节控都不一定全知道。
- python 可以 从视频中 直接剪辑音频出来(亲测MP4)
- [洛谷P1268]树的重量
- 微信小程序通用开发框架小程序端包含若干基础组件
- 【Kafka】Kafka为什么要加入分区的概念
- 2.1 《数据库系统概论》关系数据结构及形式化定义(关系、关系模式、关系数据库)
- Oracle备份如何到异机还原
- SpringBoot整合MyBatis后台分页前端BootstrapTable添加删除查看编辑搜索数据(一)
- 4月17日 键盘大小写指示indicator-lockkeys
- vs 配置 .pdb
- Windows环境下hadoop安装和配置详细步骤
- Python入门到精通———第一天
- mysql recordcount_Filter 和 RecordCount 属性示例 (VB)
- 计算机主机闪烁显示器黑屏,显示器黑屏一闪一闪的怎么回事_显示器黑屏一闪一闪解决教程 - 系统家园...
- 指数基金投资指南读书笔记
- 设置手机最小宽度为1000,无限重启怎么办
- 餐馆点餐系统(Java GUI + mysql)
- 求sin(x)的近似值
- ESP32C3驱动舵机
- 基于角色管理的简易家谱管理系统(C++/C(几乎都是C))2020-06-16
热门文章
- 【转】用Fiddler做抓包分析详解
- h5的formData 上传文件及.net后台
- |洛谷|DFS|P1101 单词方阵
- Ctrl与Caps Lock键的交换
- VS2010插件之NuGet
- sql里如何for循环
- django 1.3下关于静态文件staticfiles的设置
- Android动态赋权限,安卓6.0以上动态添加权限超简单模板
- 如何从Internet Explorer或Edge迁移到Chrome(以及为什么要迁移)
- chrome怎么隐藏浏览器_如何使用Google Chrome的隐藏阅读器模式