简体   繁体   English

使用 Serilog 并行记录多个文件

[英]Parallel logging in multiple files using Serilog

I want to log different files with different log templates depending on Users count that are changes only at program start using Serilog.我想根据用户数使用不同的日志模板记录不同的文件,这些用户数仅在程序开始使用 Serilog 时发生变化。

Let's say we have User object:假设我们有用户object:

class User
{
    public string Username { get; set; }

    private static ILogger _logger;

    public Username()
    {
         _logger = Log.ForContext("Username", User.Username);
    }
    public void DoSomething()
    {
         _logger.Information("I did something!");//Which sends to the {User.Username}-log.txt
                                             //And appends this field to the logtemplate like the example:
                                             //13:25:12 | [INF] | {USERNAME} | I did something!
    }
    //
}

After creating multiple Users I want to run parallel tasks and log them separate.创建多个用户后,我想运行并行任务并将它们分开记录。

        private static void Main(string[]? args)
        {
        Log.Logger = new LoggerConfiguration()
            .WriteTo.Logger(lc => lc.
                Filter.ByIncludingOnly(Matching.WithProperty("Username"))
                .WriteTo.File("logs/log-{Username}", LogEventLevel.Debug, rollingInterval: RollingInterval.Day)
                .WriteTo.Console(LogEventLevel.Debug, "{Timestamp:HH:mm:ss} | [{Level:u3}] | {Username} | {Message}{NewLine}{Exception}", theme: SystemConsoleTheme.Literate))
            .WriteTo.Console(LogEventLevel.Debug, "{Timestamp:HH:mm:ss} | [{Level:u3}] | {Message}{NewLine}{Exception}", theme: SystemConsoleTheme.Literate)
            .MinimumLevel.Information()
            .WriteTo.File("logs/log-", LogEventLevel.Debug, rollingInterval: RollingInterval.Day)
            .MinimumLevel.Debug()
            .CreateLogger();
            var users = new List<User>();
            //Init users

            foreach (var user in users)
            {
                Task.Run(() =>
                {
                    while (true)
                    {
                        user.DoSomething();
                    }
                });
            }
        }

I tried to use inside User class but it applies the Username of the last User created.我尝试在用户class 内部使用,但它应用了最后一个用户创建的用户名。

Solution解决方案

I came to this way but I don't really like it.我来到这里,但我真的不喜欢它。

First, configure static logger:首先,配置 static 记录器:

Log.Logger = new LoggerConfiguration()
            .WriteTo.Map("Username", "log", (fileName, wt) => wt.File($"logs/{fileName}-.txt", rollingInterval: RollingInterval.Day), restrictedToMinimumLevel: LogEventLevel.Debug)
            .CreateLogger();

I used Serilog.Sinks.Map for this, which I use to attach property key trigger "Username" for log files name.我为此使用了 Serilog.Sinks.Map,我用它来为日志文件名附加属性键触发器“用户名”

I created my own Logger class for easier property attaching and for the new log template:我创建了自己的 Logger class 以便于附加属性和新的日志模板:

internal class Logger
{
    public ILogger Log;
    public Logger(User user)
    {
        User = user;
        Log = Serilog.Log.ForContext("Username", user.Username);
    }

    public User User { get; set; }

    public void Information(string message)
    {
        Log.Information(string.IsNullOrEmpty(User.Username) ? message : $"{{Username}} | {message}", User.Username);
    }
}

And the usage:以及用法:

new Logger(User).Information("The most stupid solution but it works honestly.");

Yes, I have to create new Logger() each time I want to log something with a specific user.是的,每次我想用特定用户记录某些东西时,我都必须创建新的 Logger()。

Hope someone can show me better way.希望有人能告诉我更好的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM