| File: HttpLoggingInterceptorContext.cs | Web Access |
| Project: src\aspnetcore\src\Middleware\HttpLogging\src\Microsoft.AspNetCore.HttpLogging.csproj (Microsoft.AspNetCore.HttpLogging) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; namespace Microsoft.AspNetCore.HttpLogging; /// <summary> /// The context used for <see cref="IHttpLoggingInterceptor"/>. /// </summary> /// <remarks> /// Settings will be pre-initialized with the relevant values from <see cref="HttpLoggingOptions" /> and updated with endpoint specific /// values from <see cref="HttpLoggingAttribute"/> or /// <see cref="HttpLoggingEndpointConventionBuilderExtensions.WithHttpLogging{TBuilder}(TBuilder, HttpLoggingFields, int?, int?)" />. /// All settings can be modified per request. All settings will carry over from /// <see cref="IHttpLoggingInterceptor.OnRequestAsync(HttpLoggingInterceptorContext)"/> /// to <see cref="IHttpLoggingInterceptor.OnResponseAsync(HttpLoggingInterceptorContext)"/> except the <see cref="Parameters"/> /// which are cleared after logging the request. /// </remarks> public sealed class HttpLoggingInterceptorContext { private HttpContext? _httpContext; /// <summary> /// The request context. /// </summary> /// <remarks> /// This property should not be set by user code except for testing purposes. /// </remarks> public HttpContext HttpContext { get => _httpContext ?? throw new InvalidOperationException("HttpContext was not initialized."); // Public for 3rd party testing of interceptors. // We'd make this a required constructor/init parameter but ObjectPool requires a parameterless constructor. set => _httpContext = value ?? throw new ArgumentNullException(nameof(value)); } /// <summary> /// Gets or sets which parts of the request and response to log. /// </summary> /// <remarks> /// This is pre-populated with the value from <see cref="HttpLoggingOptions.LoggingFields"/>, /// <see cref="HttpLoggingAttribute.LoggingFields"/>, or /// <see cref="HttpLoggingEndpointConventionBuilderExtensions.WithHttpLogging{TBuilder}(TBuilder, HttpLoggingFields, int?, int?)"/>. /// </remarks> public HttpLoggingFields LoggingFields { get; set; } /// <summary> /// Gets or sets the maximum number of bytes of the request body to log. /// </summary> /// <remarks> /// This is pre-populated with the value from <see cref="HttpLoggingOptions.RequestBodyLogLimit"/>, /// <see cref="HttpLoggingAttribute.RequestBodyLogLimit"/>, or /// <see cref="HttpLoggingEndpointConventionBuilderExtensions.WithHttpLogging{TBuilder}(TBuilder, HttpLoggingFields, int?, int?)"/>. /// </remarks> public int RequestBodyLogLimit { get; set; } /// <summary> /// Gets or sets the maximum number of bytes of the response body to log. /// </summary> /// <remarks> /// This is pre-populated with the value from <see cref="HttpLoggingOptions.ResponseBodyLogLimit"/>, /// <see cref="HttpLoggingAttribute.ResponseBodyLogLimit"/>, or /// <see cref="HttpLoggingEndpointConventionBuilderExtensions.WithHttpLogging{TBuilder}(TBuilder, HttpLoggingFields, int?, int?)"/>. /// </remarks> public int ResponseBodyLogLimit { get; set; } internal long StartTimestamp { get; set; } internal TimeProvider TimeProvider { get; set; } = null!; internal List<KeyValuePair<string, object?>> InternalParameters { get; set; } = new(); /// <summary> /// Gets a list of parameters that will be logged as part of the request or response. Values specified in <see cref="LoggingFields"/> /// will be added automatically after all interceptors run. All values are cleared after logging the request. /// All other relevant settings will carry over to the response. /// </summary> /// <remarks> /// If <see cref="HttpLoggingOptions.CombineLogs"/> is enabled, the parameters will be logged as part of the combined log. /// </remarks> public IList<KeyValuePair<string, object?>> Parameters => InternalParameters; /// <summary> /// Adds data that will be logged as part of the request or response. See <see cref="Parameters"/>. /// </summary> /// <param name="key">The parameter name.</param> /// <param name="value">The parameter value.</param> public void AddParameter(string key, object? value) { InternalParameters.Add(new(key, value)); } /// <summary> /// Adds the given fields to what's currently enabled in <see cref="LoggingFields"/>. /// </summary> /// <param name="fields">Additional fields to enable.</param> public void Enable(HttpLoggingFields fields) { LoggingFields |= fields; } /// <summary> /// Checks if any of the given fields are currently enabled in <see cref="LoggingFields"/>. /// </summary> /// <param name="fields">One or more field flags to check.</param> public bool IsAnyEnabled(HttpLoggingFields fields) { return (LoggingFields & fields) != HttpLoggingFields.None; } /// <summary> /// Removes the given fields from what's currently enabled in <see cref="LoggingFields"/>. /// </summary> /// <param name="fields">Fields to disable.</param> public void Disable(HttpLoggingFields fields) { LoggingFields &= ~fields; } /// <summary> /// Disables the given fields if any are currently enabled in <see cref="LoggingFields"/>. /// </summary> /// <param name="fields">One or more field flags to disable if present.</param> /// <returns><see langword="true" /> if any of the fields were previously enabled.</returns> public bool TryDisable(HttpLoggingFields fields) { if (IsAnyEnabled(fields)) { Disable(fields); return true; } return false; } internal void Reset() { _httpContext = null; LoggingFields = HttpLoggingFields.None; RequestBodyLogLimit = 0; ResponseBodyLogLimit = 0; StartTimestamp = 0; TimeProvider = null!; // Not pooled, the logger may store a reference to this instance. InternalParameters = new(); } internal double GetDuration() { return TimeProvider.GetElapsedTime(StartTimestamp).TotalMilliseconds; } }