IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> asp.net core mvc接口,请求响应统一日志管理 -> 正文阅读

[开发测试]asp.net core mvc接口,请求响应统一日志管理

如何为api所有的请求和响应做一个统一的日志记录

1.创建日志类

public class RequestResponseLog {
    public string Url { get; set; }
    public IDictionary<string, string> Headers { get; set; } = new Dictionary<string, string>();
    public string Method { get; set; }
    public string RequestBody { get; set; }
    public string ResponseBody { get; set; }
    public DateTime ExcuteStartTime { get; set; }
    public DateTime ExcuteEndTime { get; set; }
    public override string ToString()
    {
      string headers = "[" + string.Join(",", this.Headers.Select(i => "{" + $"\"{i.Key}\":\"{i.Value}\"" + "}")) + "]";
      return $"\r\n***********************************************************************\r\nUrl: {this.Url},\r\nHeaders: {headers},\r\nMethod: {this.Method},\r\nRequestBody: {this.RequestBody},\r\nResponseBody: {this.ResponseBody},\r\nExcuteStartTime: {this.ExcuteStartTime.ToString("yyyy-MM-dd HH:mm:ss.fff")},\r\nExcuteEndTime: {this.ExcuteEndTime.ToString("yyyy-MM-dd HH:mm:ss.fff")}";
    }
  }

2.创建日志中间件

public class RequestResponseLoggingMiddleware {
  private readonly RequestDelegate _next;
  private RequestResponseLog _logInfo;

  public RequestResponseLoggingMiddleware(RequestDelegate next)
  {
    _next = next;
  }

  public async Task Invoke(HttpContext context)
  {
    _logInfo = new RequestResponseLog();

    HttpRequest request = context.Request;
    _logInfo.Url = request.Path.ToString();
    _logInfo.Headers = request.Headers.ToDictionary(k => k.Key, v => string.Join(";", v.Value.ToList()));
    _logInfo.Method = request.Method;
    _logInfo.ExcuteStartTime = DateTime.Now;

    //获取request.Body内容
    if (request.Method.ToLower().Equals("post"))
    {

      //request.EnableRewind(); //启用倒带功能,就可以让 Request.Body 可以再次读取,.net 5弃用
      request.EnableBuffering(); 

      Stream stream = request.Body;
      byte[] buffer = new byte[request.ContentLength.Value];
      //stream.Read(buffer, 0, buffer.Length);   //.net 3.0之后不允许同步读取
      stream.ReadAsync(buffer, 0, buffer.Length);
      _logInfo.RequestBody = Encoding.UTF8.GetString(buffer);

      request.Body.Position = 0;

    }
    else if (request.Method.ToLower().Equals("get"))
    {
      _logInfo.RequestBody = request.QueryString.Value;
    }

    //获取Response.Body内容
    var originalBodyStream = context.Response.Body;

    using (var responseBody = new MemoryStream())
    {
      context.Response.Body = responseBody;

      await _next(context);

      _logInfo.ResponseBody = await FormatResponse(context.Response);
      _logInfo.ExcuteEndTime = DateTime.Now;
      //Log4Net.LogInfo($"VisitLog: {_logInfo.ToString()}");
      LogA.SaveInfoToTxtFile($"VisitLog: {_logInfo.ToString()}");


      await responseBody.CopyToAsync(originalBodyStream);
    }
  }

  private async Task<string> FormatResponse(HttpResponse response)
  {
    response.Body.Seek(0, SeekOrigin.Begin);
    var text = await new StreamReader(response.Body).ReadToEndAsync();
    response.Body.Seek(0, SeekOrigin.Begin);

    return text;
  }
}

public static class RequestResponseLoggingMiddlewareExtensions {
  public static IApplicationBuilder UseRequestResponseLogging(this IApplicationBuilder builder)
  {
    return builder.UseMiddleware<RequestResponseLoggingMiddleware>();
  }
}

3.日志书写类

public static class LogA {
  public static void SaveInfoToTxtFile(string info)
  {
    string bPath = AppContext.BaseDirectory;
    //如果不存在Log文件夹就创建文件夹
    if (Directory.Exists(bPath+@".\Log") == false)
    {
      Directory.CreateDirectory(bPath+@".\Log");
    }

    //如果不存在log文件夹下的以年月命名的文件夹就创建file文件夹
    if (Directory.Exists(bPath+@".\Log\" + DateTime.Now.ToString("yyyyMM")) == false)
    {
      Directory.CreateDirectory(bPath+@".\Log\" + DateTime.Now.ToString("yyyyMM"));
    }

    string fileName = bPath+@".\Log\" + DateTime.Now.ToString("yyyyMM") + "\\" + DateTime.Now.ToString("yyyyMMddHH") + ".txt";
    StreamWriter sWriter = null;

    try
    {
      sWriter = new StreamWriter(fileName, true, Encoding.Default);

      sWriter.Write(info);
    }
    catch (Exception err)
    {
      Console.WriteLine("\r\n保存控制台显示的信息 出现异常!" + err.Message);
    }
    finally
    {
      //如果流不为空,关闭它
      if (sWriter != null)
        sWriter.Close();
    }
  }
}

4.在starpup.cs中注册中间件

app.UseRequestResponseLogging();

5.完成,收工

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-09-01 12:14:13  更:2021-09-01 12:16:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/15 1:20:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码