Cysharp / ZLogger

Zero Allocation Text/Structured Logger for .NET with StringInterpolation and Source Generator, built on top of a Microsoft.Extensions.Logging.
MIT License
1.16k stars 81 forks source link

Mapped Diagnostic Logical Context like? #13

Closed robertmircea closed 4 years ago

robertmircea commented 4 years ago

Is it possible to have something like MDLC? I want to log current user name or request id across log messages during http requests.

Thanks!

neuecc commented 4 years ago

No(for performance reason, ZLogger no suports logging scope).

However, by using AsyncLocal externally to save and using PrefixFormatter, SuffixFormatter, and StructuredLoggingFormatter, a similar thing can be achieved.

robertmircea commented 1 year ago

Sorry for resurrecting an old thread: could you please show a small example showing how to access the current ClaimsPrincipal in the context of PrefixFormatter even if has a slower performance? I've designed the following class for storing the current user during login, but I can't find a way to access it inside PrefixFormatter.

public class UserContextAccessor : IUserContextAccessor
{
    private static readonly AsyncLocal<UserContextHolder> userContext = new AsyncLocal<UserContextHolder>();

    public ClaimsPrincipal? User
    {
        get => userContext.Value?.User;
        set
        {
            var holder = userContext.Value;
            if (holder != null) 
                holder.User = null;

            if (value != null) 
                userContext.Value = new UserContextHolder() { User = value };
        }
    }

    private class UserContextHolder
    {
        public ClaimsPrincipal? User;
    }
}

in my app builder, I register a singleton:

builder.Services.AddLogging(logging =>
{
    logging.ClearProviders();
    logging.ConfigureZLog(builder);
});
builder.Services.AddSingleton<IUserContextAccessor, UserContextAccessor>();

in my log in code:

                var claims = new[]
                    { 
                        new Claim(ClaimTypes.Name, usernameS),
                    };
                var identity = new ClaimsIdentity(claims, "Basic");
                var claimsPrincipal = new ClaimsPrincipal(identity);
                userContextAccessor.User = claimsPrincipal;

but how do I can I access userContextAccessor from PrefixFormatter since I don't have access to the service provider?