简体   繁体   English

在其他项目引用的 class 库中使用 serilog

[英]Using serilog in a class library referenced by other projects

I have a solution containing multiple .NET Core API and windows services.我有一个包含多个 .NET Core API 和 windows 服务的解决方案。 How can I integrate Serilog in such a way that I will not be required to make changes at several different places for adding a column or changing some property?我怎样才能集成 Serilog,这样我就不需要在几个不同的地方进行更改以添加列或更改某些属性?

I'm thinking of adding Serilog in a common library and use that custom library in all other projects however how to invoke starting point of the serilog as we see in below code in Program.cs, any code reference will help.我正在考虑在公共库中添加 Serilog 并在所有其他项目中使用该自定义库,但是如何调用 serilog 的起点,正如我们在 Program.cs 中的以下代码中看到的那样,任何代码参考都会有所帮助。

 .UseSerilog((hostingContext, loggerConfiguration) =>
                {
                    loggerConfiguration.MinimumLevel.Debug()
                            .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
                            .Enrich.FromLogContext()
                            .WriteTo.File(path: Path.Combine(Environment.CurrentDirectory, "Logs", "log.txt"),
                                rollOnFileSizeLimit: true,
                                retainedFileCountLimit: 20,
                                rollingInterval: RollingInterval.Day,
                                fileSizeLimitBytes: 10000
                                )
                            .WriteTo.Console();
                })

================ Updated =================== ================更新===================

For windows service, I have the code in common library.
public class LogManager : ILogManager
    {
       public LogManager()
            {
                Log.Logger = new LoggerConfiguration()
                             .MinimumLevel.Verbose()
                             .Enrich.FromLogContext()
                             //  .WriteTo.Console(LogEventLevel.Debug, OutputTemplate, theme: AnsiConsoleTheme.Code)
                             .WriteTo.RollingFile(@"C:\Users\hnq6ww\Documents\Important\logs.txt",
                                                        LogEventLevel.Verbose,
                                                        // OutputTemplate,
                                                        retainedFileCountLimit: (int?)RollingInterval.Day,
                                                        buffered: true, fileSizeLimitBytes: 10000)
                             .CreateLogger();
            }
}

In Program.cs在 Program.cs 中

  static void Main(string[] args)
        {
            ILogManager log = new LogManager();
            log.WriteLog(Serilog.Events.LogEventLevel.Information, "Testing");
        }

In your common library you can create an extension method that will inject Serilog into your multiple .NET Web API projects在您的公共库中,您可以创建一个扩展方法,将 Serilog 注入您的多个 .NET Web API 项目

So you can have something like this in your common class lib因此,您可以在常见的 class 库中拥有类似的东西

public static class SerilogDi
    {
        public static IHostBuilder InjectSerilog(this IHostBuilder hostBuilder)
        {
            hostBuilder.UseSerilog((hostingContext, loggerConfiguration) =>
            {
                loggerConfiguration.MinimumLevel.Debug()
                        .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
                        .Enrich.FromLogContext()
                        .WriteTo.File(path: Path.Combine(Environment.CurrentDirectory, "Logs", "log.txt"),
                            rollOnFileSizeLimit: true,
                            retainedFileCountLimit: 20,
                            rollingInterval: RollingInterval.Day,
                            fileSizeLimitBytes: 10000
                            )
                        .WriteTo.Console();
            });

            return hostBuilder;
        }
    }

and then you can add project reference of this project into your .NET Web API projects and inject Serilog in them, something like this然后您可以将此项目的项目参考添加到您的 .NET Web API 项目中并在其中注入 Serilog,如下所示

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .InjectSerilog()
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });

Also, you can make InjectSerilog() parameterized to further configure it on per project basis.此外,您可以将InjectSerilog()参数化,以便在每个项目的基础上进一步配置它。

