接受的答案有点奇怪:这意味着您必须记录您制作的每一段 Linq 代码。
(使用 AspNetCore DI)。
知道Microsoft.Azure.Cosmos.CosmosClient 包含HttpClient,我们可以做的第一件事就是搜索是否可以传递我们自己的HttpClient。
我们可以。例如,通过CosmosClientBuilder 并使用注入的IHttpClientFactory:
.WithHttpClientFactory(() => httpClientFactory.CreateClient("Client"))
如果您的日志过滤器配置良好,您将在控制台中看到请求/响应。
现在,我们可以在 ConfigureServices 或 .NET 6 中的 builder.Services 中将 DelegatingHandler 添加到 HttpClient 中:
services.AddTransient<NoSqlLoggingDelegatingHandler>();
services.AddHttpClient("Client")
.AddHttpMessageHandler<NoSqlLoggingDelegatingHandler>();
或者查看CosmosClient 是否可以添加我们自己的选项,当然可以(例如通过CosmosClientBuilder)。
.AddCustomHandlers(
new NoSqlLoggingDelegatingHandler(loggerFactory.CreateLogger<NoSqlLoggingDelegatingHandler>()))
这样,我们就可以拦截发送的请求和响应了:
public override async Task<ResponseMessage> SendAsync(RequestMessage request, CancellationToken cancellationToken)
{
_logger.LogInformation("Requesting {uri}.\n{query}",
request.RequestUri, await GetQueryAsync(request.Content));
ResponseMessage response = await base.SendAsync(request, cancellationToken);
_logger.LogInformation("Requested {uri} - {status}",
response.RequestMessage.RequestUri, response.StatusCode);
return response;
}
而GetQueryAsync 使用System.Text.Json 读取请求的主体流:
private static async ValueTask<string?> GetQueryAsync(Stream content)
{
string? stringContents;
// Create a StreamReader with leaveOpen = true so it doesn't close the Stream when disposed
using (StreamReader sr = new StreamReader(content, Encoding.UTF8, true, 1024, true))
{
stringContents = await sr.ReadToEndAsync();
}
content.Position = 0;
if (string.IsNullOrEmpty(stringContents))
{
return null;
}
try
{
using JsonDocument parsedJObject = JsonDocument.Parse(stringContents);
return parsedJObject.RootElement.GetProperty("query").GetString();
}
catch (KeyNotFoundException)
{
return stringContents;
}
// Not a JSON.
catch (JsonException)
{
return stringContents;
}
}
你有它。我尝试过缩短代码,例如我没有添加条件来检查日志级别是否启用,以避免做无用的工作。