Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

ZLoggerMessage default .ToString() with IEnumerable parameters result in type emitted in the message #195

Open
AlexandreRevel opened this issue Dec 23, 2024 · 0 comments

Comments

@AlexandreRevel
Copy link
Contributor

When using zlogger's source generator and using the resulting code with another LoggerProvider (OpenTelemetry Exporter for my case)

the default ToString of the state object is called to generate the logging message:

public override string ToString() => $"MyItems: {Items}";

Where Items parameter is of type IEnumerable

Here is the ZLoggerMessage call:

[ZLoggerMessage(EventId = EventIdCategory + 4, Level = LogLevel.Error, Message = "MyItems: {MyEnumerable}", SkipEnabledCheck = true)]
public static partial void MyEnumerableDetails(this ILogger<Test> logger, string[] myEnumerable);

Here is the resulting message formatted in the end

image

By comparison, the LoggerMessageAttribute from Microsoft calls the following methods on the value:

private static object FormatArgument(object? value)
{
    return TryFormatArgumentIfNullOrEnumerable(value, out object? stringValue) ? stringValue : value!;
}

private static bool TryFormatArgumentIfNullOrEnumerable<T>(T? value, [NotNullWhen(true)] out object? stringValue)
{
    if (value == null)
    {
        stringValue = NullValue;
        return true;
    }

    // if the value implements IEnumerable but isn't itself a string, build a comma separated string.
    if (value is not string && value is IEnumerable enumerable)
    {
        var vsb = new ValueStringBuilder(stackalloc char[256]);
        bool first = true;
        foreach (object? e in enumerable)
        {
            if (!first)
            {
                vsb.Append(", ");
            }

            vsb.Append(e != null ? e.ToString() : NullValue);
            first = false;
        }
        stringValue = vsb.ToString();
        return true;
    }

    stringValue = null;
    return false;
}

Previous code found here : https://github.com/dotnet/runtime/blob/main/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatter.cs#L253

Is it something that can be done on the default ToString method of the ZLogger's state object to render the message?

The immediate not a solution that works is to generetate log methods that logs Enumerable values using LoggerMessageAttribute instead of ZLoggerMessage

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant