Skip to content

LoggerMessage generator in Microsoft.Extensions.Telemetry.Abstractions generates different EventId than Microsoft.Extensions.Logging #6498

@ArturDorochowicz

Description

@ArturDorochowicz

Description

The new LoggerMessage generator from Microsoft.Extensions.Telemetry.Abstractions produces different EventId values compared to the original generator from Microsoft.Extensions.Logging. This is when there's no explicit EventName provided.

The problem is in the passed in input. Instead of using the method name, it's passed a nameof(Method) expression. See here:

string eventName = string.IsNullOrWhiteSpace(lm.EventName) ? $"nameof({lm.Name})" : $"\"{lm.EventName}\"";
(string exceptionArg, string exceptionLambdaName) = GetException(lm);

if (lm.EventId != null)
{
OutLn($"new({lm.EventId}, {eventName}),");
}
else
{
OutLn($"new({GetNonRandomizedHashCode(eventName)}, {eventName}),");
}

Actually, when looking at this now, it seems to me that even when EventName is explicitly provided, it will also calculate an incorrect EventId value, because it will include the double quotes around it.

Reproduction Steps

Create a project with Microsoft.Extensions.Logging:

dotnet new classlib
dotnet add package Microsoft.Extensions.Logging

Change Class1.cs to be:

using Microsoft.Extensions.Logging;

public partial class Class1(ILogger logger)
{
    [LoggerMessage(LogLevel.Error, "message")]
    partial void LogMessage();
}

The generated code has EventId(1180592680, nameof(LogMessage)) :

// <auto-generated/>
#nullable enable

    partial class Class1
    {
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "9.0.12.26613")]
        private static readonly global::System.Action<global::Microsoft.Extensions.Logging.ILogger, global::System.Exception?> __LogMessageCallback =
            global::Microsoft.Extensions.Logging.LoggerMessage.Define(global::Microsoft.Extensions.Logging.LogLevel.Error, new global::Microsoft.Extensions.Logging.EventId(1180592680, nameof(LogMessage)), "message", new global::Microsoft.Extensions.Logging.LogDefineOptions() { SkipEnabledCheck = true }); 

        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "9.0.12.26613")]
        partial void LogMessage()
        {
            if (logger.IsEnabled(global::Microsoft.Extensions.Logging.LogLevel.Error))
            {
                __LogMessageCallback(logger, null);
            }
        }
    }

Now do the same with Microsoft.Extensions.Telemetry :

dotnet new classlib
dotnet add package Microsoft.Extensions.Telemetry

Same Class1.cs as before.

The generated code has new(752341003, nameof(LogMessage):


// <auto-generated/>
#nullable enable
#pragma warning disable CS1591 // Compensate for https://github.com/dotnet/roslyn/issues/54103
partial class Class1
{
    /// <summary>
    /// Logs "message" at "Error" level.
    /// </summary>
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Gen.Logging", "9.6.0.0")]
    partial void LogMessage()
    {
        var state = global::Microsoft.Extensions.Logging.LoggerMessageHelper.ThreadLocalState;

        _ = state.ReserveTagSpace(1);
        state.TagArray[0] = new("{OriginalFormat}", "message");

        logger.Log(
            global::Microsoft.Extensions.Logging.LogLevel.Error,
            new(752341003, nameof(LogMessage)),
            state,
            null,
            [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Gen.Logging", "9.6.0.0")] static string (s, _) =>
            {
                return "message";
            });

        state.Clear();
    }
}

The EventId values are different

Expected behavior

EventId must remain the same when using the new lib.

Actual behavior

EventId changes.

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

No response

Metadata

Metadata

Assignees

Labels

area-telemetrybugThis issue describes a behavior which is not expected - a bug.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions