我的ASP.NET Core 2.1应用程序登录到Serilog文件接收器,所有“通常的东西” - 即应用程序相关的东西,如调试,监控,性能等。
但是,我们还需要将其他数据记录到单独的文件中。 与应用程序无关,但客户相关 - 应该进入数据库的那种东西。 但是由于遗留原因,此系统上没有数据库,因此需要将数据保存到文件中。 显然这不能写入同一个日志文件。
我可以写一个FileStream 。 但我更喜欢用Serilog进行结构化日志记录。
那么有没有办法同时拥有两个记录器? 其中将不同的数据记录到不同的文件接收器。
(如果是这样,我如何将它们注入我的类 - 现在我只注入ILogger<ClassName> 。)
My ASP.NET Core 2.1 app logs to a Serilog file sink, all the "usual stuff" - i.e. app related stuff such as debug, monitoring, performance, etc.
However we also need to log other data to a separate file. Not app related, but customer related - the kind of stuff that should go into a database. However for legacy reasons, there is no database on this system and so that data needs to be saved to a file instead. Obviously this can't be written to the same log file.
I could just write to a FileStream. But I prefer to do structured logging with Serilog.
So is there a way to have two loggers simultaneously? Which log different data to different file sinks.
(If so, how do I inject them into my classes - right now I just inject ILogger<ClassName>.)
最满意答案
你绝对可以做到这一点。
您需要导入包Serilog.Sinks.File
然后你必须配置Serilog。
在program.cs做以下事情。
Log.Logger = new LoggerConfiguration() .MinimumLevel.Debug() .MinimumLevel.Override("Microsoft", LogEventLevel.Information) .Enrich.FromLogContext() .WriteTo.File( @"<<your log file path>>", fileSizeLimitBytes: 10000000, rollOnFileSizeLimit: true, shared: true, flushToDiskInterval: TimeSpan.FromSeconds(1)) .CreateLogger();在buildWebHost函数中添加UseSerilog()。
public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .UseSerilog() // <-- Add this line .Build();更新1
我使用了EventId属性。 这只是演示如何使用基于eventId的不同文件,但是为了您的要求,您必须自己实现其他功能。
Program.cs中
public class Program { public static void Main(string[] args) { Log.Logger = new LoggerConfiguration() .WriteTo.Logger(cc => cc.Filter.ByIncludingOnly(WithProperty("EventId",1001)).WriteTo.File("Test1001.txt",flushToDiskInterval: TimeSpan.FromSeconds(1))) .WriteTo.Logger(cc => cc.Filter.ByIncludingOnly(WithProperty("EventId", 2001)).WriteTo.File("Test2001.txt", flushToDiskInterval: TimeSpan.FromSeconds(1))) .CreateLogger(); CreateWebHostBuilder(args).Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args).UseSerilog() .UseStartup<Startup>(); public static Func<LogEvent, bool> WithProperty(string propertyName, object scalarValue) { if (propertyName == null) throw new ArgumentNullException("propertyName"); ScalarValue scalar = new ScalarValue(scalarValue); return e=> { LogEventPropertyValue propertyValue; if (e.Properties.TryGetValue(propertyName, out propertyValue)) { var stValue = propertyValue as StructureValue; if (stValue != null) { var value = stValue.Properties.Where(cc => cc.Name == "Id").FirstOrDefault(); bool result = scalar.Equals(value.Value); return result; } } return false; }; } }我的HomeController.cs
public class HomeController : Controller { ILogger<HomeController> logger; public HomeController(ILogger<HomeController> logger) { this.logger = logger; } public IActionResult Index() { logger.Log(LogLevel.Information,new EventId(1001), "This is test 1"); logger.Log(LogLevel.Information, new EventId(2001), "This is test 2"); return View(); } }注意:主要的是你必须使用某种类型的过滤器。
You can definitely do that.
You need to import package Serilog.Sinks.File
Then you have to configure Serilog.
In program.cs do following thing.
Log.Logger = new LoggerConfiguration() .MinimumLevel.Debug() .MinimumLevel.Override("Microsoft", LogEventLevel.Information) .Enrich.FromLogContext() .WriteTo.File( @"<<your log file path>>", fileSizeLimitBytes: 10000000, rollOnFileSizeLimit: true, shared: true, flushToDiskInterval: TimeSpan.FromSeconds(1)) .CreateLogger();In buildWebHost function add UseSerilog().
public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .UseSerilog() // <-- Add this line .Build();Update 1
I have used EventId property. This is just demo that how you can use different file based on eventId but for your requirement you have to implement additional thing your own.
Program.cs
public class Program { public static void Main(string[] args) { Log.Logger = new LoggerConfiguration() .WriteTo.Logger(cc => cc.Filter.ByIncludingOnly(WithProperty("EventId",1001)).WriteTo.File("Test1001.txt",flushToDiskInterval: TimeSpan.FromSeconds(1))) .WriteTo.Logger(cc => cc.Filter.ByIncludingOnly(WithProperty("EventId", 2001)).WriteTo.File("Test2001.txt", flushToDiskInterval: TimeSpan.FromSeconds(1))) .CreateLogger(); CreateWebHostBuilder(args).Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args).UseSerilog() .UseStartup<Startup>(); public static Func<LogEvent, bool> WithProperty(string propertyName, object scalarValue) { if (propertyName == null) throw new ArgumentNullException("propertyName"); ScalarValue scalar = new ScalarValue(scalarValue); return e=> { LogEventPropertyValue propertyValue; if (e.Properties.TryGetValue(propertyName, out propertyValue)) { var stValue = propertyValue as StructureValue; if (stValue != null) { var value = stValue.Properties.Where(cc => cc.Name == "Id").FirstOrDefault(); bool result = scalar.Equals(value.Value); return result; } } return false; }; } }My HomeController.cs
public class HomeController : Controller { ILogger<HomeController> logger; public HomeController(ILogger<HomeController> logger) { this.logger = logger; } public IActionResult Index() { logger.Log(LogLevel.Information,new EventId(1001), "This is test 1"); logger.Log(LogLevel.Information, new EventId(2001), "This is test 2"); return View(); } }Note: Main thing is that you have to use some type of filter.
更多推荐
发布评论