Cysharp / ZLogger

Zero Allocation Text/Structured Logger for .NET with StringInterpolation and Source Generator, built on top of a Microsoft.Extensions.Logging.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Recommendation for Caller* attributes

Rurouni opened this issue · comments

Hello,

I am trying to switch some of our code to ZLogger, but we have methods like

public static void Debug(
            string format, 
            object arg0, 
            object arg1,
            object arg2,
            CallerArgsGuard nextParamsAreAlwaysDefaults = default,
            [CallerFilePath] string path = null,
            [CallerLineNumber] int line = 0,
            [CallerMemberName] string method = null)
        {

Is there some way to optionally include Caller location data while preserving ZLog methods alloc efficiency?
The only idea I had was to use LogScopes to include extra caller properties and then do extra formatting via SuffixFormatter

Thank you

Example of what I am currently doing:

[UnityEngine.HideInCallstack]
    public static void Debug(
        this ILogger logger,
        [InterpolatedStringHandlerArgument("logger")] ref ZLoggerDebugInterpolatedStringHandler message, 
        UnityEngine.Object gameObject,
        [CallerFilePath] string path = null,
        [CallerLineNumber] int line = 0,
        [CallerMemberName] string method = null)
    {
        if (logger.IsEnabled(LogLevel.Debug))
        {
            using var x = logger.BeginScope("{Caller}",Log.FormatCallerInfo(path, line, method));
            logger.ZLogDebug(ref message, gameObject);
        }
    }

and then in PlainTextFormatter:

y.SetSuffixFormatter($"{0}", (message, info) =>
{
    var sb = new StringBuilder();
    if (info.ScopeState is { IsEmpty: false })
    {
        foreach (var pair in info.ScopeState.Properties)
        {
            if(pair.Key == "{OriginalFormat}")
                continue;
            sb.AppendLine();
            sb.Append("| ");   
            sb.Append(pair.Key);
            sb.Append(":");
            if (pair.Value is StringValues stringValues)
                sb.Append(stringValues.ToString());
            else
                sb.Append(pair.Value);
        }
        message.Format(sb.ToString());
    }
}

I had considered including them in LogInfo, but abandoned the idea due to compatibility issues with Source Generator. However, by handling them as string?, int?, string? in LogInfo and making them optional in Source Generator, it seems possible to implement this without any issues. Therefore, I'd like to consider adding them to the standard Log method.

I've released 2.3.0, it includes this feature.