zoukankan      html  css  js  c++  java
  • netcore api请求日志输出中间件

    /// <summary>
    /// 统一错误处理中间件
    /// </summary>
    public class CustomExceptionMiddleware
    {
    private readonly RequestDelegate _next;

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

    public async Task InvokeAsync(HttpContext context)
    {
    var responseBodyStream = context.Response.Body;
    try
    {
    await LogRequest(context.Request);
    //Copy a pointer to the original response body stream
    using (var ms = new MemoryStream())
    {
    context.Response.Body = ms;
    await _next(context);
    await LogResponse(context.Response, ms);
    ms.Position = 0;
    await ms.CopyToAsync(responseBodyStream);
    }
    }
    catch (Exception ex)
    {
    LogHelper.Error("Error", ex);
    await HandleExceptionAsync(context, responseBodyStream, ex).ConfigureAwait(true);
    }
    }

    private async Task HandleExceptionAsync(HttpContext context, Stream body, Exception exception)
    {
    context.Response.ContentType = "application/json";
    context.Response.StatusCode = 200;// (int)HttpStatusCode.InternalServerError;
    var data = new { code = 500, message = exception.Message };
    var result = JsonHelper.ToJson(data);
    using (var ms = new MemoryStream())
    {
    //ms.Seek(0, SeekOrigin.Begin);
    await ms.WriteAsync(Encoding.UTF8.GetBytes(result));
    ms.Seek(0, SeekOrigin.Begin);
    await ms.CopyToAsync(body);
    }
    }

    #region 日志
    private async Task<string> FormatRequest(HttpRequest request)
    {
    var body = "";

    if (request.ContentLength > 0)
    {
    if (!request.Body.CanSeek)
    {
    request.EnableBuffering();
    await request.Body.DrainAsync(CancellationToken.None);
    request.Body.Seek(0L, SeekOrigin.Begin);
    }

    var contentType = request.ContentType;
    var mediaType = contentType == null ? default(MediaType) : new MediaType(contentType);
    var encoding = mediaType.Encoding;
    if (encoding == null)
    {
    encoding = Encoding.UTF8;
    }

    using (StreamReader sr = new StreamReader(request.Body, encoding, true, 1024, true))//这里注意Body部分不能随StreamReader一起释放
    {
    body = await sr.ReadToEndAsync();
    request.Body.Seek(0, SeekOrigin.Begin);//内容读取完成后需要将当前位置初始化,否则后面的InputFormatter会无法读取
    }

    }
    return body;
    }

    private async Task LogResponse(HttpResponse response, MemoryStream ms)
    {
    ms.Position = 0;
    var body = await new StreamReader(ms).ReadToEndAsync();
    response.Body.Seek(0, SeekOrigin.Begin);//内容读取完成后需要将当前位置初始化,否则后面的InputFormatter会无法读取
    LogHelper.Info($"id:{Thread.GetCurrentProcessorId()};Code:{response.StatusCode};body:{body}");
    }

    /// <summary>
    /// 请求日志
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    private async Task LogRequest(HttpRequest request)
    {
    var method = request.Method;
    var query = "";
    if (request.Query.Count > 0)
    {
    query = request.QueryString.Value;
    }
    var form = new StringBuilder();
    if (method.Equals("post", StringComparison.OrdinalIgnoreCase) && request.HasFormContentType)
    {
    foreach (var item in request.Form)
    {
    form.Append($"{item.Key}={item.Value}&");
    }
    }
    var body = await FormatRequest(request);
    LogHelper.Info($"id:{Thread.GetCurrentProcessorId()};api:{request.Host}{request.Path};method:{method};query:{query}; form:{form.ToString()}; body:{body}");
    }
    #endregion
    }

  • 相关阅读:
    约瑟夫问题
    LCIS(最长公共上升子序列)
    Spfa求负环
    裴蜀(贝祖)定理
    Tarjan算法之简单缩点
    树形dp-二次扫描+换根
    sys.path.insert
    python学习之路(十二)
    python学习之路(十一)
    python学习之路(十)
  • 原文地址:https://www.cnblogs.com/zhuyue/p/13267242.html
Copyright © 2011-2022 走看看