我们在构建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. flex 操作xml 实现增删改查 .

    一 在介绍Flex中操作XML之前,首先简单介绍下XML中的基本术语. 元素:XML中拥有开始标签和结束标签的这一块称为“元素”    节点:把XML元素与文本结合起来统称为节点    根节点:位于整 ...

  2. Vue 基础

    1. data 数据 methods 方法 watch 监听变化 2. 模版指令(类似 angular) {{}} v-text 渲染数据 v-html html 结构 3. v-if v-show ...

  3. 简明扼要谈Spring IOC的好处

    http://a-kuei.iteye.com/blog/676524 iOC:控制反转,它是不是什么技术,它是一种设计模式.所谓控制反转就是由容器控制程序间的关系,而不是传统实现中,由编程代码直接操 ...

  4. vs2010 msvcr100.DLL 丢失!!! 用release 就可以了

  5. Robots协议应用与写法研究

  6. Spring Base

    1.在java开发领域,Spring相对于EJB来说是一种轻量级的,非侵入性的Java开发框架,曾经有两本很畅销的书<Expert one-on-one J2EE Design and Deve ...

  7. 在Java中如何编写回调函数,以及回调函数的简单应用

    import static java.lang.System.out; import static java.lang.System.err; import java.util.logging.Lev ...

  8. 记录Linux常用命令

    创建用户:useradd -m user1,-m表示同时创建用户主目录,默认会创建/home/user1目录 设置密码:passwd user1,然后就会出现设置密码的提示了 为新用户添加sudo权限 ...

  9. SWT.Shell

    import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; public class SWT_Shell ...

  10. scrollView 代理方法的实现顺序的些许区别