-
Notifications
You must be signed in to change notification settings - Fork 10.3k
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
Soft enable CA1810 #33619
Soft enable CA1810 #33619
Conversation
A lot of the warnings for this rule appear from logging. Given this is going to be replaced by a source generator, this change soft enables the rule while fixing warnings that appear in non-logging code
_endpointsFound(logger, endpoints.Select(e => e.DisplayName), address, null); | ||
} | ||
} | ||
[LoggerMessage(EventId = 100, EventName = "EndpointsFound", Level = LogLevel.Debug, Message = "Found the endpoints {Endpoints} for address {Address}")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maryamariyan / @eerhardt could you have a look at this and let me know if I'm doing this correctly?
FYI @JamesNK / @davidfowl
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The previous EndpointsFound
method would check whether logging was enabled and then use LINQ to get endpoint names. I believe that is missing post your changes.
Follow the pattern you used with TemplateFailedRequiredValues?
@@ -19,6 +19,7 @@ Microsoft.AspNetCore.Http.HttpResponse</Description> | |||
<ItemGroup> | |||
<Reference Include="Microsoft.AspNetCore.Http.Features" /> | |||
<Reference Include="Microsoft.Net.Http.Headers" /> | |||
<Reference Include="Microsoft.Extensions.Logging.Abstractions" PrivateAssets="All" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this private assets?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to add a reference for the source generator. Our build complains if you add new references and I didn't want to deal with it.
@@ -809,37 +809,25 @@ private class FactoryContext | |||
public List<(ParameterExpression, Expression)> TryParseParams { get; } = new(); | |||
} | |||
|
|||
private static class Log | |||
internal static partial class Log |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why internal
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can revert it. I was fiddling around with making the source generator work.
} | ||
} | ||
[LoggerMessage(EventId = 100, EventName = "EndpointsFound", Level = LogLevel.Debug, Message = "Found the endpoints {Endpoints} for address {Address}")] | ||
public static partial void EndpointsFound(ILogger logger, object address, IEnumerable<Endpoint> endpoints); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the order of {Endpoints}
and {Address}
need to match in the string with how it is ordered in the method signature?
If not, do the names need to match? Here they differ by case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the generator looks them up by name (case insensitively).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's the dope code it generates: https://gist.github.com/pranavkm/dba57e845227045d8e3651b0d49d3418
_endpointsFound(logger, endpoints.Select(e => e.DisplayName), address, null); | ||
} | ||
} | ||
[LoggerMessage(EventId = 100, EventName = "EndpointsFound", Level = LogLevel.Debug, Message = "Found the endpoints {Endpoints} for address {Address}")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The previous EndpointsFound
method would check whether logging was enabled and then use LINQ to get endpoint names. I believe that is missing post your changes.
Follow the pattern you used with TemplateFailedRequiredValues?
} | ||
} | ||
[LoggerMessage(EventId = 100, EventName = "EndpointsFound", Level = LogLevel.Debug, Message = "Found the endpoints {Endpoints} for address {Address}")] | ||
public static partial void EndpointsFound(ILogger logger, object address, IEnumerable<Endpoint> endpoints); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to check.
Message = "Failed to process the template {Template} for {Endpoint}. " + | ||
"A required route value is missing, or has a different value from the required default values. " + | ||
"Supplied ambient values {AmbientValues} and {Values} with default values {Defaults}")] | ||
public static partial void TemplateFailedRequiredValues(ILogger logger, string template, string endpoint, string ambientValues, string values, string defaults); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do partial methods on log generators always have to be public? Looks like this would only be called from the overload so it could be private.
Message = "Failed to process the template {Template} for {Endpoint}. " + | ||
"The failure occurred while expanding the template with values {Values} " + | ||
"This is usually due to a missing or empty value in a complex segment")] | ||
public static partial void TemplateFailedExpansion(ILogger logger, string template, string endpoint, string values); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is skip log level check added yet? Can add it to attribute when method is called from an overload that already checks for IsEnabled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not yet but close: dotnet/runtime#54305
Add comments to attributes where it should be added once supported.
@@ -95,7 +95,7 @@ | |||
<MicrosoftExtensionsHostingAbstractionsVersion>6.0.0-preview.6.21314.2</MicrosoftExtensionsHostingAbstractionsVersion> | |||
<MicrosoftExtensionsHostingVersion>6.0.0-preview.6.21314.2</MicrosoftExtensionsHostingVersion> | |||
<MicrosoftExtensionsHttpVersion>6.0.0-preview.6.21314.2</MicrosoftExtensionsHttpVersion> | |||
<MicrosoftExtensionsLoggingAbstractionsVersion>6.0.0-preview.6.21314.2</MicrosoftExtensionsLoggingAbstractionsVersion> | |||
<MicrosoftExtensionsLoggingAbstractionsVersion>6.0.0-preview.7.21316.3</MicrosoftExtensionsLoggingAbstractionsVersion> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will simply cause conflicts or be overwritten the next time we get versions from dotnet/runtime. Suggest retrying after #33560 is in.
@@ -163,21 +163,16 @@ protected override void HandleException(Exception exception) | |||
|
|||
private static class Log | |||
{ | |||
private static readonly Action<ILogger, string, Exception> _unhandledExceptionRenderingComponent; | |||
private static readonly Action<ILogger, string, Exception> _unhandledExceptionRenderingComponent = LoggerMessage.Define<string>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or maybe something like below?
[LoggerMessage(EventId = EventIds.UnhandledExceptionRenderingComponent, Level = LogLevel.Critical, Message = "Unhandled exception rendering component: {Message}")]
public static partial void UnhandledExceptionRenderingComponent(ILogger logger, string message);
{ | ||
_listeningOnAddress(logger, address, null); | ||
} | ||
[LoggerMessage(EventId = LoggerEventIds.ServerListeningOnAddresses, EventName = "ServerListeningOnAddresses", Level = LogLevel.Information, Message = "Now listening on: {address}")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note, when you don't specify EventName, it would take the method name as the event name for the log method.
Instead of setting EventName, I would rename this method from ListeningOnAddress
to ServerListeningOnAddresses
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We want to be explicit about the event name. It is easy for someone to unknowingly change the event name by renaming a method. That would introduce a breaking change.
That is the reason why we have strings today instead of using nameof(MethodName)
.
{ | ||
_samesiteNotSecure(logger, name, null); | ||
} | ||
[LoggerMessage(EventId = 1, EventName = "SameSiteNotSecure", Level = LogLevel.Warning, Message = "The cookie '{name}' has set 'SameSite=None' and must also set 'Secure'.")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When you don't set EventName explicitly the generator uses the log method's name as the event name. So you if you prefer, just remove , EventName = "SameSiteNotSecure"
and rename SameSiteCookieNotSecure(..)
to SameSiteNotSecure
.
{ | ||
_failedToReadStackFrameInfo(logger, exception); | ||
} | ||
[LoggerMessage(EventId = 0, EventName = "FailedToReadStackTraceInfo", Level = LogLevel.Debug, Message = "Failed to read stack trace information for exception.")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[LoggerMessage(EventId = 0, EventName = "FailedToReadStackTraceInfo", Level = LogLevel.Debug, Message = "Failed to read stack trace information for exception.")] | |
[LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = "Failed to read stack trace information for exception.")] |
{ | ||
_writeCancelled(logger, ex); | ||
} | ||
[LoggerMessage(EventId = 14, EventName = "WriteCancelled", Level = LogLevel.Debug, Message = "The file transmission was cancelled")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[LoggerMessage(EventId = 14, EventName = "WriteCancelled", Level = LogLevel.Debug, Message = "The file transmission was cancelled")] | |
[LoggerMessage(EventId = 14, Level = LogLevel.Debug, Message = "The file transmission was cancelled")] |
LogLevel.Information, | ||
new EventId(6, "OriginNotAllowed"), | ||
"Request origin {origin} does not have permission to access the resource."); | ||
[LoggerMessage(EventId = 7, EventName = "AccessControlMethodNotAllowed", Level = LogLevel.Information, Message = "Request method {accessControlRequestMethod} not allowed in CORS policy.")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[LoggerMessage(EventId = 7, EventName = "AccessControlMethodNotAllowed", Level = LogLevel.Information, Message = "Request method {accessControlRequestMethod} not allowed in CORS policy.")] | |
[LoggerMessage(EventId = 7, Level = LogLevel.Information, Message = "Request method {accessControlRequestMethod} not allowed in CORS policy.")] |
LogLevel.Information, | ||
new EventId(7, "AccessControlMethodNotAllowed"), | ||
"Request method {accessControlRequestMethod} not allowed in CORS policy."); | ||
[LoggerMessage(EventId = 8, EventName = "RequestHeaderNotAllowed", Level = LogLevel.Information, Message = "Request header '{requestHeader}' not allowed in CORS policy.")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[LoggerMessage(EventId = 8, EventName = "RequestHeaderNotAllowed", Level = LogLevel.Information, Message = "Request header '{requestHeader}' not allowed in CORS policy.")] | |
[LoggerMessage(EventId = 8, Level = LogLevel.Information, Message = "Request header '{requestHeader}' not allowed in CORS policy.")] |
LogLevel.Information, | ||
new EventId(8, "RequestHeaderNotAllowed"), | ||
"Request header '{requestHeader}' not allowed in CORS policy."); | ||
[LoggerMessage(EventId = 9, EventName = "FailedToSetCorsHeaders", Level = LogLevel.Warning, Message = "Failed to apply CORS Response headers.")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[LoggerMessage(EventId = 9, EventName = "FailedToSetCorsHeaders", Level = LogLevel.Warning, Message = "Failed to apply CORS Response headers.")] | |
[LoggerMessage(EventId = 9, Level = LogLevel.Warning, Message = "Failed to apply CORS Response headers.")] |
LogLevel.Warning, | ||
new EventId(9, "FailedToSetCorsHeaders"), | ||
"Failed to apply CORS Response headers."); | ||
[LoggerMessage(EventId = 10, EventName = "NoCorsPolicyFound", Level = LogLevel.Information, Message = "No CORS policy found for the specified request.")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[LoggerMessage(EventId = 10, EventName = "NoCorsPolicyFound", Level = LogLevel.Information, Message = "No CORS policy found for the specified request.")] | |
[LoggerMessage(EventId = 10, Level = LogLevel.Information, Message = "No CORS policy found for the specified request.")] |
{ | ||
_isNotPreflightRequest(logger, null); | ||
} | ||
[LoggerMessage(EventId = 12, EventName = "IsNotPreflightRequest", Level = LogLevel.Debug, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[LoggerMessage(EventId = 12, EventName = "IsNotPreflightRequest", Level = LogLevel.Debug, | |
[LoggerMessage(EventId = 12, Level = LogLevel.Debug, |
{ | ||
_requestBodyIOException(GetLogger(httpContext), exception); | ||
} | ||
[LoggerMessage(EventId = 1, EventName = "RequestBodyIOException", Level = LogLevel.Debug, Message = "Reading the request body failed with an IOException.")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[LoggerMessage(EventId = 1, EventName = "RequestBodyIOException", Level = LogLevel.Debug, Message = "Reading the request body failed with an IOException.")] | |
[LoggerMessage(EventId = 1, Level = LogLevel.Debug, Message = "Reading the request body failed with an IOException.")] |
} | ||
=> RequestBodyInvalidDataException(GetLogger(httpContext), exception); | ||
|
||
[LoggerMessage(EventId = 2, EventName = "RequestBodyInvalidDataException", Level = LogLevel.Debug, Message = "Reading the request body failed with an InvalidDataException.")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[LoggerMessage(EventId = 2, EventName = "RequestBodyInvalidDataException", Level = LogLevel.Debug, Message = "Reading the request body failed with an InvalidDataException.")] | |
[LoggerMessage(EventId = 2, Level = LogLevel.Debug, Message = "Reading the request body failed with an InvalidDataException.")] |
=> ParameterBindingFailed(GetLogger(httpContext), parameterTypeName, parameterName, sourceValue); | ||
|
||
[LoggerMessage(EventId = 3, EventName = "ParamaterBindingFailed", Level = LogLevel.Debug, Message = @"Failed to bind parameter ""{ParameterType} {ParameterName}"" from ""{SourceValue}"".")] | ||
public static partial void ParameterBindingFailed(ILogger logger, string parameterType, string parameterName, string sourceValue); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ParamaterBindingFailed
vs. ParameterBindingFailed
Closing this. Will work on converting to LoggerMessage in independent PRs. |
A lot of the warnings for this rule appear from logging. Given this is going
to be replaced by a source generator, this change soft enables the rule while
fixing warnings that appear in non-logging code
Contributes to #24055