.NET CORE之API日志收集
我们在构建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日志收集的更多相关文章
- 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 重点: 实现多级子目录的压缩, ...
- 在.NET Core中使用Exceptionless分布式日志收集框架
一.Exceptionless简介 Exceptionless 是一个开源的实时的日志收集框架,它可以应用在基于 ASP.NET,ASP.NET Core,Web Api,Web Forms,WPF, ...
- asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程
最近在学习张善友老师的NanoFabric 框架的时了解到Exceptionless : https://exceptionless.com/ !因此学习了一下这个开源框架!下面对Exceptionl ...
- Net Core免费开源分布式异常日志收集框架Exceptionless
asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程 https://www.cnblogs.com/yilezhu/p/9193723.htm ...
- 【转】asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程
最近在学习张善友老师的NanoFabric 框架的时了解到Exceptionless : https://exceptionless.com/ !因此学习了一下这个开源框架!下面对Exceptionl ...
- 一套标准的ASP.NET Core容器化应用日志收集分析方案
讲故事 关注我公众号的朋友,应该知道我写了一些云原生应用收集和分析相关的文章,其中内容大多聚焦某个具体的组件: 超级有用的TraceId,快点用起来吧! 如何利用NLog输出结构化日志,并在Kiban ...
- 微服务日志之.NET Core使用NLog通过Kafka实现日志收集
一.前言 NET Core越来越受欢迎,因为它具有在多个平台上运行的原始.NET Framework的强大功能.Kafka正迅速成为软件行业的标准消息传递技术.这篇文章简单介绍了如何使用.NET(Co ...
- 循序渐进学.Net Core Web Api开发系列【10】:使用日志
系列目录 循序渐进学.Net Core Web Api开发系列目录 本系列涉及到的源码下载地址:https://github.com/seabluescn/Blog_WebApi 一.本篇概述 本篇介 ...
- .NET Core使用NLog通过Kafka实现日志收集
微服务日志之.NET Core使用NLog通过Kafka实现日志收集 https://www.cnblogs.com/maxzhang1985/p/9522017.html 一.前言 NET Core ...
随机推荐
- Struts2学习(二)运行Action中方法的三种方式
1.运行execute()方法 一般的能够直接在action中书写execute,调用action时会自己主动运行此方法 2.配置method方法 在struts.xml中配置action时.写met ...
- (WPF)Storyboard
Storyboard是一个为其所包括的动画提供目标信息的容器. 除非动画放在Storyboard中,负责不能在XMAL中被实例化. BeginStoryboard通过将Storyboard加入到触发器 ...
- Redis java使用
直接应用redis.clients:jedis的jar包到项目中,然后直接就可以使用,具体对五种类型的数据操作方法,可以翻代码找到. 连接到 redis 服务 实例 import redis.clie ...
- 多媒体开发之---h264快速运动估计算法
#include "stdio.h"#include "stdlib.h"#include "malloc.h"#include " ...
- 关于用HOOK拦截键盘的一些问题
因为MSDN上说要这样做,所以我就这样做的,读懂MSDN是关键,下面来仔细阅读一下MSDN,看它到底是怎样描述的.阅读的时候我先给出原文,再进行自己的一些翻译或描述. 先看回调函数KeyboardPr ...
- Iterator && Iterable Collection && Map
Java集合类库将集合的接口与实现分离.同样的接口,可以有不同的实现. Java集合类的基本接口是Collection接口.而Collection接口必须实现Iterable接口. 以下图表示集合框架 ...
- c3p0+spring
1. 首先是jdbc.properties属性文件的编写,便于数据库移植: datasource.driverClassName=oracle.jdbc.driver.OracleDriverdata ...
- 在Windows上使用libcurl发起HTTP请求
curl下载地址https://curl.haxx.se/download.html 当前最新版本为7.61.0 将下载的curl-7.61.0.zip解压,得到curl-7.61.0 在目录curl ...
- 获取Android设备无线和以太网MAC地址
package com.raycloud.wolf.blogformac; import android.net.wifi.WifiManager; import android.support.v7 ...
- Android 的assets文件资源与raw文件资源读取
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/zpf8861/article/details/34504183 res/raw和assets的同 ...