S
S
sudo rm -rf /2022-04-07 23:13:17
.NET
sudo rm -rf /, 2022-04-07 23:13:17

How to configure Worker Service to log Entity Framework requests via NLog?

I am writing a test Working Service application in C# that uses a database.
I use NLog for logging .

When configuring the database context to enable logging of the process of working with the database, it is possible to use the UseLoggerFactory(ILoggerFactory).

The problem is that it NLog.LogFactory doesn't inherit ILoggerFactory .
If I were writing not Working Service , but an ASP.NET Core application, I could use the NLog.Web.AspNetCore library for these purposes . This library does not support my project type .

The host configuration process for these two types of projects is almost identical., however, the direct approach to solving this issue is only for ASP.NET Core applications.

Maybe someone faced such a problem?
Is there a workaround ?

UPD1 : I am attaching a host configuration listing

Program.cs

var logger = LogManager.GetCurrentClassLogger();

try
{
    logger.Info($"Начинаю запуск приожения {AppDomain.CurrentDomain.FriendlyName}...");

    IHost host = Host.CreateDefaultBuilder(args)
        .ConfigureLogging((hostContext, logging) =>
        {
            logging.ClearProviders();
            logging.SetMinimumLevel(LogLevel.Trace);

            logger.Info("Логгирование сконфигурировано");
        })
        .UseNLog()
        .ConfigureServices((hostContext, services) =>
        {
            services.AddHostedService<Worker>();
            services.AddDbContext<MariaDbContext>(options =>
            {
                Version version = new(10, 3, 34);
                ServerVersion serverVersion = ServerVersion.Create(version, ServerType.MariaDb);

                // options.UseLoggerFactory();

                string connectionString = hostContext.Configuration.GetConnectionString("MariaDataBase");
                options.UseMySql(connectionString, serverVersion);

                logger.Info("Контекст базы данных добвален");
            }, ServiceLifetime.Transient, ServiceLifetime.Transient);

            logger.Info("Сервисы сконфигурированы");
        })
        .Build();

    logger.Info($"Запускаю");
    await host.RunAsync();
}

catch (Exception ex)
{
    if (ex is OperationCanceledException)
    {
        logger.Info("Запрошена остановка приложения");
    }

    else
    {
        logger.Fatal(ex, "Приложение остановлено из-за непридвиденной ошибки");
    }
}

finally
{
    logger.Info("Завершаю работу приложения");
    LogManager.Shutdown();
}

Answer the question

In order to leave comments, you need to log in

2 answer(s)
V
Vasily Bannikov, 2022-04-07
@MaxLevs

You need the NLog.Extensions.Logging package:
https://github.com/NLog/NLog.Extensions.Logging
But in general I advise you to switch to serilog.

M
Morrowind, 2022-04-08
@hekkaaa

Hey!
Here is my version of connecting Nlog to such a service on .NET 6
The process of connecting and using it through DI further took from this example
. Maybe I missed a couple of "brackets", but this is what Program.cs looks like :

IHost host = Host.CreateDefaultBuilder(args)
    .ConfigureHostConfiguration(builder =>
    {
        builder.SetBasePath(System.IO.Directory.GetCurrentDirectory());
    
    })

    .ConfigureServices(services =>
    {
        services.AddHostedService<Worker>();
      var config = new ConfigurationBuilder()
              .SetBasePath(System.IO.Directory.GetCurrentDirectory())
              .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
              .AddEnvironmentVariables()
              .Build();
     
        services.AddSingleton<IRunner, Runner>()
        .AddLogging(loggingBuilder =>
        {
            // configure Logging with NLog
            loggingBuilder.ClearProviders();
            loggingBuilder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Debug);
            loggingBuilder.AddNLog(config);
        });
        services.AddSingleton<IEmailService, EmailService>();
        services.AddSingleton<IClientSmtp, SmtpClientGoogleAsync>();
        services.AddSingleton<ICheckingSubEmailService, CheckingSubEmailService>();
    })
    .UseWindowsService()
    .Build();

After in such an instance in the documentation there is a part where the class Running is created, there you just throw a POST request into your database. All this is done on DI is not very difficult.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question