События
Чемпионат мира Power BI DataViz
14 февр., 16 - 31 мар., 16
С 4 шансами войти, вы можете выиграть пакет конференции и сделать его в LIVE Grand Finale в Лас-Вегасе
ПодробнееЭтот браузер больше не поддерживается.
Выполните обновление до Microsoft Edge, чтобы воспользоваться новейшими функциями, обновлениями для системы безопасности и технической поддержкой.
Примечание
Это не последняя версия этой статьи. В текущем выпуске см . версию .NET 9 этой статьи.
Предупреждение
Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. В текущем выпуске см . версию .NET 9 этой статьи.
Важно!
Эта информация относится к предварительному выпуску продукта, который может быть существенно изменен до его коммерческого выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
В текущем выпуске см . версию .NET 9 этой статьи.
Ведение журнала HTTP — это ПО промежуточного слоя, которое регистрирует сведения о входящих HTTP-запросах и ответах HTTP. Ведение журнала HTTP предоставляет журналы со следующими сведениями:
Ведение журнала HTTP может:
Ведение журнала HTTP может снизить производительность приложения, особенно при ведении журналов запросов и ответов. При выборе регистрируемых полей учитывайте возможное влияние на производительность. Проверьте влияние выбранных свойств ведения журнала на производительность.
Предупреждение
Ведение журнала HTTP может потенциально ведения журнала личных сведений (PII). Примите во внимание возможные риски и не записывайте конфиденциальную информацию.
Ведение журнала HTTP включено путем вызова AddHttpLogging и UseHttpLogging, как показано в следующем примере:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(o => { });
var app = builder.Build();
app.UseHttpLogging();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.MapGet("/", () => "Hello World!");
app.Run();
Пустая лямбда в предыдущем примере вызова AddHttpLogging
добавляет ПО промежуточного слоя с конфигурацией по умолчанию. По умолчанию протоколирование HTTP регистрирует общие свойства, такие как путь, код состояния и заголовки для запросов и ответов.
Добавьте следующую строку в файл appsettings.Development.json
на уровне "LogLevel": {
, чтобы отображались журналы HTTP:
"Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information"
При настройке по умолчанию запрос и ответ регистрируются как пара сообщений, аналогичных следующему примеру:
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[1]
Request:
Protocol: HTTP/2
Method: GET
Scheme: https
PathBase:
Path: /
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Host: localhost:52941
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 Edg/118.0.2088.61
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: [Redacted]
sec-ch-ua: [Redacted]
sec-ch-ua-mobile: [Redacted]
sec-ch-ua-platform: [Redacted]
sec-fetch-site: [Redacted]
sec-fetch-mode: [Redacted]
sec-fetch-user: [Redacted]
sec-fetch-dest: [Redacted]
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[2]
Response:
StatusCode: 200
Content-Type: text/plain; charset=utf-8
Date: Tue, 24 Oct 2023 02:03:53 GMT
Server: Kestrel
Чтобы настроить глобальные параметры ПО промежуточного слоя ведения журнала HTTP, вызовите AddHttpLogging его Program.cs
, используя лямбда-файл для настройки HttpLoggingOptions.
using Microsoft.AspNetCore.HttpLogging;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.All;
logging.RequestHeaders.Add("sec-ch-ua");
logging.ResponseHeaders.Add("MyResponseHeader");
logging.MediaTypeOptions.AddText("application/javascript");
logging.RequestBodyLogLimit = 4096;
logging.ResponseBodyLogLimit = 4096;
logging.CombineLogs = true;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseHttpLogging();
app.Use(async (context, next) =>
{
context.Response.Headers["MyResponseHeader"] =
new string[] { "My Response Header Value" };
await next();
});
app.MapGet("/", () => "Hello World!");
app.Run();
Примечание
В предыдущем примере и следующих примерах UseHttpLogging
вызывается после UseStaticFiles
этого, поэтому ведение журнала HTTP не включено для статических файлов. Чтобы включить ведение журнала HTTP статического файла, вызовите перед UseStaticFiles
вызовомUseHttpLogging
.
HttpLoggingOptions.LoggingFields
— это флаг перечисления, который позволяет настроить определенные регистрируемые части запроса и ответа. HttpLoggingOptions.LoggingFields
по умолчанию использует RequestPropertiesAndHeaders | ResponsePropertiesAndHeaders.
RequestHeaders и ResponseHeaders представляют собой наборы заголовков HTTP, которые регистрируются. Значения заголовков регистрируются только для имен заголовков, которые находятся в этих коллекциях. Следующий код добавляется sec-ch-ua
в RequestHeadersжурнал, поэтому значение заголовка sec-ch-ua
регистрируется. И он добавляется MyResponseHeader
в ResponseHeadersжурнал, поэтому значение заголовка MyResponseHeader
регистрируется. Если эти строки удалены, значения этих заголовков являются [Redacted]
.
using Microsoft.AspNetCore.HttpLogging;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.All;
logging.RequestHeaders.Add("sec-ch-ua");
logging.ResponseHeaders.Add("MyResponseHeader");
logging.MediaTypeOptions.AddText("application/javascript");
logging.RequestBodyLogLimit = 4096;
logging.ResponseBodyLogLimit = 4096;
logging.CombineLogs = true;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseHttpLogging();
app.Use(async (context, next) =>
{
context.Response.Headers["MyResponseHeader"] =
new string[] { "My Response Header Value" };
await next();
});
app.MapGet("/", () => "Hello World!");
app.Run();
MediaTypeOptions предоставляет конфигурацию для выбора кодировки, используемой для конкретного типа носителя.
using Microsoft.AspNetCore.HttpLogging;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.All;
logging.RequestHeaders.Add("sec-ch-ua");
logging.ResponseHeaders.Add("MyResponseHeader");
logging.MediaTypeOptions.AddText("application/javascript");
logging.RequestBodyLogLimit = 4096;
logging.ResponseBodyLogLimit = 4096;
logging.CombineLogs = true;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseHttpLogging();
app.Use(async (context, next) =>
{
context.Response.Headers["MyResponseHeader"] =
new string[] { "My Response Header Value" };
await next();
});
app.MapGet("/", () => "Hello World!");
app.Run();
Этот подход также можно использовать для включения ведения журнала для данных, которые не регистрируются по умолчанию (например, данные формы, которые могут иметь тип носителя, application/x-www-form-urlencoded
например или multipart/form-data
).
using Microsoft.AspNetCore.HttpLogging;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.All;
logging.RequestHeaders.Add("sec-ch-ua");
logging.ResponseHeaders.Add("MyResponseHeader");
logging.MediaTypeOptions.AddText("application/javascript");
logging.RequestBodyLogLimit = 4096;
logging.ResponseBodyLogLimit = 4096;
logging.CombineLogs = true;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseHttpLogging();
app.Use(async (context, next) =>
{
context.Response.Headers["MyResponseHeader"] =
new string[] { "My Response Header Value" };
await next();
});
app.MapGet("/", () => "Hello World!");
app.Run();
Параметр CombineLogs настройки true
ПО промежуточного слоя для консолидации всех включенных журналов запроса и ответа в один журнал в конце. К ним относятся запрос, текст запроса, ответ, текст ответа и длительность.
using Microsoft.AspNetCore.HttpLogging;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.All;
logging.RequestHeaders.Add("sec-ch-ua");
logging.ResponseHeaders.Add("MyResponseHeader");
logging.MediaTypeOptions.AddText("application/javascript");
logging.RequestBodyLogLimit = 4096;
logging.ResponseBodyLogLimit = 4096;
logging.CombineLogs = true;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseHttpLogging();
app.Use(async (context, next) =>
{
context.Response.Headers["MyResponseHeader"] =
new string[] { "My Response Header Value" };
await next();
});
app.MapGet("/", () => "Hello World!");
app.Run();
Для конфигурации для конкретной конечной точки в минимальных приложениях WithHttpLogging API доступен метод расширения. В следующем примере показано, как настроить ведение журнала HTTP для одной конечной точки:
app.MapGet("/response", () => "Hello World! (logging response)")
.WithHttpLogging(HttpLoggingFields.ResponsePropertiesAndHeaders);
Для конфигурации для конкретной конечной точки в приложениях, использующих контроллеры, [HttpLogging]
атрибут доступен. Атрибут также можно использовать в минимальных приложениях API, как показано в следующем примере:
app.MapGet("/duration", [HttpLogging(loggingFields: HttpLoggingFields.Duration)]
() => "Hello World! (logging duration)");
IHttpLoggingInterceptor — это интерфейс для службы, которая может быть реализована для обработки запросов и обратных вызовов для каждого ответа для настройки сведений, которые регистрируются в журнале. Все параметры журнала, относящиеся к конечной точке, применяются сначала и затем можно переопределить в этих обратных вызовах. Реализация может:
IHttpLoggingInterceptor
Регистрация реализации путем вызова AddHttpLoggingInterceptor<T>
Program.cs
. Если зарегистрировано несколько IHttpLoggingInterceptor
экземпляров, они выполняются в порядке, зарегистрированном.
В следующем примере показано, как зарегистрировать реализацию IHttpLoggingInterceptor
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.Duration;
});
builder.Services.AddHttpLoggingInterceptor<SampleHttpLoggingInterceptor>();
В следующем примере показана IHttpLoggingInterceptor
реализация:
using Microsoft.AspNetCore.HttpLogging;
namespace HttpLoggingSample;
internal sealed class SampleHttpLoggingInterceptor : IHttpLoggingInterceptor
{
public ValueTask OnRequestAsync(HttpLoggingInterceptorContext logContext)
{
if (logContext.HttpContext.Request.Method == "POST")
{
// Don't log anything if the request is a POST.
logContext.LoggingFields = HttpLoggingFields.None;
}
// Don't enrich if we're not going to log any part of the request.
if (!logContext.IsAnyEnabled(HttpLoggingFields.Request))
{
return default;
}
if (logContext.TryDisable(HttpLoggingFields.RequestPath))
{
RedactPath(logContext);
}
if (logContext.TryDisable(HttpLoggingFields.RequestHeaders))
{
RedactRequestHeaders(logContext);
}
EnrichRequest(logContext);
return default;
}
public ValueTask OnResponseAsync(HttpLoggingInterceptorContext logContext)
{
// Don't enrich if we're not going to log any part of the response
if (!logContext.IsAnyEnabled(HttpLoggingFields.Response))
{
return default;
}
if (logContext.TryDisable(HttpLoggingFields.ResponseHeaders))
{
RedactResponseHeaders(logContext);
}
EnrichResponse(logContext);
return default;
}
private void RedactPath(HttpLoggingInterceptorContext logContext)
{
logContext.AddParameter(nameof(logContext.HttpContext.Request.Path), "RedactedPath");
}
private void RedactRequestHeaders(HttpLoggingInterceptorContext logContext)
{
foreach (var header in logContext.HttpContext.Request.Headers)
{
logContext.AddParameter(header.Key, "RedactedHeader");
}
}
private void EnrichRequest(HttpLoggingInterceptorContext logContext)
{
logContext.AddParameter("RequestEnrichment", "Stuff");
}
private void RedactResponseHeaders(HttpLoggingInterceptorContext logContext)
{
foreach (var header in logContext.HttpContext.Response.Headers)
{
logContext.AddParameter(header.Key, "RedactedHeader");
}
}
private void EnrichResponse(HttpLoggingInterceptorContext logContext)
{
logContext.AddParameter("ResponseEnrichment", "Stuff");
}
}
При использовании этого перехватчика запрос POST не создает журналы, даже если для журнала HTTP настроено ведение журнала HttpLoggingFields.All
. Запрос GET создает журналы, аналогичные следующему примеру:
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[1]
Request:
Path: RedactedPath
Accept: RedactedHeader
Host: RedactedHeader
User-Agent: RedactedHeader
Accept-Encoding: RedactedHeader
Accept-Language: RedactedHeader
Upgrade-Insecure-Requests: RedactedHeader
sec-ch-ua: RedactedHeader
sec-ch-ua-mobile: RedactedHeader
sec-ch-ua-platform: RedactedHeader
sec-fetch-site: RedactedHeader
sec-fetch-mode: RedactedHeader
sec-fetch-user: RedactedHeader
sec-fetch-dest: RedactedHeader
RequestEnrichment: Stuff
Protocol: HTTP/2
Method: GET
Scheme: https
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[2]
Response:
Content-Type: RedactedHeader
MyResponseHeader: RedactedHeader
ResponseEnrichment: Stuff
StatusCode: 200
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[4]
ResponseBody: Hello World!
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[8]
Duration: 2.2778ms
В следующем списке показано порядок приоритета для конфигурации ведения журнала:
[HttpLogging]
или WithHttpLogging метода расширения переопределяет глобальную конфигурацию.IHttpLoggingInterceptor
вызывается с результатами и может дополнительно изменять конфигурацию для каждого запроса.Ведение журнала HTTP реализуется с помощью ПО промежуточного слоя, которое регистрирует сведения о входящих HTTP-запросах и ответах. Ведение журнала HTTP предоставляет журналы со следующими сведениями:
Ведение журнала HTTP можно использовать в нескольких сценариях:
Ведение журнала HTTP может снизить производительность приложения, особенно при записи текста запроса и ответа. При выборе регистрируемых полей учитывайте возможное влияние на производительность. Проверьте влияние выбранных свойств ведения журнала на производительность.
Предупреждение
В ходе ведения журнала HTTP могут записываться личные сведения. Примите во внимание возможные риски и не записывайте конфиденциальную информацию.
Ведение журнала HTTP включается с использованием UseHttpLogging для добавления соответствующего ПО промежуточного слоя.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseHttpLogging();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.MapGet("/", () => "Hello World!");
app.Run();
По умолчанию в ходе ведения журнала HTTP в журнал записываются общие свойства, такие как путь, код состояния и заголовки для запросов и ответов. Добавьте следующую строку в файл appsettings.Development.json
на уровне "LogLevel": {
, чтобы отображались журналы HTTP:
"Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information"
Выходные данные записываются в журнал как одно сообщение в LogLevel.Information
.
Чтобы настроить ПО промежуточного слоя для ведения журнала HTTP, вызовите AddHttpLogging в Program.cs
.
using Microsoft.AspNetCore.HttpLogging;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.All;
logging.RequestHeaders.Add("sec-ch-ua");
logging.ResponseHeaders.Add("MyResponseHeader");
logging.MediaTypeOptions.AddText("application/javascript");
logging.RequestBodyLogLimit = 4096;
logging.ResponseBodyLogLimit = 4096;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseHttpLogging();
app.Use(async (context, next) =>
{
context.Response.Headers["MyResponseHeader"] =
new string[] { "My Response Header Value" };
await next();
});
app.MapGet("/", () => "Hello World!");
app.Run();
Примечание
В предыдущем примере и следующих примерах UseHttpLogging
вызывается после UseStaticFiles
этого, поэтому ведение журнала HTTP не включено для статического файла. Чтобы включить ведение журнала HTTP статического файла, вызовите перед UseStaticFiles
вызовомUseHttpLogging
.
HttpLoggingOptions.LoggingFields
— это флаг перечисления, который позволяет настроить определенные регистрируемые части запроса и ответа. HttpLoggingOptions.LoggingFields
по умолчанию использует RequestPropertiesAndHeaders | ResponsePropertiesAndHeaders.
Headers — это набор заголовков HTTP-запросов, которые разрешено регистрировать. Значения заголовков регистрируются только для имен заголовков в этой коллекции. Следующий код регистрирует заголовок "sec-ch-ua"
запроса. Если удалить logging.RequestHeaders.Add("sec-ch-ua");
, значение заголовка запроса "sec-ch-ua"
исключается из записи. Следующий выделенный код вызывает HttpLoggingOptions.RequestHeaders
и HttpLoggingOptions.ResponseHeaders
:
using Microsoft.AspNetCore.HttpLogging;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.All;
logging.RequestHeaders.Add("sec-ch-ua");
logging.ResponseHeaders.Add("MyResponseHeader");
logging.MediaTypeOptions.AddText("application/javascript");
logging.RequestBodyLogLimit = 4096;
logging.ResponseBodyLogLimit = 4096;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseHttpLogging();
app.Use(async (context, next) =>
{
context.Response.Headers["MyResponseHeader"] =
new string[] { "My Response Header Value" };
await next();
});
app.MapGet("/", () => "Hello World!");
app.Run();
MediaTypeOptions предоставляет конфигурацию для выбора кодировки, используемой для конкретного типа носителя.
using Microsoft.AspNetCore.HttpLogging;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.All;
logging.RequestHeaders.Add("sec-ch-ua");
logging.ResponseHeaders.Add("MyResponseHeader");
logging.MediaTypeOptions.AddText("application/javascript");
logging.RequestBodyLogLimit = 4096;
logging.ResponseBodyLogLimit = 4096;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseHttpLogging();
app.Use(async (context, next) =>
{
context.Response.Headers["MyResponseHeader"] =
new string[] { "My Response Header Value" };
await next();
});
app.MapGet("/", () => "Hello World!");
app.Run();
Этот подход также можно использовать для включения ведения журнала для данных, которые не регистрируются по умолчанию. Например, данные формы, которые могут иметь тип носителя, например application/x-www-form-urlencoded
или multipart/form-data
.
using Microsoft.AspNetCore.HttpLogging;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.All;
logging.RequestHeaders.Add("sec-ch-ua");
logging.ResponseHeaders.Add("MyResponseHeader");
logging.MediaTypeOptions.AddText("application/javascript");
logging.RequestBodyLogLimit = 4096;
logging.ResponseBodyLogLimit = 4096;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseHttpLogging();
app.Use(async (context, next) =>
{
context.Response.Headers["MyResponseHeader"] =
new string[] { "My Response Header Value" };
await next();
});
app.MapGet("/", () => "Hello World!");
app.Run();
Отзыв о ASP.NET Core
ASP.NET Core — это проект с открытым исходным кодом. Выберите ссылку, чтобы оставить отзыв:
События
Чемпионат мира Power BI DataViz
14 февр., 16 - 31 мар., 16
С 4 шансами войти, вы можете выиграть пакет конференции и сделать его в LIVE Grand Finale в Лас-Вегасе
Подробнее