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

Soft enable CA1810 #33619

Closed
wants to merge 2 commits into from
Closed

Soft enable CA1810 #33619

wants to merge 2 commits into from

Conversation

pranavkm
Copy link
Contributor

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

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}")]
Copy link
Contributor Author

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

Copy link
Member

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" />
Copy link
Member

@davidfowl davidfowl Jun 17, 2021

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?

Copy link
Contributor Author

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
Copy link
Member

Choose a reason for hiding this comment

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

Why internal?

Copy link
Contributor Author

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);
Copy link
Member

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.

Copy link
Contributor Author

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).

Copy link
Member

Choose a reason for hiding this comment

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

Need to check.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

_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}")]
Copy link
Member

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);
Copy link
Member

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);
Copy link
Member

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);
Copy link
Member

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.

Copy link
Member

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>
Copy link
Member

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>(
Copy link
Member

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}")]
Copy link
Member

@maryamariyan maryamariyan Jun 18, 2021

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.

Copy link
Member

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'.")]
Copy link
Member

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.")]
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
[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")]
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
[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.")]
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
[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.")]
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
[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.")]
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
[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.")]
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
[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,
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
[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.")]
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
[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.")]
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
[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);
Copy link
Member

@maryamariyan maryamariyan Jun 18, 2021

Choose a reason for hiding this comment

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

ParamaterBindingFailed vs. ParameterBindingFailed

@Pilchie Pilchie added the area-infrastructure Includes: MSBuild projects/targets, build scripts, CI, Installers and shared framework label Jun 21, 2021
@pranavkm
Copy link
Contributor Author

Closing this. Will work on converting to LoggerMessage in independent PRs.

@pranavkm pranavkm closed this Jun 29, 2021
@pranavkm pranavkm deleted the prkrishn/fxcop-5 branch June 29, 2021 02:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-infrastructure Includes: MSBuild projects/targets, build scripts, CI, Installers and shared framework
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants