Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Diagnostics Middleware API review #4604

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
Microsoft.AspNetCore.Hosting.Abstractions
Microsoft.AspNetCore.Http
Microsoft.AspNetCore.Http.Abstractions
Microsoft.AspNetCore.Http.Features
Microsoft.AspNetCore.HttpLogging
Microsoft.AspNetCore.Mvc.Abstractions
Microsoft.AspNetCore.Mvc.Core
Microsoft.AspNetCore.Routing
Microsoft.Extensions.AmbientMetadata.Application
Microsoft.Extensions.Compliance.Abstractions
Microsoft.Extensions.Configuration.Abstractions
Microsoft.Extensions.Configuration.Binder
Microsoft.Extensions.DependencyInjection.Abstractions
Microsoft.Extensions.DependencyInjection.AutoActivation
Microsoft.Extensions.Diagnostics.Extra
Microsoft.Extensions.Diagnostics.ExtraAbstractions
Microsoft.Extensions.Features
Microsoft.Extensions.Logging.Abstractions
Microsoft.Extensions.ObjectPool
Microsoft.Extensions.Options
Microsoft.Extensions.Options.ConfigurationExtensions
Microsoft.Extensions.Primitives
System.Collections
System.Collections.Concurrent
System.Collections.Immutable
System.ComponentModel
System.ComponentModel.Annotations
System.Linq
System.Memory
System.Private.CoreLib
System.Private.Uri
System.Runtime
System.Runtime.CompilerServices.Unsafe
System.Runtime.InteropServices
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

namespace Microsoft.AspNetCore.Builder;

