前段时间,项目有需求,需要将某些模块的日志单独记录文件夹,于是找了一下Serilog的目录配置。
如果是按照appsetting来配置,节点内容大概如下:
{
"Name": "RollingFile",
"Args": {
"pathFormat": "Logs/Warning/{Date}.txt",
"RestrictedToMinimumLevel": "Warning",
"rollingInterval": "Day",
"outputTemplate": "{Timestamp:yyyy-MM-dd hh:mm:ss} || {Level} || {SourceContext:l} || {Message} || {Exception} || end {NewLine}"
}
}
看这个样子,pathFormat只能根据日期来区分,再看看如果在程序内配置如何:
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.MinimumLevel.Warning() // 生产最小记录级别
.WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Debug).WriteTo.File(LogFilePath("Debug"), rollingInterval: RollingInterval.Day, outputTemplate: SerilogOutputTemplate))
网上找到例子,看上去Filter只能控制Level来区分目录,每个Level一个目录,还是不符合我的需求。
不过后来看到了Filter筛选对象是LogEvent,那么可以根据其属性Properties进行条件判断来区分目录,代码如下:
string LogFilePath(string LogEvent) => $@"{AppContext.BaseDirectory}Log/{LogEvent}/log.log";
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.WriteTo.Console() // 输出到控制台
.MinimumLevel.Debug() // 测试最小记录级别
.WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(p => {
var result = p.Properties.FirstOrDefault(c => c.Key == "SourceContext").Value;
if (result != null) {
return result.ToString().Contains("模块名");
}
return false;
}).WriteTo
.File(LogFilePath("模块目录"), rollingInterval: RollingInterval.Day, outputTemplate: SocketOutputTemplate))
.CreateLogger();
这样就可以筛选某个模块的日志,将其归类到某个日志目录当中了。
当然创建日志的时候,也要命名好模块,代码如下:
public class Test
{
public Test(ILoggerFactory LoggerFactory)
{
var logger = LoggerFactory.CreateLogger("模块名");
logger.LogDebug("Conch是最帅的男人!");
}
}
除此之外,LogEvent还有其他的属性,例如:Exception可以根据异常类型进行分类。具体可以在过滤器的Func<LogEvent, bool>委托内自由发挥。