我们在构建WEBAPI项目时,通常需要构建一个全局的记录API 请求和返回 的功能,在WEBAPI框架下 我们通过自定义一个DelegateHandler来实现这个功能,

在.NET CORE框架下已经不存在DelegateHandler管道了,我们需要通过Middleware管道来实现。具体实现如下:

定义LoggingMiddleware

    public class GlobalApiLoggingMiddleware : IMiddleware
{
private readonly ILogger _logger; public GlobalApiLoggingMiddleware(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger("ApiLog");
}
        public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
        //在这里我们来拦截请求,收集日志
 await next.Invoke(context);
}
}

HttpContext的定义

可以看到里面的Request和Response对象 分别时 HttpRequest 和 HttpResponse,不再像在webapi框架下直接通过HttpRequestMessage、HttpResponseMessage来获取请求报文和返回报文。

这里需要花费一些技巧。

获取请求报文,

            //reuqest支持buff,否则body只能读取一次
context.Request.EnableBuffering();
//这里不要释放stream,否则后续读取request.body会报错
var reader = new StreamReader(context.Request.Body, Encoding.UTF8);
var requestStr = await reader.ReadToEndAsync();
            //var requestStr = reader.ReadToEnd(); 升级.net core 3.1后 会报 Synchronous operations are disallowed. 错误

首先类似于webapi框架下获取请求报文一样,需要先设置request buffer,这样request报文可以读取多次

其次获取报文的方式 是通过 stream获取,这里stream不要释放 不要释放 不要释放。重要的事情说三次。

获取返回报文 更加复杂一点

           Stream originalBody = context.Response.Body;

            try
{
using (var memStream = new MemoryStream())
{
context.Response.Body = memStream;
await next.Invoke(context); var request = context.Request;
var log = new ApiLogEntity()
{
Appkey = request.GetAppkey(),
ClientIp = request.GetClientRealIp(),
HttpMethod = request.Method,
Request = requestStr,
RequestId = request.GetRequestId(),
RequestUrl = request.Path.Value,
QueryString = request.QueryString.Value,
ServerIp = request.Host.Value,
StatusCode = context.Response.StatusCode
}; memStream.Position = ;
log.Response = await new StreamReader(memStream).ReadToEndAsync(); memStream.Position = ;
await memStream.CopyToAsync(originalBody); _logger.LogInformation(JsonConvert.SerializeObject(log));
}
}
finally
{
//重新给response.body赋值,用于返回
context.Response.Body = originalBody;
}

这里HttpResponse的body是不允许读取的!!所以这里的策略是 先给body赋值一个新的stream,

执行完action得到返回值后,可以读取我们自己定义的stream拿到返回报文

最后把返回值stream copy给原来的body对象,并重新赋给context.Response.Body,这里客户端可以正确返回了。

OK,结束!

.NET CORE之API日志收集的更多相关文章

  1. C#实现多级子目录Zip压缩解压实例 NET4.6下的UTC时间转换 [译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了 asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程 asp.net core异步进行新增操作并且需要判断某些字段是否重复的三种解决方案 .NET Core开发日志

    C#实现多级子目录Zip压缩解压实例 参考 https://blog.csdn.net/lki_suidongdong/article/details/20942977 重点: 实现多级子目录的压缩, ...

  2. 在.NET Core中使用Exceptionless分布式日志收集框架

    一.Exceptionless简介 Exceptionless 是一个开源的实时的日志收集框架,它可以应用在基于 ASP.NET,ASP.NET Core,Web Api,Web Forms,WPF, ...

  3. asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程

    最近在学习张善友老师的NanoFabric 框架的时了解到Exceptionless : https://exceptionless.com/ !因此学习了一下这个开源框架!下面对Exceptionl ...

  4. Net Core免费开源分布式异常日志收集框架Exceptionless

    asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程 https://www.cnblogs.com/yilezhu/p/9193723.htm ...

  5. 【转】asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程

    最近在学习张善友老师的NanoFabric 框架的时了解到Exceptionless : https://exceptionless.com/ !因此学习了一下这个开源框架!下面对Exceptionl ...

  6. 一套标准的ASP.NET Core容器化应用日志收集分析方案

    讲故事 关注我公众号的朋友,应该知道我写了一些云原生应用收集和分析相关的文章,其中内容大多聚焦某个具体的组件: 超级有用的TraceId,快点用起来吧! 如何利用NLog输出结构化日志,并在Kiban ...

  7. 微服务日志之.NET Core使用NLog通过Kafka实现日志收集

    一.前言 NET Core越来越受欢迎,因为它具有在多个平台上运行的原始.NET Framework的强大功能.Kafka正迅速成为软件行业的标准消息传递技术.这篇文章简单介绍了如何使用.NET(Co ...

  8. 循序渐进学.Net Core Web Api开发系列【10】:使用日志

    系列目录 循序渐进学.Net Core Web Api开发系列目录 本系列涉及到的源码下载地址:https://github.com/seabluescn/Blog_WebApi 一.本篇概述 本篇介 ...

  9. .NET Core使用NLog通过Kafka实现日志收集

    微服务日志之.NET Core使用NLog通过Kafka实现日志收集 https://www.cnblogs.com/maxzhang1985/p/9522017.html 一.前言 NET Core ...

随机推荐

  1. c程序设计语言第一章3

    字符数组是C语言中最常用的数组类型.下面我们通过编写一个程序,来说明字符数组以反操作字符数组的函数的用法.该程序读入一组文本行,并把最长的文水行打印出来.该算法的基本框架非常简单: while (还有 ...

  2. jQuery源代码框架思路

    開始计划时间读源代码,第一节jQuery框架阅读思路整理 (function(){ jQuery = function(){}; jQuery一些变量和函数和给jQuery对象加入一些方法和属性 ex ...

  3. ok6410[000] ubuntu1604_64bit下安装wps

    虽说Ubuntu下有自动的office工具,不过使用上体验很差.而国内最好的office软件也就是金山的wps. ------------------------------------------- ...

  4. apt仓库以及apt-get分析

    1 debian repository 参考:https://wiki.debian.org/DebianRepository 1.1 版本代号 sid,still in development,该版 ...

  5. Wordpress播客网站搭建

  6. Random 类生成随机数

    Random类 (java.util) Random类中实现的随机算法是伪随机,也就是有规则的随机.在进行随机时,随机算法的起源数字称为种子数(seed),在种子数的基础上进行一定的变换,从而产生需要 ...

  7. js与原生的交互

    一.与安卓的交互 Android与js通过WebView互相调用方法,实际上是: Android去调用JS的代码 JS去调用Android的代码 二者沟通的桥梁是WebView 对于android调用 ...

  8. Caused by: java.lang.IllegalArgumentException: Result Maps collection already contains value for com.st.mapper.UserMapper.userBaseMap

    mybatis出现此异常,可能是因为 ***Mapper.xml 文件中存在重名对象,一不小心重复启动了mybatis的逆向工程. 以为会覆盖掉以前生成的,没想到是新生成的和之前生成的重复了 解决:把 ...

  9. 一步一步学Silverlight 2系列(30):使用Transform实现更炫的效果(下)

    概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...

  10. AtCoder3857:Median Sum (Bitset优化背包&&对称性求中位数)

    Median Sum You are given N integers A1, A2, ..., AN. Consider the sums of all non-empty subsequences ...