Net Core 2 Serilog, внедряемый из консольного приложения в веб-хост

Я хотел бы знать, как управлять и лучше всего переносить экземпляр Serilog из консольного приложения в класс StartUp, который настраивает веб-хост.

Сценарий:

У меня есть класс Main из консольного приложения, в котором я настраиваю регистратор (серилог). Пространство имен 1

 static void Main(string[] args)
    {
        DateTime Date = new DateTime.Now;
           Log.Logger = = new LoggerConfiguration()
         .MinimumLevel.Debug()
         .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
         .Enrich.FromLogContext()
         .WriteTo.Console()
         .WriteTo.File($"Log-Startup-{Date}.txt", rollingInterval: 
RollingInterval.Day, outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff 
zzz}")
         .CreateLogger();

[...]

`StaticLauncherClass.Launch(args, config, Log.Logger)`;

Обратите внимание, что после этого я просто вызываю метод статического класса и передаю Logger.

Статический класс должен настраивать веб-хост как типичное приложение для веб-хоста в сетевом ядре 2. Launch Method делает что-то вроде. Пространство имен2

      public static IConfiguration Config { get; private set; }


public static void Launch(string[] args, IConfigurationSection config, 
ILogger logger)
        {
            Log.Logger = logger;
            Config = config;
            CreateWebHostBuilder(args).Build().Run();
        }


      public static IWebHostBuilder CreateWebHostBuilder(string[] args)
        {
            Log.Information("Starting web host");
  Serilog.ILogger _logger = Log.Logger;
            try
            {
                return CreateWebhostBuilder(args)
                        // Use Serilog
                        // Evitar inicio de hospedaje
                        .UseSerilog()
                        .UseSetting(WebHostDefaults.PreventHostingStartupKey, 
"true")
                    .ConfigureServices(svc =>
{
    svc.AddSingleton(_logger);
})
                        .UseStartup<Startup>();
            }
[...]
}

В том же классе, наконец, CreateWebhostBuilder (args) настраивает веб-хост

 var builder = new WebHostBuilder()
           .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                var env = hostingContext.HostingEnvironment;

                if (env.IsDevelopment())
                {
                    var appAssembly = Assembly.Load(new 
AssemblyName(env.ApplicationName));
                    if (appAssembly != null)
                    {
                        config.AddUserSecrets(appAssembly, optional: true);
                    }
                }

                if (args != null)
                {
                    config.AddCommandLine(args);
                }
                config.SetBasePath(Directory.GetCurrentDirectory());
                // Add settings to bootstrap EF config.
            })

            .UseIISIntegration()
            .UseDefaultServiceProvider((context, options) =>
            {
                options.ValidateScopes = 
context.HostingEnvironment.IsDevelopment();
            });


    return builder;

И затем мой вопрос, как в этом сценарии я могу использовать мой Регистратор в используемом классе Startup. Я намерен сделать регистратор лучше и проще в мире. Какие решения вы преследуете?

 internal class Startup {
???
???
 public Startup(IConfiguration config, IHostingEnvironment environment)
    {       
        ???
    }

   public void ConfigureServices(IServiceCollection services)
    {
        Console.WriteLine("Startup");
        Log.Information("Startup: Configure services");
    }
}

Класс Startup записывает содержимое Console.WriteLine, но не записывает содержимое Log.Information. Изменить: фактический статус, запустить службу в автозагрузку, но не применять конфигурацию, предоставленную для входа в файл. Думаю, действует просто по умолчанию.


person Sam    schedule 30.06.2018    source источник
comment
Мне кажется, что в вашем сценарии рекомендуется просто использовать статическое свойство Serilog.Log.Logger. Я не вижу никаких преимуществ в использовании экземпляра с ограниченной областью видимости внутри вашего Program класса.   -  person Federico Dipuma    schedule 30.06.2018
comment
@FedericoDipuma, это правда. Я изменил код. Но как я мог пройти (и войти) из класса запуска?   -  person Sam    schedule 30.06.2018
comment
Теперь, когда у вас есть статический экземпляр, вы можете просто использовать Log.Info() (и другие методы) из своего класса запуска.   -  person Federico Dipuma    schedule 30.06.2018
comment
Дело в том, что я занимаюсь Log.Information (Startup: Configure services); из метода ConfigureServices, и он ничего не записывает в консоль или файл, и я не знаю, что мне не хватает.   -  person Sam    schedule 30.06.2018
comment
Вы уверены, что ваш ConfigureServices метод когда-либо вызывается? Пробовали ли вы в него поставить точку торможения?   -  person Federico Dipuma    schedule 30.06.2018
comment
да. И если я сделаю Console.WriteLine (Бла-бла) внутри ConfigureServices, он будет работать как обычно. Я использую Serilog; также .. Вы хоть представляете, что может быть не так?   -  person Sam    schedule 30.06.2018
comment
Не совсем. Можете ли вы обновить свой вопрос, внося изменения? Он по-прежнему использует старый экземпляр регистратора.   -  person Federico Dipuma    schedule 30.06.2018
comment
Я обновил сообщение фактическим кодом. Класс Startup записывает содержимое Console.WriteLine, но не записывает содержимое Log.Information   -  person Sam    schedule 30.06.2018
comment
В своем сообщении вы не добавили всю информацию, необходимую для поиска вашей проблемы, но из репозитория github, который вы опубликовали ранее, ясно, что вы выполняете Log.CloseAndFlush(); сразу после создания WebHostBuilder (что, конечно, немедленно закроет текущий журнал). Вот почему после этого вы не видите никаких журналов. Пожалуйста, добавьте полный код к вашему вопросу.   -  person Federico Dipuma    schedule 03.07.2018
comment
Собственно вы нашли мою ошибку. Спасибо. Я скоро опубликую полное решение для этого сценария. Большое спасибо, так как я был немного увлечен этим, пытаясь понять, что происходит, и я забыл это объявление, исходящее из фрагмента, который я взял из документации ... Действительно, спасибо.   -  person Sam    schedule 05.07.2018


Ответы (1)


Вы можете зарегистрировать свой логгер ConfigureServices методом:

var builder = new WebHostBuilder()
            .UseKestrel()

            ...

            .UseIISIntegration()
            .ConfigureServices(servicesCollection =>
            {
                servicesCollection.AddSingleton<Serilog.ILogger>(logger);              
            })
            .UseDefaultServiceProvider((context, options) =>
            {
                options.ValidateScopes = 
context.HostingEnvironment.IsDevelopment();
            });
person Alex Riabov    schedule 30.06.2018