Skip to content

Update Kestrel logs to use LoggerMessage #34910

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

Merged
merged 1 commit into from
Aug 2, 2021
Merged
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
24 changes: 0 additions & 24 deletions src/Servers/Kestrel/Core/src/CoreStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -417,12 +417,6 @@
<data name="HttpErrorConnectionSpecificHeaderField" xml:space="preserve">
<value>Request headers contain connection-specific header field.</value>
</data>
<data name="AuthenticationFailed" xml:space="preserve">
<value>Failed to authenticate HTTPS connection.</value>
</data>
<data name="AuthenticationTimedOut" xml:space="preserve">
<value>Authentication of the HTTPS connection timed out.</value>
</data>
<data name="InvalidServerCertificateEku" xml:space="preserve">
<value>Certificate {thumbprint} cannot be used as an SSL server certificate. It has an Extended Key Usage extension but the usages do not include Server Authentication (OID 1.3.6.1.5.5.7.3.1).</value>
</data>
Expand Down Expand Up @@ -593,12 +587,6 @@ For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?l
<data name="GreaterThanOrEqualToZeroRequired" xml:space="preserve">
<value>A value greater than or equal to zero is required.</value>
</data>
<data name="HttpsConnectionEstablished" xml:space="preserve">
<value>Connection "{connectionId}" established using the following protocol: {protocol}</value>
</data>
<data name="Http2DefaultCiphersInsufficient" xml:space="preserve">
<value>HTTP/2 over TLS is not supported on Windows versions older than Windows 10 and Windows Server 2016 due to incompatible ciphers or missing ALPN support. Falling back to HTTP/1.1 instead.</value>
</data>
<data name="Http2NoTlsWin81" xml:space="preserve">
<value>HTTP/2 over TLS is not supported on Windows versions earlier than Windows 10 and Windows Server 2016 due to incompatible ciphers or missing ALPN support.</value>
</data>
Expand Down Expand Up @@ -626,18 +614,6 @@ For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?l
<data name="EndpointHasUnusedHttpsConfig" xml:space="preserve">
<value>The non-HTTPS endpoint {endpointName} includes HTTPS-only configuration for {keyName}.</value>
</data>
<data name="FoundCertWithPrivateKey" xml:space="preserve">
<value>Found certificate with private key and thumbprint {Thumbprint} in certificate store {StoreName}.</value>
</data>
<data name="LocatingCertWithPrivateKey" xml:space="preserve">
<value>Searching for certificate with private key and thumbprint {Thumbprint} in the certificate store.</value>
</data>
<data name="FailedToLocateCertificateFromStore" xml:space="preserve">
<value>Failure to locate certificate from store.</value>
</data>
<data name="FailedToOpenCertStore" xml:space="preserve">
<value>Failed to open certificate store {StoreName}.</value>
</data>
<data name="Http3ConnectionFaulted" xml:space="preserve">
<value>The HTTP/3 connection faulted.</value>
</data>
Expand Down
372 changes: 173 additions & 199 deletions src/Servers/Kestrel/Core/src/Internal/Infrastructure/KestrelTrace.cs

Large diffs are not rendered by default.

78 changes: 21 additions & 57 deletions src/Servers/Kestrel/Core/src/Internal/LoggerExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,77 +1,41 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Extensions.Logging;

namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
{
internal static class LoggerExtensions
internal static partial class LoggerExtensions
{
// Category: DefaultHttpsProvider
private static readonly Action<ILogger, string, string, Exception?> _locatedDevelopmentCertificate =
LoggerMessage.Define<string, string>(
LogLevel.Debug,
new EventId(0, "LocatedDevelopmentCertificate"),
"Using development certificate: {certificateSubjectName} (Thumbprint: {certificateThumbprint})");
private const string BadDeveloperCertificateStateMessage = "The ASP.NET Core developer certificate is in an invalid state. To fix this issue, run the following commands " +
"'dotnet dev-certs https --clean' and 'dotnet dev-certs https' to remove all existing ASP.NET Core development certificates and create a new untrusted developer certificate. " +
"On macOS or Windows, use 'dotnet dev-certs https --trust' to trust the new certificate.";

private static readonly Action<ILogger, Exception?> _unableToLocateDevelopmentCertificate =
LoggerMessage.Define(
LogLevel.Debug,
new EventId(1, "UnableToLocateDevelopmentCertificate"),
"Unable to locate an appropriate development https certificate.");
[LoggerMessage(0, LogLevel.Debug, "Using development certificate: {certificateSubjectName} (Thumbprint: {certificateThumbprint})", EventName = "LocatedDevelopmentCertificate")]
private static partial void LocatedDevelopmentCertificate(this ILogger<KestrelServer> logger, string certificateSubjectName, string certificateThumbprint);

private static readonly Action<ILogger, string, Exception?> _failedToLocateDevelopmentCertificateFile =
LoggerMessage.Define<string>(
LogLevel.Debug,
new EventId(2, "FailedToLocateDevelopmentCertificateFile"),
"Failed to locate the development https certificate at '{certificatePath}'.");
public static void LocatedDevelopmentCertificate(this ILogger<KestrelServer> logger, X509Certificate2 certificate) => LocatedDevelopmentCertificate(logger, certificate.Subject, certificate.Thumbprint);

private static readonly Action<ILogger, string, Exception?> _failedToLoadDevelopmentCertificate =
LoggerMessage.Define<string>(
LogLevel.Debug,
new EventId(3, "FailedToLoadDevelopmentCertificate"),
"Failed to load the development https certificate at '{certificatePath}'.");
[LoggerMessage(1, LogLevel.Debug, "Unable to locate an appropriate development https certificate.", EventName = "UnableToLocateDevelopmentCertificate")]
public static partial void UnableToLocateDevelopmentCertificate(this ILogger<KestrelServer> logger);

private static readonly Action<ILogger, Exception?> _badDeveloperCertificateState =
LoggerMessage.Define(
LogLevel.Error,
new EventId(4, "BadDeveloperCertificateState"),
CoreStrings.BadDeveloperCertificateState);
[LoggerMessage(2, LogLevel.Debug, "Failed to locate the development https certificate at '{certificatePath}'.", EventName = "FailedToLocateDevelopmentCertificateFile")]
public static partial void FailedToLocateDevelopmentCertificateFile(this ILogger<KestrelServer> logger, string certificatePath);

private static readonly Action<ILogger, string, Exception?> _developerCertificateFirstRun =
LoggerMessage.Define<string>(
LogLevel.Warning,
new EventId(5, "DeveloperCertificateFirstRun"),
"{Message}");
[LoggerMessage(3, LogLevel.Debug, "Failed to load the development https certificate at '{certificatePath}'.", EventName = "FailedToLoadDevelopmentCertificate")]
public static partial void FailedToLoadDevelopmentCertificate(this ILogger<KestrelServer> logger, string certificatePath);

private static readonly Action<ILogger, string, Exception?> _failedToLoadCertificate =
LoggerMessage.Define<string>(
LogLevel.Error,
new EventId(6, "MissingOrInvalidCertificateFile"),
"The certificate file at '{CertificateFilePath}' can not be found, contains malformed data or does not contain a certificate.");
[LoggerMessage(4, LogLevel.Error, BadDeveloperCertificateStateMessage, EventName = "BadDeveloperCertificateState")]
public static partial void BadDeveloperCertificateState(this ILogger<KestrelServer> logger);

private static readonly Action<ILogger, string, Exception?> _failedToLoadCertificateKey =
LoggerMessage.Define<string>(
LogLevel.Error,
new EventId(7, "MissingOrInvalidCertificateKeyFile"),
"The certificate key file at '{CertificateKeyFilePath}' can not be found, contains malformed data or does not contain a PEM encoded key in PKCS8 format.");
[LoggerMessage(5, LogLevel.Warning, "{Message}", EventName = "DeveloperCertificateFirstRun")]
public static partial void DeveloperCertificateFirstRun(this ILogger<KestrelServer> logger, string message);

public static void LocatedDevelopmentCertificate(this ILogger<KestrelServer> logger, X509Certificate2 certificate) => _locatedDevelopmentCertificate(logger, certificate.Subject, certificate.Thumbprint, null);
[LoggerMessage(6, LogLevel.Error, "The certificate file at '{CertificateFilePath}' can not be found, contains malformed data or does not contain a certificate.", EventName = "MissingOrInvalidCertificateFile")]
public static partial void FailedToLoadCertificate(this ILogger<KestrelServer> logger, string certificateFilePath);

public static void UnableToLocateDevelopmentCertificate(this ILogger<KestrelServer> logger) => _unableToLocateDevelopmentCertificate(logger, null);

public static void FailedToLocateDevelopmentCertificateFile(this ILogger<KestrelServer> logger, string certificatePath) => _failedToLocateDevelopmentCertificateFile(logger, certificatePath, null);

public static void FailedToLoadDevelopmentCertificate(this ILogger<KestrelServer> logger, string certificatePath) => _failedToLoadDevelopmentCertificate(logger, certificatePath, null);

public static void BadDeveloperCertificateState(this ILogger<KestrelServer> logger) => _badDeveloperCertificateState(logger, null);

public static void DeveloperCertificateFirstRun(this ILogger<KestrelServer> logger, string message) => _developerCertificateFirstRun(logger, message, null);

public static void FailedToLoadCertificate(this ILogger<KestrelServer> logger, string certificatePath) => _failedToLoadCertificate(logger, certificatePath, null);

public static void FailedToLoadCertificateKey(this ILogger<KestrelServer> logger, string certificateKeyPath) => _failedToLoadCertificateKey(logger, certificateKeyPath, null);
[LoggerMessage(7, LogLevel.Error, "The certificate key file at '{CertificateKeyFilePath}' can not be found, contains malformed data or does not contain a PEM encoded key in PKCS8 format.", EventName = "MissingOrInvalidCertificateKeyFile")]
public static partial void FailedToLoadCertificateKey(this ILogger<KestrelServer> logger, string certificateKeyFilePath);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -509,81 +509,45 @@ private static bool IsWindowsVersionIncompatibleWithHttp2()
}
}

