背景

上回提到开发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日志的记录相关推荐

  1. 使用FuncT, TResult 委托实现API日志的记录

    问题 平常我们开发web api的时候,一般是需要记录api的输入输出信息,方便后续排查问题:那么我们一般怎么做的,一般是我们在一个公共地方的写个公共方法控制输入输出.这时候Func<T, TR ...

  2. 【Go API 开发实战 7】基础 3:记录和管理 API 日志

    记录和管理 API 日志 本节核心内容 Go 日志包数量众多,功能不同.性能不同,本教程介绍一个笔者认为比较好的日志库,并给出原因 介绍如何初始化日志包 介绍如何调用日志包 介绍如何转存(rotate ...

  3. ASP.NET Core 实战:使用 NLog 将日志信息记录到 MongoDB

    在项目开发中,日志系统是系统的一个重要组成模块,通过在程序中记录运行日志.错误日志,可以让我们对于系统的运行情况做到很好的掌控.同时,收集日志不仅仅可以用于诊断排查错误,由于日志同样也是大量的数据,通 ...

  4. .NET WebAPI 用ExceptionFilterAttribute实现错误(异常)日志的记录(log4net做写库操作)...

    好吧,还是那个社区APP,非管理系统,用户行为日志感觉不是很必要的,但是,错误日志咱还是得记录则个.总不能上线后报bug了让自己手足无措吧,虽然不管有木有错误日志报bug都是件很头疼的事... 我们知 ...

  5. Dynamics CRM2016 Web API之创建记录

    前篇介绍了通过primary key来查询记录,那query的知识点里面还有很多需要学习的,这个有待后面挖掘,本篇来简单介绍下用web api的创建记录. 直接上代码,这里的entity的属性我列了几 ...

  6. .NET WebAPI 用ExceptionFilterAttribute实现错误(异常)日志的记录(log4net做写库操作)

    .NET WebAPI 用ExceptionFilterAttribute实现错误(异常)日志的记录(log4net做写库操作) 参考文章: (1).NET WebAPI 用ExceptionFilt ...

  7. 4.36域名重定向4.37用户认证4.38Nginx访问日志4.39日志不记录静态文件4.40日志切割...

    2019独角兽企业重金招聘Python工程师标准>>> 域名重定向 用户认证 Nginx访问日志 日志不记录静态文件 日志切割 域名重定向 配置第二个域名: vi /etc/ngin ...

  8. outlook 未安装信息服务器,Outlook Web Access 未初始化并且在客户端访问服务器上的应用程序日志中记录了事件 ID 64...

    Outlook Web Access 未初始化并且在客户端访问服务器上的应用程序日志中记录了事件 ID 64 07/04/2014 本文内容 上一次修改主题: 2007-10-17 尝试访问 Micr ...

  9. Linux centos7 VMware Apache访问日志不记录静态文件、访问日志切割、静态元素过期时间...

    一.Apache访问日志不记录静态文件 网站大多元素为静态文件,如图片.css.js等,这些元素可以不用记录 vim /usr/local/apache2.4/conf/extra/httpd-vho ...

最新文章

  1. 不显示圆点_10个应用隐藏的彩蛋,细节控都不一定全知道。
  2. python 可以 从视频中 直接剪辑音频出来(亲测MP4)
  3. [洛谷P1268]树的重量
  4. 微信小程序通用开发框架小程序端包含若干基础组件
  5. 【Kafka】Kafka为什么要加入分区的概念
  6. 2.1 《数据库系统概论》关系数据结构及形式化定义(关系、关系模式、关系数据库)
  7. Oracle备份如何到异机还原
  8. SpringBoot整合MyBatis后台分页前端BootstrapTable添加删除查看编辑搜索数据(一)
  9. 4月17日 键盘大小写指示indicator-lockkeys
  10. vs 配置 .pdb
  11. Windows环境下hadoop安装和配置详细步骤
  12. Python入门到精通———第一天
  13. mysql recordcount_Filter 和 RecordCount 属性示例 (VB)
  14. 计算机主机闪烁显示器黑屏,显示器黑屏一闪一闪的怎么回事_显示器黑屏一闪一闪解决教程 - 系统家园...
  15. 指数基金投资指南读书笔记
  16. 设置手机最小宽度为1000,无限重启怎么办
  17. 餐馆点餐系统(Java GUI + mysql)
  18. 求sin(x)的近似值
  19. ESP32C3驱动舵机
  20. 基于角色管理的简易家谱管理系统(C++/C(几乎都是C))2020-06-16

热门文章

  1. 【转】用Fiddler做抓包分析详解
  2. h5的formData 上传文件及.net后台
  3. |洛谷|DFS|P1101 单词方阵
  4. Ctrl与Caps Lock键的交换
  5. VS2010插件之NuGet
  6. sql里如何for循环
  7. django 1.3下关于静态文件staticfiles的设置
  8. Android动态赋权限,安卓6.0以上动态添加权限超简单模板
  9. 如何从Internet Explorer或Edge迁移到Chrome(以及为什么要迁移)
  10. chrome怎么隐藏浏览器_如何使用Google Chrome的隐藏阅读器模式