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

Add SkipEnabledCheck on LoggerMessageAttribute #54305

Merged
merged 7 commits into from
Jun 22, 2021

Conversation

maryamariyan
Copy link
Member

@maryamariyan maryamariyan commented Jun 17, 2021

@ghost
Copy link

ghost commented Jun 17, 2021

Tagging subscribers to this area: @maryamariyan
See info in area-owners.md if you want to be subscribed.

Issue Details

/cc @gfoidl

Author: maryamariyan
Assignees: maryamariyan
Labels:

area-Extensions-Logging

Milestone: -

@dotnet-issue-labeler
Copy link

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

Copy link
Member

@gfoidl gfoidl left a comment

Choose a reason for hiding this comment

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

Two nits, otherwise LGTM.

Didn't try to run this new feature in a demo-project, as I don't know how to wire things together from the PR build. But according the tests added in this PR it should work.

@maryamariyan
Copy link
Member Author

I added another commit, that fixes: #52277, making the logging generator more robust against null input arguments.

@@ -450,13 +455,13 @@ public IReadOnlyList<LoggerClass> GetLogClasses(IEnumerable<ClassDeclarationSynt
switch (a.NameEquals.Name.ToString())
{
case "EventId":
eventId = (int)sm.GetConstantValue(a.Expression, _cancellationToken).Value!;
eventId = (int?)sm.GetConstantValue(a.Expression, _cancellationToken).Value ?? -1;
Copy link
Member Author

@maryamariyan maryamariyan Jun 17, 2021

Choose a reason for hiding this comment

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

Also fixes issue #52223

When event ID is not set, it will default to -1, and when multiple logging methods in a class don't have event ID set, they all default to -1, causing the SYSLIB1006 warning.

break;
case "Message":
message = sm.GetConstantValue(a.Expression, _cancellationToken).ToString();
break;
case "SkipEnabledCheck":
bool? flag = (bool?)sm.GetConstantValue(a.Expression, _cancellationToken).Value;
Copy link
Member

Choose a reason for hiding this comment

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

What happens to this code if someone writes code that might not compile? Does the source generator fail with an exception, adding more errors to the Error List?

[LoggerMessage(SkipEnabledCheck = 6)]

Copy link
Member Author

Choose a reason for hiding this comment

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

for this specific use case we get this error:

[warning CS8785: Generator 'LoggerMessageGenerator' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type 'InvalidCastException' with message 'Unable to cast object of type 'System.Int32' to type 'System.Nullable`1[System.Boolean]'.']

Copy link
Member

Choose a reason for hiding this comment

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

Should we fix that? That may be confusing to users.

Copy link
Member Author

Choose a reason for hiding this comment

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

OK looking into it.

Copy link
Member Author

@maryamariyan maryamariyan Jun 22, 2021

Choose a reason for hiding this comment

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

Fixed and made generator more robust against misconfigured input in the latest commit (58e1a75)

/cc @chsienki

/// <param name="eventId">The log event Id.</param>
/// <param name="level">The log level.</param>
/// <param name="message">Format string of the log message.</param>
public LoggerMessageAttribute(int eventId, LogLevel level, string message)
Copy link
Contributor

Choose a reason for hiding this comment

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

Any reason not to have EventName here?

Copy link
Member Author

@maryamariyan maryamariyan Jun 22, 2021

Choose a reason for hiding this comment

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

This was the only ctor approved since we assumed it to be the most commonly used. If we think there is value in adding another ctor with EventName included (4 args) then we can take it to API review.

IReadOnlyList<Diagnostic> diagnostics = await RunGenerator(@"
public static partial class C
{
[LoggerMessage(SkipEnabledCheck = 6)]
Copy link
Member Author

Choose a reason for hiding this comment

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

@eerhardt here's the test case you asked for.

@@ -93,6 +94,9 @@ public IReadOnlyList<LoggerClass> GetLogClasses(IEnumerable<ClassDeclarationSynt
}

sm ??= _compilation.GetSemanticModel(classDec.SyntaxTree);
IMethodSymbol logMethodSymbol = sm.GetDeclaredSymbol(method, _cancellationToken) as IMethodSymbol;
Debug.Assert(logMethodSymbol != null, "log method is present.");
(int eventId, int? level, string message, string? eventName, bool skipEnabledCheck) = (-1, null, string.Empty, null, false);
Copy link
Member

Choose a reason for hiding this comment

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

Does this need to use a tuple anymore? Can this just be regular variables?

Copy link
Member Author

Choose a reason for hiding this comment

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

no but I thought it would be neater this way, all defined in one line.

Copy link
Member

Choose a reason for hiding this comment

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

I'm not crazy about it... Especially because I need to match up the variable with the value on the right-hand side to see what its default value is.

@maryamariyan
Copy link
Member Author

Failures are System.IO.Tests.Directory_GetFileSystemEntries_str.GetEntriesThenDelete and System.Linq.Queryable.Tests

https://dev.azure.com/dnceng/public/_build/results?buildId=1199358&view=ms.vss-test-web.build-test-results-tab&runId=35941624&resultId=169277&paneView=debug

@maryamariyan maryamariyan merged commit 7a3343f into dotnet:main Jun 22, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants