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.完成,收工

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FlYFlOWERANDLEAF

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值