无需代码为 ASP.NET Framework Web 应用程序添加 HTTP 请求/响应日志记录





5.00/5 (1投票)
通过使用 IIS 模块启用对 ASP.NET Web 应用程序(或 Web 服务)的请求/响应日志记录的演练。
引言
您是否曾经遇到过 ASP.NET Web 应用程序的故障排除,并希望能够看到幕后的情况?
IIS 日志非常棒 - 它们可以指示请求是否已到达服务器、处理请求花费了多长时间、源 IP 是什么、响应状态代码是什么等等。
但它没有给您您有时需要的那一点额外的 - 例如
- 通过查询字符串或 HTTP 主体传递到应用程序的内容是什么?
- 对该特定请求的响应是什么?
但是,如果尚未将此级别的日志记录构建到 Web 应用程序中,应该如何启用它呢?
一个选项是找到源代码,添加一个日志记录框架(log4net、Serilog 等)和一堆日志记录语句,然后重新部署该应用程序。这并非总是有利、可能或可行。
另一个选项是通过使用 HTTP 模块拦截 IIS 管道中的请求/响应,而这正是本文的内容。
请记住,这仅适用于参与 IIS 管道的 Web 应用程序(阅读:.NET Framework Web 应用程序或 Web 服务)。通常情况下,.NET Core Web 应用程序不参与 IIS 管道(除非您添加了 ANCM 模块)。因此,如果您仍在 ASP.NET Framework 的世界里摸索,那么这适合您!
背景
我已经开发和使用了几年 Web 服务 - 从 SOAP 到 REST 再到 WebAPI,甚至还有一点 GraphQL.NET。我早就学会了向服务添加请求/响应日志记录。这些日志在进行故障排除时非常宝贵 - 尤其是在与第三方打交道时。他们会说他们发送了 x 并得到了 y,而在日志中快速查找可以确认(或反驳)他们的说法。日志记录产生的任何开销都由节省下来的时间来弥补,这些时间用于寻找根本不存在的问题。
当您“继承”一些没有任何日志记录的旧版应用程序,并且需要查看请求/响应的详细信息时,这也会有所帮助。
Using the Code
- 下载 RequestResponseModule.zip 并解压文件。
将 RequestResponseModule.dll 文件添加到您希望添加日志记录的 ASP.NET Web 应用程序或服务的 bin 目录中。
将这些键添加到 web.config 文件的 <appSettings>
部分(根据您的需求进行更改)
<!-- Enable/disable logging (disable when not required, you'll save some overhead) -->
<add key="requestResponseLogger.enabled" value="true" />
<!-- Required (wildcards are not supported) -->
<!-- Comma separated path values to include in the logs. -->
<!-- If the URL path contains this value, the request will be logged. -->
<add key="requestResponseLogger.path.include" value="api/customer, api/order" />
<!-- Comma separated path values to exclude from the logs -->
<!-- If the URL path contains this value, the request will not be logged. -->
<add key="requestResponseLogger.path.exclude" value="api/payment,.aspx" />
通过添加/修改 <system.webServer>
部分来注册该模块,如下所示
<system.webServer>
<modules>
<add name="RequestResponseModule" type="RequestResponseModule.Logger" />
</modules>
</system.webServer>
就是这样 - 您已准备好开始日志记录。
日志文件将在您的 Web 应用程序的根目录 (~/Logs/RequestResponse/) 中创建。
每天创建一个新文件,任何异常都将记录到 Errors.log 文件中。
注意:确保允许 Web 应用程序的服务帐户(Web 应用程序运行所依据的用户上下文 - 通常是 ASPNET 或 NETWORK SERVICE)具有足够的权限(修改)以创建日志记录目录结构和文件。
日志包含以下 JSON 格式的数据
Url
方法
TimeStamp
(yyyy-MM-dd HH:mm:ss.fff)RequestBody
ResponseBody
ProcessingTime
(hh:mm:ss.fffffff)HttpStatusCode
以下是日志文件中单个条目的示例
{"Url":"/api/customer/card/14","Method":"GET","TimeStamp":"2024-01-09 14:32:36.815",
"RequestBody":"","ResponseBody":"{\"CardHolderName\":\"LT FORD 14\",
\"Token\":\"FF3D60F8-6418-4729-AD06-BBB946462A8C\",\"ExpiryDate\":\"07/2025\",
\"IssuedDate\":\"2023-11-10T14:32:36.8151265+02:00\"}",
" ProcessingTime ":"00:00:0009941","HttpStatusCode":200}
该模块还添加了一个响应标头,以指示请求是否被标记(基于路径过滤器)进行记录
关注点
理论上,可以通过添加 用于 IIS 的 ASP.NET Core 模块,使 ASP.NET Core Web 应用程序在 IIS 管道中运行。但我还没有尝试过。
感谢 this post 中的 "mckamey" 提供的解决方案,用于访问请求主体。
我尝试了几种方法来优化日志记录性能,并选择了 SemaphoreSlim 类,以便以同步方式写入日志文件。我欢迎您提出有关如何改进此功能的建议。
将来,我想增强该模块,以允许写入用户定义或共享位置(UNC 路径)。
源代码可在 https://github.com/thurstonford/RequestResponseModule 上找到。
历史
- 2024 年 1 月 12 日:初始版本