首页 > 编程语言 >C# 自定义日志中间件 ASP.NET Core Web API

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

时间:2024-01-17 16:46:25浏览次数:21  
标签:Core string 自定义 get request 中间件 using logInfo public

自定义日志中间件

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();

 

标签:Core,string,自定义,get,request,中间件,using,logInfo,public
From: https://www.cnblogs.com/nanxixi/p/17970382

相关文章

  • 自定义指令-倒计时
    1、directive/time.jsconstvueTime=(Vue)=>{Vue.directive('time',{bind(el,binding,vnode){constendDate=binding.value;//倒计时结束时间戳,毫秒lettimer=null;functionupdateCountdown(){constnow=newD......
  • C# 下载文件 (ASP.NET Core Web API )
    usingMicrosoft.AspNetCore.Mvc;usingSystem.IO;usingMicrosoft.AspNetCore.Hosting;usingMicrosoft.AspNetCore.Authorization;usingMicrosoft.Extensions.Logging;usingMicrosoft.AspNetCore.StaticFiles;usingSystem.Threading.Tasks;namespaceFCore.Saas.......
  • ASP.NET Core 中AOP(面向切面编程)的支持方式
    在ASP.NETCore中,AOP(面向切面编程)的支持可以通过以下方式实现:过滤器(Filters):ASP.NETCore提供了多种类型的过滤器:身份验证过滤器(AuthenticationFilters):用于验证用户身份。例如,[Authorize] 属性可以应用在控制器或动作方法上,确保只有经过身份验证的用户才能访问。授权......
  • .net core 中什么是中间件
    在.NETCore中,中间件(Middleware)是ASP.NETCore应用程序处理请求和响应的组件。中间件位于应用程序的请求处理管道中,它可以截获请求,执行一些逻辑,并将请求传递给下一个中间件或终止请求的执行。中间件的主要作用是实现横切关注点,处理跨请求的功能和任务,例如身份验证、异常处理......
  • Gin 控制器的继承,自定义方法
    Gin控制器的继承,自定义方法1我们想直接获取到int类型的数据怎么办/* 当我们获取Get参数时都时获取到的都是string类型,有时候我们想直接获取到int类型,我们就需要转换,如果需要转换的地方多了也会很麻烦, 那我们可以怎么办 解决办法很简单,我们可以写一个baseController来实......
  • Gin中间件
    Gin中间件1中间件简介/* Gin框架允许开发者在处理请求的过程中,加入用户自己的钩子(Hook)函数。这个钩子函数就叫中间件,中间件适合处理一些公共的业务逻辑,比如登录认证、权限校验、数据分页、记录日志、耗时统计等。*/在gin中的Default的方法中已经有两个中间件了://Defaul......
  • FlashDuty Changelog 2023-12-18 | 值班管理、服务日历、自定义操作和邮件集成
    FlashDuty:一站式告警响应平台,前往此地址免费体验!值班管理UI交互优化【个人日程】从头像下拉菜单调整到值班列表页面,快速查看个人值班日程【值班列表】支持原地预览最近一周值班情况,包括当前和下一阶段值班人【值班详情】支持日历模式与时间线模式切换,查看月度计划更方便......
  • 界面组件DevExpress ASP.NET Core v23.2 - 拥有全新的主题样式
    DevExpressASP.NETCore Controls使用强大的混合方法,结合现代企业Web开发工具所期望的所有功能。该套件通过ASP.NETRazor标记和服务器端ASP.NETCoreWebAPI的生产力和简便性,提供客户端JavaScript的性能和灵活性。ThemeBuilder工具和集成的MaterialDesign、通用主题集可以让......
  • 麒麟linux安装net8并配置netcore项目网站运行
     1.安装net8执行下面命令。从微软官方下载net8:https://dotnet.microsoft.com/zh-cn/download/dotnet/8.0https://dotnet.microsoft.com/zh-cn/download/dotnet/thank-you/sdk-8.0.101-linux-x64-binaries  然后进入linux,按照官方说明执行: mkdir-p$HOME/dotnet......
  • Asp .Net Core 系列:集成 Ocelot+Consul实现网关、服务注册、服务发现
    什么是Ocelot?Ocelot是一个开源的ASP.NETCore微服务网关,它提供了API网关所需的所有功能,如路由、认证、限流、监控等。Ocelot是一个简单、灵活且功能强大的API网关,它可以与现有的服务集成,并帮助您保护、监控和扩展您的微服务。以下是Ocelot的一些主要功能:路由管理:Ocelot允许......