UPDATE Ok according to your update I think you only want to configuration to be common.更新好的,根据您的更新,我认为您只想配置通用。 So what you can do is create a static method in your common library which return a configured logger.所以你可以做的是在你的公共库中创建一个 static 方法,它返回一个配置的记录器。

public static class MySerilog
    {
        public static Logger GetInstance()
        {
            return new LoggerConfiguration()
                             .MinimumLevel.Verbose()
                             .Enrich.FromLogContext()
                             //  All my settings here
                             .CreateLogger();
        }
    }

and then in your other projects you can use this instance然后在你的其他项目中你可以使用这个实例

public static int Main(string[] args)
{
    Log.Logger = MySerilog.GetInstance();
}

And in your CreateHostBuilder method you can simply do在您的CreateHostBuilder方法中,您可以简单地做

Host.CreateDefaultBuilder(args)
                .UseSerilog()
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });

This will work for both types of your project and you can make GetInstance() parameterized as well!这适用于您的两种类型的项目,您也可以将GetInstance()参数化!

You can further refer here https://github.com/serilog/serilog-aspnetcore您可以进一步参考这里https://github.com/serilog/serilog-aspnetcore

If you want to move logging logic into separate library, then you need to do the following steps.如果要将日志记录逻辑移动到单独的库中,则需要执行以下步骤。

The first step is to create logic of logging in your class library:第一步是在 class 库中创建日志记录逻辑:

public interface ILoggerService
{
    void Info(Serilog.Events.LogEventLevel.Information info, Message message );
}

public class LoggerService : ILoggerService
{   
    public void Write(LogEventLevel level, Message message) =>
        Serilog.Log.Write(serilogEvents[level], JsonConvert.SerializeObject(message));
        
}

Then you need to create an extension method in your class library to register your service in other projects:然后你需要在你的 class 库中创建一个扩展方法来在其他项目中注册你的服务:

public static class LoggingServiceExtensions
{
    public static IServiceCollection RegisterMyLogger(this IServiceCollection services, 
        IConfiguration configuration)
    {
        Log.Logger = new LoggerConfiguration().ReadFrom
            .Configuration(configuration).CreateLogger();

        services.AddSingleton<ILoggerService, LoggerService>();

        return services;
    }
}

If your are going to use this library in ASP.NET Core MVC or Web API, then just register your library:如果你打算在 ASP.NET Core MVC 或 Web API 中使用这个库,那么只需注册你的库:

public void ConfigureServices(IServiceCollection services)
{
    services.ConfigBaseServiceSettings<AppSettings>(Configuration);
    services.RegisterMyLogger(Configuration);
}

Do not forget to install the following dependencies through NuGet in your class library:不要忘记在 class 库中通过 NuGet 安装以下依赖项:

Serilog 
Serilog.Settings.Configuration

And other libraries if you want:如果需要,还可以使用其他库:

Serilog.Sinks.Console
Serilog.Sinks.Http
Serilog.Sinks.MSSqlServer

I have just a usabillity recommendation based on the answer from honey_ramgarhia我只是根据 honey_ramgarhia 的回答提出了可用性建议

I wraped the serilog usage in a common helper library.我将 serilog 的用法包装在一个通用的帮助库中。 This way only the main program (Service, Webapp, whatever) and the common library needs to reference the serilog nuget package.这样只有主程序(Service、Webapp等)和公共库需要引用serilog nuget package。

public static class LogHelper
{
    public static Logger GetInstance()
    {
        return new LoggerConfiguration()
                .MinimumLevel.Debug()
                .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
                .Enrich.FromLogContext()
                .WriteTo.File(GetLogFilePath())
                .CreateLogger();
    }

    public static void LogText(string text)
    {
        Log.Information(text);
    }

    public static void LogException(Exception ex)
    {
        Log.Fatal(ex.Message + ";" + ex.InnerException + "Stacktrace:" + ex.StackTrace, Encoding.Default);
    }

    public static void End()
    {
        Log.CloseAndFlush();
    }    

}

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

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