65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2024年1月11日

CPOL

3分钟阅读

viewsIcon

9393

downloadIcon

160

通过使用 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.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 日:初始版本
© . All rights reserved.