public static class RequestLatencyTelemetryApplicationBuilderExtensions
{
public static IApplicationBuilder UseRequestCheckpoint(this IApplicationBuilder builder);
public static IApplicationBuilder UseRequestLatencyTelemetry(this IApplicationBuilder builder);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

namespace Microsoft.AspNetCore.Diagnostics.Latency;

public static class RequestCheckpointConstants
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think these static classes declaring telemetry constants need to be public. I don't understand what the use-case would be. For anyone who wanted to parse the ILogger data after it was emitted or make their own implementation that emits the same values I expect they would just write these same constants into their own code rather than take a ref on this assembly.

{
public const string ElapsedTillHeaders = "elthdr";
public const string ElapsedTillFinished = "eltltf";
public const string ElapsedTillPipelineExitMiddleware = "eltexm";
public const string ElapsedResponseProcessed = "eltrspproc";
public const string ElapsedTillEntryMiddleware = "eltenm";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

using System;
using System.Runtime.CompilerServices;
using Microsoft.Shared.Data.Validation;

namespace Microsoft.AspNetCore.Diagnostics.Latency;

public class RequestLatencyTelemetryOptions
{
[TimeSpan(1000)]
public TimeSpan LatencyDataExportTimeout { get; set; }
public RequestLatencyTelemetryOptions();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

using System.Collections.Generic;
using System.Runtime.CompilerServices;

namespace Microsoft.AspNetCore.Diagnostics.Logging;

public static class HttpLoggingTagNames
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, I don't think this needs to be public.

{
public const string Duration = "Duration";
public const string Host = "Host";
public const string Method = "Method";
public const string Path = "Path";
public const string RequestHeaderPrefix = "RequestHeader.";
public const string ResponseHeaderPrefix = "ResponseHeader.";
public const string RequestBody = "RequestBody";
public const string ResponseBody = "ResponseBody";
public const string StatusCode = "StatusCode";
public static IReadOnlyList<string> DimensionNames { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Diagnostics.Enrichment;

namespace Microsoft.AspNetCore.Diagnostics.Logging;

[Experimental("EXTEXP0013", UrlFormat = "https://aka.ms/dotnet-extensions-warnings/{0}")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Experimental

public interface IHttpLogEnricher
{
void Enrich(IEnrichmentTagCollector collector, HttpContext httpContext);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

namespace Microsoft.AspNetCore.Diagnostics.Logging;

public enum IncomingPathLoggingMode
{
Formatted = 0,
Structured = 1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using Microsoft.Extensions.Compliance.Classification;
using Microsoft.Extensions.Http.Diagnostics;

namespace Microsoft.AspNetCore.Diagnostics.Logging;

[Experimental("EXTEXP0013", UrlFormat = "https://aka.ms/dotnet-extensions-warnings/{0}")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Experimental

public class LoggingRedactionOptions
{
public IncomingPathLoggingMode RequestPathLoggingMode { get; set; }
public HttpRouteParameterRedactionMode RequestPathParameterRedactionMode { get; set; }
[Required]
public IDictionary<string, DataClassification> RouteParameterDataClasses { get; set; }
[Required]
public IDictionary<string, DataClassification> RequestHeadersDataClasses { get; set; }
[Required]
public IDictionary<string, DataClassification> ResponseHeadersDataClasses { get; set; }
[Required]
public ISet<string> ExcludePathStartsWith { get; set; }
public LoggingRedactionOptions();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using Microsoft.Extensions.Compliance.Classification;

namespace Microsoft.AspNetCore.Diagnostics.Logging;

public class RequestHeadersLogEnricherOptions
{
[Required]
[Experimental("EXTEXP0003", UrlFormat = "https://aka.ms/dotnet-extensions-warnings/{0}")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Experimental

public IDictionary<string, DataClassification> HeadersDataClasses { get; set; }
public RequestHeadersLogEnricherOptions();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

using System;
using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Diagnostics.Logging;
using Microsoft.Extensions.Configuration;

namespace Microsoft.Extensions.DependencyInjection;

[Experimental("EXTEXP0013", UrlFormat = "https://aka.ms/dotnet-extensions-warnings/{0}")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Experimental

public static class HttpLoggingServiceCollectionExtensions
{
public static IServiceCollection AddHttpLoggingRedaction(this IServiceCollection services, Action<LoggingRedactionOptions>? configure = null);
public static IServiceCollection AddHttpLoggingRedaction(this IServiceCollection services, IConfigurationSection section);
public static IServiceCollection AddHttpLogEnricher<T>(this IServiceCollection services) where T : class, IHttpLogEnricher;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

using System;
using Microsoft.AspNetCore.Diagnostics.Logging;

namespace Microsoft.Extensions.DependencyInjection;

public static class RequestHeadersEnricherServiceCollectionExtensions
{
public static IServiceCollection AddRequestHeadersLogEnricher(this IServiceCollection services);
public static IServiceCollection AddRequestHeadersLogEnricher(this IServiceCollection services, Action<RequestHeadersLogEnricherOptions> configure);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

using System;
using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Diagnostics.Latency;
using Microsoft.Extensions.Configuration;

namespace Microsoft.Extensions.DependencyInjection;

public static class RequestLatencyTelemetryServiceCollectionExtensions
{
public static IServiceCollection AddRequestCheckpoint(this IServiceCollection services);
public static IServiceCollection AddRequestLatencyTelemetry(this IServiceCollection services);
public static IServiceCollection AddRequestLatencyTelemetry(this IServiceCollection services, Action<RequestLatencyTelemetryOptions> configure);
public static IServiceCollection AddRequestLatencyTelemetry(this IServiceCollection services, IConfigurationSection section);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

namespace Microsoft.AspNetCore.Builder;

/// <summary>
/// Extensions to register the request latency telemetry middleware.
/// </summary>
public static class RequestLatencyTelemetryApplicationBuilderExtensions
{
/// <summary>
/// Registers middleware for request checkpointing.
/// </summary>
/// <param name="builder">The <see cref="T:Microsoft.AspNetCore.Builder.IApplicationBuilder" />.</param>
/// <returns>The value of <paramref name="builder" />.</returns>
/// <exception cref="T:System.ArgumentNullException"><paramref name="builder" /> is <see langword="null" />.</exception>
public static IApplicationBuilder UseRequestCheckpoint(this IApplicationBuilder builder);

/// <summary>
/// Adds the request latency telemetry middleware to <see cref="T:Microsoft.AspNetCore.Builder.IApplicationBuilder" /> request execution pipeline.
/// </summary>
/// <param name="builder">The <see cref="T:Microsoft.AspNetCore.Builder.IApplicationBuilder" />.</param>
/// <returns>The value of <paramref name="builder" />.</returns>
/// <exception cref="T:System.ArgumentNullException"><paramref name="builder" /> is <see langword="null" />.</exception>
public static IApplicationBuilder UseRequestLatencyTelemetry(this IApplicationBuilder builder);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

namespace Microsoft.AspNetCore.Diagnostics.Latency;

/// <summary>
/// Project constants.
/// </summary>
public static class RequestCheckpointConstants
{
/// <summary>
/// The time elapsed before the response headers have been sent to the client.
/// </summary>
public const string ElapsedTillHeaders = "elthdr";

/// <summary>
/// The time elapsed before the response has finished being sent to the client.
/// </summary>
public const string ElapsedTillFinished = "eltltf";

/// <summary>
/// The time elapsed before hitting the <see cref="T:Microsoft.AspNetCore.Diagnostics.Latency.CapturePipelineExitMiddleware" /> middleware.
/// </summary>
public const string ElapsedTillPipelineExitMiddleware = "eltexm";

/// <summary>
/// The time elapsed before the response back to middleware pipeline.
/// </summary>
public const string ElapsedResponseProcessed = "eltrspproc";

/// <summary>
/// The time elapsed before hitting the first middleware.
/// </summary>
public const string ElapsedTillEntryMiddleware = "eltenm";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

using System;
using System.Runtime.CompilerServices;
using Microsoft.Shared.Data.Validation;

namespace Microsoft.AspNetCore.Diagnostics.Latency;

/// <summary>
/// Options to configure the request latency middleware.
/// </summary>
public class RequestLatencyTelemetryOptions
{
/// <summary>
/// Gets or sets the amount of time to wait for export of latency data.
/// </summary>
/// <value>
/// The default value is 5 seconds.
/// </value>
[TimeSpan(1000)]
public TimeSpan LatencyDataExportTimeout { get; set; }

public RequestLatencyTelemetryOptions();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

using System.Collections.Generic;
using System.Runtime.CompilerServices;

namespace Microsoft.AspNetCore.Diagnostics.Logging;

/// <summary>
/// Constants used for incoming HTTP request logging tags.
/// </summary>
public static class HttpLoggingTagNames
{
/// <summary>
/// HTTP Request duration in milliseconds.
/// </summary>
public const string Duration = "Duration";

/// <summary>
/// HTTP Host.
/// </summary>
public const string Host = "Host";

/// <summary>
/// HTTP Method.
/// </summary>
public const string Method = "Method";

/// <summary>
/// HTTP Path.
/// </summary>
public const string Path = "Path";

/// <summary>
/// HTTP Request Headers prefix.
/// </summary>
public const string RequestHeaderPrefix = "RequestHeader.";

/// <summary>
/// HTTP Response Headers prefix.
/// </summary>
public const string ResponseHeaderPrefix = "ResponseHeader.";

/// <summary>
/// HTTP Request Body.
/// </summary>
public const string RequestBody = "RequestBody";

/// <summary>
/// HTTP Response Body.
/// </summary>
public const string ResponseBody = "ResponseBody";

/// <summary>
/// HTTP Status Code.
/// </summary>
public const string StatusCode = "StatusCode";

/// <summary>
/// Gets a list of all dimension names.
/// </summary>
/// <returns>A read-only <see cref="T:System.Collections.Generic.IReadOnlyList`1" /> of all dimension names.</returns>
public static IReadOnlyList<string> DimensionNames { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Diagnostics.Enrichment;

namespace Microsoft.AspNetCore.Diagnostics.Logging;

/// <summary>
/// Interface for implementing log enrichers for incoming HTTP requests.
/// </summary>
[Experimental("EXTEXP0013", UrlFormat = "https://aka.ms/dotnet-extensions-warnings/{0}")]
public interface IHttpLogEnricher
{
/// <summary>
/// Enrich logs.
/// </summary>
/// <param name="collector">Tag collector to add tags to.</param>
/// <param name="httpContext"><see cref="T:Microsoft.AspNetCore.Http.HttpContext" /> object associated with the incoming HTTP request.</param>
void Enrich(IEnrichmentTagCollector collector, HttpContext httpContext);
}
Loading