.NET CORE 接口请求日志的采集

 public class LogMiddleware : IMiddleware
    {
        private readonly ILogger<LogMiddleware> _logger;
        private readonly IRequestContext _requestContext;
        private static readonly List<string> ActionLog = new List<string>() {
        
         "senddiamond",
         "addPropertydiamondasync",
         "diamondpaymentorder",
         "adddiamondorder",
         "addCustomdiamondorder"
        };
        public LogMiddleware(IRequestContext requestContext, ILogger<LogMiddleware> logger)
        {
            _requestContext = requestContext;
            _logger = logger;

        }
        public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            PMSLog log = new PMSLog();
            log.StartTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ffff");
            var watch = new Stopwatch();
            watch.Start();
            context.Request.EnableBuffering();
            var requestReader = new StreamReader(context.Request.Body);
            var requestContent = requestReader.ReadToEnd();
            context.Request.Body.Position = 0;
            var bodyStream = context.Response.Body;
            var ms = new MemoryStream();
            context.Response.Body = ms;
            await next.Invoke(context);
            ms.Position = 0;
            var responseReader = new StreamReader(ms);
            log.ResponseBody = responseReader.ReadToEnd();
            ms.Position = 0;
            ms.CopyTo(bodyStream);
            watch.Stop();
            try
            {
                bool insertLog = false;
                log.ActionName = context.GetRouteData()?.Values["action"]?.ToString();
                if (!string.IsNullOrEmpty(log.ActionName))
                {
                    if (ActionLog.Contains(log.ActionName.ToLower()))
                    {
                        insertLog = true;

                    }
                }
                if (insertLog)
                {
                    log.ControllerName = context.GetRouteData().Values["controller"]?.ToString();
                    var responseTimeForCompleteRequest = watch.ElapsedMilliseconds;
                    log.EndTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ffff");
                    log.ExecuteTime = responseTimeForCompleteRequest;
                    log.RequestID = context.TraceIdentifier;
                    var tokenInfo = _requestContext.TokenInfo;
                    if (tokenInfo != null)
                    {
                        log.AccountID = tokenInfo.AccountID;
                        log.DepartmentID = tokenInfo.CurrentDepartmentID;
                        log.CompanyID = tokenInfo.CompanyID;
                        log.Email = tokenInfo.Email;
                    }
                    log.ClientIp = _requestContext.ClientIp;
                    log.CityEn = _requestContext.CityEn;
                    log.Language = _requestContext.Language;
                    log.OSVersion = _requestContext.OSVersion;
                    log.AppVersion = _requestContext.AppVersion;
                    log.Platform = _requestContext.Platform.ToString();
                    log.Header = new List<(string, object)>();
                    foreach (var item in context.Request.Headers)
                    {
                        log.Header.Add((item.Key, item.Value));
                    }
                    log.RequestBody = requestContent;
                    _logger.LogCritical("Trace {RequestID}{StartTime}{EndTime}{ExecuteTime}{AccountID}{DepartmentID}{CompanyID}{Email}{ClientIp}{CityEn}{Language}{Platform}{Header}{RequestBody}{ResponseBody}{OSVersion}{AppVersion}",
                        log.RequestID, log.StartTime, log.EndTime, log.ExecuteTime, log.AccountID, log.DepartmentID, log.CompanyID, log.Email, log.ClientIp, log.CityEn, log.Language, log.Platform, log.Header, log.RequestBody, log.ResponseBody, log.OSVersion, log.AppVersion);
     
                }

            }
            catch (Exception)
            {

            }
        }
        private Dictionary<string, string> GetDic(string str)
        {
            JObject jsonObject = JObject.Parse(str);
            IEnumerable<JToken> jTokens = jsonObject.Descendants().Where(p => p.Count() == 0);
            Dictionary<string, string> results = jTokens.Aggregate(new Dictionary<string, string>(), (properties, jToken) =>
            {
                properties.Add(jToken.Path, jToken.ToString());
                return properties;
            });
            return results;
        }
        #region Request
        private async Task<string> ReadRequestBodyAsync(HttpRequest request)
        {
            if (request.ContentLength > 0)
            {
                await EnableRewindAsync(request).ConfigureAwait(false);
                var encoding = GetRequestEncoding(request);
                return await this.ReadStreamAsync(request.Body, encoding).ConfigureAwait(false);
            }
            return null;
        }

        private Encoding GetRequestEncoding(HttpRequest request)
        {
            var requestContentType = request.ContentType;
            var requestMediaType = requestContentType == null ? default : new MediaType(requestContentType);
            var requestEncoding = requestMediaType.Encoding;
            if (requestEncoding == null)
            {
                requestEncoding = Encoding.UTF8;
            }
            return requestEncoding;
        }
        private async Task EnableRewindAsync(HttpRequest request)
        {
            if (!request.Body.CanSeek)
            {
                request.EnableBuffering();

                await request.Body.DrainAsync(CancellationToken.None);
                request.Body.Seek(0L, SeekOrigin.Begin);
            }
        }

        private async Task<string> ReadStreamAsync(Stream stream, Encoding encoding)
        {
            using (StreamReader sr = new StreamReader(stream, encoding, true, 1024, true))//这里注意Body部分不能随StreamReader一起释放
            {
                var str = await sr.ReadToEndAsync();
                stream.Seek(0, SeekOrigin.Begin);//内容读取完成后需要将当前位置初始化,否则后面的InputFormatter会无法读取
                return str;
            }
        }
        #endregion

        #region Response


        private Encoding GetEncoding(string contentType)
        {
            var mediaType = contentType == null ? default : new MediaType(contentType);
            var encoding = mediaType.Encoding;
            if (encoding == null)
            {
                encoding = Encoding.UTF8;
            }
            return encoding;
        }


        #endregion


        public class PMSLog
        {
            /// <summary>
            /// 请求开始时间
            /// </summary>
            public string StartTime { get; set; }
            /// <summary>
            /// 请求结束时间
            /// </summary>
            public string EndTime { get; set; }
            /// <summary>
            /// 执行毫秒数
            /// </summary>
            public long ExecuteTime { get; set; }
            /// <summary>
            /// 请求标识
            /// </summary>
            public string RequestID { get; set; }

            /// <summary>
            /// 控制器名称
            /// </summary>
            public string ControllerName { get; set; }

            public string AppVersion { get; set; }
            public string OSVersion { get; set; }

            /// <summary>
            /// 方法名称
            /// </summary>
            public string ActionName { get; set; }

            /// <summary>
            /// 请求头扁平化
            /// </summary>
            public List<(string, object)> Header { get; set; }


            /// <summary>
            /// 请求实体序列化
            /// </summary>
            public string RequestBody { get; set; }


            / <summary>
            / 请求实体扁平化
            / </summary>
          //  public Dictionary<string, string> Request { get; set; }
            / <summary>
            / 请求路径
            / </summary>
            //public string RequestPath { get; set; }


            /// <summary>
            /// 返回实体序列化
            /// </summary>
            public string ResponseBody { get; set; }

            /// <summary>
            /// 返回实体扁平化
            /// </summary>
            public Dictionary<string, string> Response { get; set; }
            /// <summary>
            /// PMS公司的ID
            /// </summary>
            public int CompanyID { get; set; }

            /// <summary>
            /// PMS部门的ID
            /// </summary>
            public int DepartmentID { get; set; }

            /// <summary>
            /// 公司用户id
            /// </summary>
            public int AccountID { get; set; }
            /// <summary>
            /// 客户端IP
            /// </summary>
            public string ClientIp { get; set; }

            /// <summary>
            /// 城市编号
            /// </summary>
            public string CityEn { get; set; }
            /// <summary>
            /// 平台
            /// </summary>
            public string Platform { get; set; }
            /// <summary>
            /// 语言
            /// </summary>
            public string Language { get; set; }


            /// <summary>
            /// 邮箱
            /// </summary>
            public string Email { get; set; }
        }


    }
    public static class LogExtensions
    {
        public static IApplicationBuilder UseLog(this IApplicationBuilder applicationBuilder)
        {
            return applicationBuilder.UseMiddleware<LogMiddleware>();
        }
    }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值