From 3195fbbd82fdb7f132d6698591ba6489ad6dd8cf Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Sat, 24 Jun 2023 11:56:43 -0700 Subject: [PATCH] Auto generate Event Ids in the logging source gen (#87892) --- .../gen/LoggerMessageGenerator.Parser.cs | 33 +++++++++++-- .../TestWithDefaultValues.generated.txt | 2 +- .../LoggerMessageGeneratedCodeTests.cs | 48 +++++++++++++++++-- .../TestClasses/TestInstances.cs | 14 ++++++ 4 files changed, 87 insertions(+), 10 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs index 24d70caf79114..2b5b8ca6a1a49 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs @@ -103,6 +103,7 @@ public IReadOnlyList GetLogClasses(IEnumerable GetLogClasses(IEnumerable GetLogClasses(IEnumerable GetLogClasses(IEnumerable GetLogClasses(IEnumerable !IsLogger && !IsException && !IsLogLevel; } + + /// + /// Returns a non-randomized hash code for the given string. + /// We always return a positive value. + /// + internal static int GetNonRandomizedHashCode(string s) + { + uint result = 2166136261u; + foreach (char c in s) + { + result = (c ^ result) * 16777619; + } + return Math.Abs((int)result); + } } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithDefaultValues.generated.txt b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithDefaultValues.generated.txt index 9fafdd9774b0d..fbeae59ffb120 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithDefaultValues.generated.txt +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithDefaultValues.generated.txt @@ -49,7 +49,7 @@ namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses { logger.Log( level, - new global::Microsoft.Extensions.Logging.EventId(-1, nameof(M0)), + new global::Microsoft.Extensions.Logging.EventId(316638712, nameof(M0)), new __M0Struct(), null, __M0Struct.Format); diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratedCodeTests.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratedCodeTests.cs index 8d6eafe7ec91a..7688e26ad0062 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratedCodeTests.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratedCodeTests.cs @@ -209,7 +209,7 @@ public void MessageTests() Assert.Null(logger.LastException); Assert.Equal(string.Empty, logger.LastFormattedString); Assert.Equal(LogLevel.Trace, logger.LastLogLevel); - Assert.Equal(-1, logger.LastEventId.Id); + Assert.Equal(400_526_807, logger.LastEventId.Id); Assert.Equal(1, logger.CallCount); logger.Reset(); @@ -269,6 +269,7 @@ public void InstanceTests() var logger = new MockLogger(); var o = new TestInstances(logger); + // [LoggerMessage(EventId = 0, Level = LogLevel.Error, Message = "M0")] logger.Reset(); o.M0(); Assert.Null(logger.LastException); @@ -276,6 +277,7 @@ public void InstanceTests() Assert.Equal(LogLevel.Error, logger.LastLogLevel); Assert.Equal(1, logger.CallCount); + // [LoggerMessage(EventId = 1, Level = LogLevel.Trace, Message = "M1 {p1}")] logger.Reset(); o.M1("Foo"); Assert.Null(logger.LastException); @@ -283,26 +285,64 @@ public void InstanceTests() Assert.Equal(LogLevel.Trace, logger.LastLogLevel); Assert.Equal(1, logger.CallCount); + // [LoggerMessage(LogLevel.Information, "M2 {p1}")] logger.Reset(); o.M2("Bar"); Assert.Null(logger.LastException); Assert.Equal("M2 Bar", logger.LastFormattedString); Assert.Equal(LogLevel.Information, logger.LastLogLevel); - Assert.Equal(-1, logger.LastEventId.Id); + Assert.Equal(350_193_950, logger.LastEventId.Id); + // [LoggerMessage("M3 {p1}")] logger.Reset(); o.M3(LogLevel.Critical, "Foo Bar"); Assert.Null(logger.LastException); Assert.Equal("M3 Foo Bar", logger.LastFormattedString); Assert.Equal(LogLevel.Critical, logger.LastLogLevel); - Assert.Equal(-1, logger.LastEventId.Id); + Assert.Equal(366_971_569, logger.LastEventId.Id); + // [LoggerMessage(LogLevel.Debug)] logger.Reset(); o.M4(); Assert.Null(logger.LastException); Assert.Equal("", logger.LastFormattedString); Assert.Equal(LogLevel.Debug, logger.LastLogLevel); - Assert.Equal(-1, logger.LastEventId.Id); + Assert.Equal(383_749_188, logger.LastEventId.Id); + + // [LoggerMessage(level: LogLevel.Warning, message: "custom message {v}", eventId: 12341)] + logger.Reset(); + o.M5("Hello"); + Assert.Null(logger.LastException); + Assert.Equal("custom message Hello", logger.LastFormattedString); + Assert.Equal(LogLevel.Warning, logger.LastLogLevel); + Assert.Equal(12341, logger.LastEventId.Id); + + // [LoggerMessage(EventName = "My Event Name", Level = LogLevel.Information, Message = "M6 - {p1}")] + logger.Reset(); + o.M6("Generate event Id"); + Assert.Null(logger.LastException); + Assert.Equal("M6 - Generate event Id", logger.LastFormattedString); + Assert.Equal(LogLevel.Information, logger.LastLogLevel); + Assert.Equal("My Event Name", logger.LastEventId.Name); + Assert.Equal(26_601_394, logger.LastEventId.Id); + + // [LoggerMessage(Level = LogLevel.Warning, Message = "M7 - {p1}")] + logger.Reset(); + o.M7("Generate event Id"); + Assert.Null(logger.LastException); + Assert.Equal("M7 - Generate event Id", logger.LastFormattedString); + Assert.Equal(LogLevel.Warning, logger.LastLogLevel); + Assert.Equal("M7", logger.LastEventId.Name); + Assert.Equal(434_082_045, logger.LastEventId.Id); + + // [LoggerMessage(EventId = 100, Level = LogLevel.Warning, Message = "M8 - {p1}")] + logger.Reset(); + o.M8("Generate event Id"); + Assert.Null(logger.LastException); + Assert.Equal("M8 - Generate event Id", logger.LastFormattedString); + Assert.Equal(LogLevel.Warning, logger.LastLogLevel); + Assert.Equal("M8", logger.LastEventId.Name); + Assert.Equal(100, logger.LastEventId.Id); } [Fact] diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/TestInstances.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/TestInstances.cs index d9e043116cd2c..c25155716f850 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/TestInstances.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/TestInstances.cs @@ -28,5 +28,19 @@ public TestInstances(ILogger logger) [LoggerMessage(LogLevel.Debug)] public partial void M4(); + + // Test with named parameters + [LoggerMessage(level: LogLevel.Warning, message: "custom message {v}", eventId: 12341)] + public partial void M5(string v); + + // Test auto-generated EventId + [LoggerMessage(EventName = "My Event Name", Level = LogLevel.Information, Message = "M6 - {p1}")] + public partial void M6(string p1); + + [LoggerMessage(Level = LogLevel.Warning, Message = "M7 - {p1}")] + public partial void M7(string p1); + + [LoggerMessage(EventId = 100, Level = LogLevel.Warning, Message = "M8 - {p1}")] + public partial void M8(string p1); } }