巧用ActionFilterAttribute实现API日志的记录

网友投稿 306 2023-05-20

[[381754]]

本文转载自微信公众号「UP技术控」,作者conan5566。转载本文请联系UP技术控公众号。  

背景

上回提到开发web api的时候,一般是需要记录api的输入输出信息,方便后续排查问题;使用的是委托的形式进行记录日志。

使用Func

这次我们使用另外一种方式,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();          }  1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.

2、定义Stopwatch ,计算方法的耗时。

复制private string ActionArguments { get; set; }          /// <summary>          /// 请求体中的所有值          /// </summary>          private string RequestBody { get; set; }          private Stopwatch Stopwatch { get; set; }  1.2.3.4.5.6.7.8.

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 asdynamic             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} 毫秒(指控制器内对应方法执行完毕的时间)");          }  1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.

4、控制器调用LogAttribute。

复制/// <summary>      ///      /// </summary>      [Produces("application/json")]      [LogAttribute]      [CustomExceptionFilterAttribute]      public class DefaultController : Controller      {      }  1.2.3.4.5.6.7.8.9.

完整代码

复制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 asdynamic             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} 毫秒(指控制器内对应方法执行完毕的时间)");          }      }  1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.47.48.49.50.51.52.53.54.55.56.57.58.59.60.61.62.63.64.65.66.67.68.69.70.71.72.73.74.75.76.77.78.79.80.81.82.83.84.85.86.87.88.89.90.91.92.93.94.95.96.97.

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:手机卡归属地怎么改?简单方法帮你解决
下一篇:手机卡怎么改归属地?——教你轻松实现苹果手机归属地显示
相关文章

 发表评论

暂时没有评论,来抢沙发吧~