简体   繁体   English

我可以使用 Serilog 登录到单独的文件吗?

[英]Can I log to separate files using Serilog?

My ASP.NET Core 2.1 app logs to a Serilog file sink, all the "usual stuff" - ie app related stuff such as debug, monitoring, performance, etc.我的 ASP.NET Core 2.1 应用程序登录到 Serilog 文件接收器,所有“常见的东西”——即与应用程序相关的东西,如调试、监控、性能等。

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 .我可以只写一个FileStream But I prefer to do structured logging with Serilog.但我更喜欢使用 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> .) (如果是这样,我如何将它们注入我的类 - 现在我只注入ILogger<ClassName> 。)

The simplest way I've managed to do this was to implement a new unique interface that I could pass to the DI system to be consumed by the controllers.我设法做到这一点的最简单方法是实现一个新的独特接口,我可以将其传递给控制器​​使用的 DI 系统。
Note: In the example I used the Serilog.Sinks.RollingFile NuGet package.注意:在示例中,我使用了Serilog.Sinks.RollingFile NuGet 包。 Use any other sinks as you see fit.使用您认为合适的任何其他水槽。 I use asp.net Core 2.1.我使用asp.net Core 2.1。

New Interface新界面

using Serilog;
using Serilog.Core;

public interface ICustomLogger
{
    ILogger Log { get; }
}

public class CustomLogger : ICustomLogger
{
    private readonly Logger _logger;

    public ILogger Log { get { return _logger; } }

    public CustomLogger( Logger logger )
    {
        _logger = logger;
    }
}

Implementation in Startup.cs在 Startup.cs 中的实现

using Serilog;
...
public void ConfigureServices( IServiceCollection services )
{
    ...

    ICustomLogger customLogger = new CustomLogger( new LoggerConfiguration()
        .MinimumLevel.Debug()
        .WriteTo.RollingFile( @"Logs\CustomLog.{Date}.log", retainedFileCountLimit: 7 )
        .CreateLogger() );
    services.AddSingleton( customLogger );

    ...
}

Usage in Controller在控制器中的使用

public class MyTestController : Controller
{
    private readonly ICustomLogger _customLogger;

    public MyTestController( ICustomLogger customLogger )
    {
        _customLogger = customLogger;
    }

    public IActionResult Index()
    {
        ...
        _customLogger.Log.Debug( "Serving Index" );
        ...
    }
}

You can definitely do that.你绝对可以这样做。

  1. You need to import package Serilog.Sinks.File您需要导入包Serilog.Sinks.File

  2. Then you have to configure Serilog.然后你必须配置 Serilog。

    In program.cs do following thing.在 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();

In buildWebHost function add UseSerilog().在 buildWebHost 函数中添加 UseSerilog()。

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
    .UseStartup<Startup>()
        .UseSerilog() // <-- Add this line
        .Build();

Update 1更新 1

I have used EventId property.我使用了 EventId 属性。 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.这只是演示如何根据 eventId 使用不同的文件,但根据您的要求,您必须自己实现其他内容。

Program.cs程序.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我的家庭控制器.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.注意:主要是您必须使用某种类型的过滤器。

Serilog.Sinks.Map does this, and includes a file logging example: Serilog.Sinks.Map执行此操作,并包含一个文件日志示例:

Log.Logger = new LoggerConfiguration()
    .WriteTo.Map("EventId", "Other", (name, wt) => wt.File($"./logs/log-{name}.txt"))
    .CreateLogger();

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

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