internal static class HttpsConnectionMiddlewareLoggerExtensions
internal static partial class HttpsConnectionMiddlewareLoggerExtensions
{
private static readonly Action<ILogger, Exception> _authenticationFailed =
LoggerMessage.Define(
logLevel: LogLevel.Debug,
eventId: new EventId(1, "AuthenticationFailed"),
formatString: CoreStrings.AuthenticationFailed);
[LoggerMessage(1, LogLevel.Debug, "Failed to authenticate HTTPS connection.", EventName = "AuthenticationFailed")]
public static partial void AuthenticationFailed(this ILogger<HttpsConnectionMiddleware> logger, Exception exception);

private static readonly Action<ILogger, Exception?> _authenticationTimedOut =
LoggerMessage.Define(
logLevel: LogLevel.Debug,
eventId: new EventId(2, "AuthenticationTimedOut"),
formatString: CoreStrings.AuthenticationTimedOut);
[LoggerMessage(2, LogLevel.Debug, "Authentication of the HTTPS connection timed out.", EventName = "AuthenticationTimedOut")]
public static partial void AuthenticationTimedOut(this ILogger<HttpsConnectionMiddleware> logger);

private static readonly Action<ILogger, string, SslProtocols, Exception?> _httpsConnectionEstablished =
LoggerMessage.Define<string, SslProtocols>(
logLevel: LogLevel.Debug,
eventId: new EventId(3, "HttpsConnectionEstablished"),
formatString: CoreStrings.HttpsConnectionEstablished);
[LoggerMessage(3, LogLevel.Debug, "Connection {connectionId} established using the following protocol: {protocol}", EventName = "HttpsConnectionEstablished")]
public static partial void HttpsConnectionEstablished(this ILogger<HttpsConnectionMiddleware> logger, string connectionId, SslProtocols protocol);

private static readonly Action<ILogger, Exception?> _http2DefaultCiphersInsufficient =
LoggerMessage.Define(
logLevel: LogLevel.Information,
eventId: new EventId(4, "Http2DefaultCiphersInsufficient"),
formatString: CoreStrings.Http2DefaultCiphersInsufficient);
[LoggerMessage(4, LogLevel.Information, "HTTP/2 over TLS is not supported on Windows versions older than Windows 10 and Windows Server 2016 due to incompatible ciphers or missing ALPN support. Falling back to HTTP/1.1 instead.",
EventName = "Http2DefaultCiphersInsufficient")]
public static partial void Http2DefaultCiphersInsufficient(this ILogger<HttpsConnectionMiddleware> logger);

private static readonly Action<ILogger, string, Exception?> _locatingCertWithPrivateKey =
LoggerMessage.Define<string>(
logLevel: LogLevel.Debug,
eventId: new EventId(5, "LocateCertWithPrivateKey"),
formatString: CoreStrings.LocatingCertWithPrivateKey);
[LoggerMessage(5, LogLevel.Debug, "Searching for certificate with private key and thumbprint {Thumbprint} in the certificate store.", EventName = "LocateCertWithPrivateKey")]
private static partial void LocatingCertWithPrivateKey(this ILogger<HttpsConnectionMiddleware> logger, string thumbPrint);

private static readonly Action<ILogger, string, string, Exception?> _foundCertWithPrivateKey =
LoggerMessage.Define<string, string>(
logLevel: LogLevel.Debug,
eventId: new EventId(6, "FoundCertWithPrivateKey"),
formatString: CoreStrings.FoundCertWithPrivateKey);
public static void LocatingCertWithPrivateKey(this ILogger<HttpsConnectionMiddleware> logger, X509Certificate2 certificate) => LocatingCertWithPrivateKey(logger, certificate.Thumbprint);

private static readonly Action<ILogger, Exception> _failedToFindCertificateInStore =
LoggerMessage.Define(
logLevel: LogLevel.Debug,
eventId: new EventId(7, "FailToLocateCertificate"),
formatString: CoreStrings.FailedToLocateCertificateFromStore);


private static readonly Action<ILogger, string, Exception> _failedToOpenCertificateStore =
LoggerMessage.Define<string>(
logLevel: LogLevel.Debug,
eventId: new EventId(8, "FailToOpenStore"),
formatString: CoreStrings.FailedToOpenCertStore);

public static void AuthenticationFailed(this ILogger<HttpsConnectionMiddleware> logger, Exception exception) => _authenticationFailed(logger, exception);

public static void AuthenticationTimedOut(this ILogger<HttpsConnectionMiddleware> logger) => _authenticationTimedOut(logger, null);

public static void HttpsConnectionEstablished(this ILogger<HttpsConnectionMiddleware> logger, string connectionId, SslProtocols sslProtocol) => _httpsConnectionEstablished(logger, connectionId, sslProtocol, null);

public static void Http2DefaultCiphersInsufficient(this ILogger<HttpsConnectionMiddleware> logger) => _http2DefaultCiphersInsufficient(logger, null);

public static void LocatingCertWithPrivateKey(this ILogger<HttpsConnectionMiddleware> logger, X509Certificate2 certificate) => _locatingCertWithPrivateKey(logger, certificate.Thumbprint, null);
[LoggerMessage(6, LogLevel.Debug, "Found certificate with private key and thumbprint {Thumbprint} in certificate store {StoreName}.", EventName = "FoundCertWithPrivateKey")]
public static partial void FoundCertWithPrivateKey(this ILogger<HttpsConnectionMiddleware> logger, string thumbprint, string? storeName);

public static void FoundCertWithPrivateKey(this ILogger<HttpsConnectionMiddleware> logger, X509Certificate2 certificate, StoreLocation storeLocation)
{
var storeLocationString = storeLocation == StoreLocation.LocalMachine ? nameof(StoreLocation.LocalMachine) : nameof(StoreLocation.CurrentUser);

_foundCertWithPrivateKey(logger, certificate.Thumbprint, storeLocationString, null);
FoundCertWithPrivateKey(logger, certificate.Thumbprint, storeLocationString);
}

public static void FailedToFindCertificateInStore(this ILogger<HttpsConnectionMiddleware> logger, Exception exception) => _failedToFindCertificateInStore(logger, exception);
[LoggerMessage(7, LogLevel.Debug, "Failure to locate certificate from store.", EventName = "FailToLocateCertificate")]
public static partial void FailedToFindCertificateInStore(this ILogger<HttpsConnectionMiddleware> logger, Exception exception);

[LoggerMessage(8, LogLevel.Debug, "Failed to open certificate store {StoreName}.", EventName = "FailToOpenStore")]
public static partial void FailedToOpenStore(this ILogger<HttpsConnectionMiddleware> logger, string? storeName, Exception exception);

public static void FailedToOpenStore(this ILogger<HttpsConnectionMiddleware> logger, StoreLocation storeLocation, Exception exception)
{
var storeLocationString = storeLocation == StoreLocation.LocalMachine ? nameof(StoreLocation.LocalMachine) : nameof(StoreLocation.CurrentUser);

_failedToOpenCertificateStore(logger, storeLocationString, exception);
FailedToOpenStore(logger, storeLocationString, exception);
}
}
}
Loading