net core 请求日志[中间件方式]

核心问题:   .net Core自定义中间件中读取Request.Body和Response.Body的内容

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


/// <summary>
/// 扩展中间件
/// </summary>
public static class ErrorHandlingMiddlewareExtensions
{
    public static IApplicationBuilder UseRequestResponseLogging(this IApplicationBuilder app)
    {
        return app.UseMiddleware<ErrorHandlingMiddleware>();
    }
}

public class ErrorHandlingMiddleware
{
    private readonly RequestDelegate _next;
    private SortedDictionary<string, object> _data;
    private Stopwatch _stopwatch;

    public ErrorHandlingMiddleware(RequestDelegate next)
    {
        _next = next;
        _stopwatch = new Stopwatch();
    }

    public async Task Invoke(HttpContext context)
    {
        _stopwatch.Restart();
        _data = new SortedDictionary<string, object>();

        //启用读取request
        context.Request.EnableBuffering();
        var request = context.Request;
        var response = context.Response;

        #region 存档request
        _data.Add("request.url", request.Path.ToString());
        _data.Add("request.headers", request.Headers.ToDictionary(x => x.Key, v => string.Join(";", v.Value.ToList())));
        _data.Add("request.method", request.Method);
        _data.Add("request.executeStartTime", DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));

        if (request.Method.ToLower().Equals("post"))
        {
            //请求body
            using var ms1 = new MemoryStream();
            await request.Body.CopyToAsync(ms1);
            var s1 = ms1.ToArray();
            var requestBody = Encoding.UTF8.GetString(s1); //把body赋值给bodyStr
            _data.Add("request.body", requestBody);
            request.Body.Position = 0;
        }
        else if (request.Method.ToLower().Equals("get"))
        {
            _data.Add("request.body", request.QueryString.Value);
        }
        var responseOriginalBody = response.Body;
        using var memStream = new MemoryStream();
        response.Body = memStream; 
        #endregion

        // 执行其他中间件
        await _next(context);

        #region 存档response
        //处理执行其他中间件后的ResponseBody
        memStream.Position = 0;
        var responseReader = new StreamReader(memStream);
        var responseBody = await responseReader.ReadToEndAsync();
        memStream.Position = 0;
        await memStream.CopyToAsync(responseOriginalBody);
        _data.Add("response.body", responseBody);
        _data.Add("response.executeEndTime", DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));

        #endregion


        // 响应完成记录时间和存入日志
        context.Response.OnCompleted(() =>
        {
            _stopwatch.Stop();
            _data.Add("elaspedTime", _stopwatch.ElapsedMilliseconds + "ms");
            var json = JsonConvert.SerializeObject(_data);
            //_logger.Debug(json, "api", request.Method.ToUpper());
            return Task.CompletedTask;
        });

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值