.net core webapi通过中间件获取请求和响应内容
程序员文章站
2022-05-15 10:30:20
本文主要根据中间件来实现对.net core webapi中产生的请求和响应数据进行获取并存入日志文件中; 这里不详细介绍日志文件的使用。你可以自己接入NLog,log4net,Exceptionless等 创建接口记录的中间件 在startup.cs中Configure方法中使用中间件 现在请求一 ......
本文主要根据中间件来实现对.net core webapi中产生的请求和响应数据进行获取并存入日志文件中;
这里不详细介绍日志文件的使用。你可以自己接入nlog,log4net,exceptionless等
创建接口记录的中间件
using microliu.core.loggers; using microsoft.aspnetcore.builder; using microsoft.aspnetcore.http; using microsoft.aspnetcore.http.internal; using newtonsoft.json; using system; using system.collections.generic; using system.diagnostics; using system.io; using system.linq; using system.text; using system.threading.tasks; namespace ptibro.partner.api.extensions { public class requestresponseloggingmiddleware { private readonly requestdelegate _next; private readonly ilogger _logger; private sorteddictionary<string, object> _data; private stopwatch _stopwatch; public requestresponseloggingmiddleware(requestdelegate next, ilogger logger) { _next = next; _logger = logger; _stopwatch = new stopwatch(); } public async task invoke(httpcontext context) { _stopwatch.restart(); _data = new sorteddictionary<string, object>(); httprequest request = context.request; _data.add("request.url", request.path.tostring()); _data.add("request.headers", request.headers.todictionary(x => x.key, v => string.join(";", v.value.tolist()))); _data.add("request.method", request.method); _data.add("request.executestarttime", datetimeoffset.now.tostring("yyyy-mm-dd hh:mm:ss.fff")); // 获取请求body内容 if (request.method.tolower().equals("post")) { // 启用倒带功能,就可以让 request.body 可以再次读取 request.enablerewind(); stream stream = request.body; byte[] buffer = new byte[request.contentlength.value]; stream.read(buffer, 0, buffer.length); _data.add("request.body", encoding.utf8.getstring(buffer)); request.body.position = 0; } else if (request.method.tolower().equals("get")) { _data.add("request.body", request.querystring.value); } // 获取response.body内容 var originalbodystream = context.response.body; using (var responsebody = new memorystream()) { context.response.body = responsebody; await _next(context); _data.add("response.body", await getresponse(context.response)); _data.add("response.executeendtime", datetimeoffset.now.tostring("yyyy-mm-dd hh:mm:ss.fff")); await responsebody.copytoasync(originalbodystream); } // 响应完成记录时间和存入日志 context.response.oncompleted(() => { _stopwatch.stop(); _data.add("elaspedtime", _stopwatch.elapsedmilliseconds + "ms"); var json = jsonconvert.serializeobject(_data); _logger.debug(json, "api", request.method.toupper()); return task.completedtask; }); } /// <summary> /// 获取响应内容 /// </summary> /// <param name="response"></param> /// <returns></returns> public async task<string> getresponse(httpresponse response) { response.body.seek(0, seekorigin.begin); var text = await new streamreader(response.body).readtoendasync(); response.body.seek(0, seekorigin.begin); return text; } } /// <summary> /// 扩展中间件 /// </summary> public static class requestresponseloggingmiddlewareextensions { public static iapplicationbuilder userequestresponselogging(this iapplicationbuilder app) { return app.usemiddleware<requestresponseloggingmiddleware>(); } } }
在startup.cs中configure方法中使用中间件
public void configure(iapplicationbuilder app, ihostingenvironment env) { if (env.isdevelopment()) { app.usedeveloperexceptionpage(); } app.useerrorhandling();// 全局异常尽量放上面 ... app.userequestresponselogging(); ... app.useexceptionless(configuration); app.usemvc(); }
现在请求一次看一下记录的效果:我的日志存在exceptionless上,如下图
解析json,记录的数据如下:
参考地址: (我只是在此基础上进行了一些小的改善)
上一篇: 凉拌黄瓜,美味在何处?