使用 Serilog 并行记录多个文件
Parallel logging in multiple files using Serilog
我想根据用户数使用不同的日志模板记录不同的文件,这些文件仅在程序启动时使用 Serilog 进行更改。
假设我们有 User 对象:
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!
}
//
}
创建多个用户后,我想运行并行任务并将它们分开记录。
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();
}
});
}
}
我尝试在 User class 中使用,但它应用了最后创建的用户的 Username。
解决方案
我是这样过来的,但我不是很喜欢
首先,配置静态记录器:
Log.Logger = new LoggerConfiguration()
.WriteTo.Map("Username", "log", (fileName, wt) => wt.File($"logs/{fileName}-.txt", rollingInterval: RollingInterval.Day), restrictedToMinimumLevel: LogEventLevel.Debug)
.CreateLogger();
我为此使用了 Serilog.Sinks.Map,我用它来附加 属性 键触发器 "用户名"用于日志文件名。
我创建了自己的 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);
}
}
以及用法:
new Logger(User).Information("The most stupid solution but it works honestly.");
是的,每次我想用特定用户记录一些东西时,我都必须创建新的 Logger()。
希望有人能告诉我更好的方法。
我想根据用户数使用不同的日志模板记录不同的文件,这些文件仅在程序启动时使用 Serilog 进行更改。
假设我们有 User 对象:
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!
}
//
}
创建多个用户后,我想运行并行任务并将它们分开记录。
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();
}
});
}
}
我尝试在 User class 中使用,但它应用了最后创建的用户的 Username。
解决方案
我是这样过来的,但我不是很喜欢
首先,配置静态记录器:
Log.Logger = new LoggerConfiguration()
.WriteTo.Map("Username", "log", (fileName, wt) => wt.File($"logs/{fileName}-.txt", rollingInterval: RollingInterval.Day), restrictedToMinimumLevel: LogEventLevel.Debug)
.CreateLogger();
我为此使用了 Serilog.Sinks.Map,我用它来附加 属性 键触发器 "用户名"用于日志文件名。
我创建了自己的 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);
}
}
以及用法:
new Logger(User).Information("The most stupid solution but it works honestly.");
是的,每次我想用特定用户记录一些东西时,我都必须创建新的 Logger()。
希望有人能告诉我更好的方法。