C# 自定义日志中间件 ASP.NET Core Web API

自定义日志中间件

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


namespace FCore.TenFu.WMS.WebAPI
{
    /// <summary>
    /// 日志中间件
    /// </summary>
    public class APIRequestLogMiddleware
    {
        private readonly RequestDelegate _next;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="next"></param>
        public APIRequestLogMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            try
            {
                var logger = context.RequestServices.GetService<ILogger<APIRequestLogMiddleware>>();
                LogInfoDTO _logInfo = new LogInfoDTO();

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

                if (request.Method.ToLower().Equals("post"))
                {
                    request.EnableBuffering();
                    Stream stream = request.Body;
                    byte[] buffer = new byte[request.ContentLength.Value];
                    await 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;
                }

                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;

                    //Serilog.Log.Information(JsonConvert.SerializeObject(_logInfo));
                    if (_logInfo.Url.ToLower().Contains("/api/pda"))
                    {
                        logger.Log(LogLevel.None, $"{JsonConvert.SerializeObject(_logInfo)}");
                    }
                    Serilog.Log.Information($"{_logInfo.ToString()}");
                    await responseBody.CopyToAsync(originalBodyStream);
                }
            }
            catch (Exception ex)
            {
                Serilog.Log.Error($"请求中间键错误:{ex.Message}");
            }

        }


        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 APIRequestLogMiddlewareExtensions
    {
        public static IApplicationBuilder UseApiRequestLogging(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<APIRequestLogMiddleware>();
        }
    }

    /// <summary>
    /// 日志记录信息
    /// </summary>
    public class LogInfoDTO
    {

        public string RequestUniqueId { get; set; } = Guid.NewGuid().ToString("n");
        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 $"RequestUniqueId: {this.RequestUniqueId},\r\n" +
                   $"Url: {this.Url},\r\n" +
                   $"Headers: {headers},\r\n" +
                   $"Method: {this.Method},\r\n" +
                   $"RequestBody: {this.RequestBody},\r\n" +
                   $"ResponseBody: {this.ResponseBody},\r\n" +
                   $"ExcuteStartTime: {this.ExcuteStartTime.ToString("yyyy-MM-dd HH:mm:ss.fff")},\r\n" +
                   $"ExcuteEndTime: {this.ExcuteEndTime.ToString("yyyy-MM-dd HH:mm:ss.fff")},\r\n" +
                   $"TotalElapsed: {this.TotalElapsed}(ms)";
        }
        public int TotalElapsed
        {
            get
            {
                return ExcuteEndTime.Subtract(ExcuteStartTime).Milliseconds;
            }
        }
    }

}

注入中间件

 //注入日志记录中间键
 app.UseApiRequestLogging();

 

posted @ 2024-01-17 16:39  东方李  阅读(137)  评论(0编辑  收藏  举报