Wire and inject NLog into .NET Core console app

前端 未结 3 1198
北恋
北恋 2021-01-11 09:13

I created a consumer/job that I will have running as a process on Linux written in C#.

The process will:

  1. Read a message from RabbitMQ
  2. Make chang
相关标签:
3条回答
  • 2021-01-11 09:59

    A complete minimalistic example of NLog in a .NET Core 1 console app (based on NLog.Extensions.Logging repository):

    var services = new ServiceCollection();
    services.AddLogging();
    var provider = services.BuildServiceProvider();
    
    var factory = provider.GetService<ILoggerFactory>();
    factory.AddNLog();
    factory.ConfigureNLog("nlog.config");
    
    var logger = provider.GetService<ILogger<Program>>();
    logger.LogCritical("hello nlog");
    

    References:

        <ItemGroup>
            <PackageReference Include="NLog.Extensions.Logging" Version="1.0.0-rtm-beta5" />
            <PackageReference Include="Microsoft.Extensions.Configuration" Version="1.1.2" />
            <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="1.1.1" />
            <PackageReference Include="Microsoft.Extensions.Logging" Version="1.1.2" />
        </ItemGroup>
    

    nlog.config:

    <?xml version="1.0" encoding="utf-8" ?>
    <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          internalLogFile="internal-nlog.txt">
    
      <variable name="Layout"
                value="${longdate}|${level:uppercase=true}|${logger}|${message}"/>
    
      <!-- the targets to write to -->
      <targets>
        <!-- write logs to file -->
        <target xsi:type="File" 
                name="allfile" 
                fileName="nlog-all-${shortdate}.log"
                layout="${Layout}" />
    
        <!-- write to the void aka just remove -->
        <target xsi:type="Null" name="blackhole" />
      </targets>
    
      <!-- rules to map from logger name to target -->
      <rules>
        <!--All logs, including from Microsoft-->
        <logger name="*" minlevel="Trace" writeTo="allfile" />
    
        <!--Skip Microsoft logs and so log only own logs-->
        <logger name="Microsoft.*" minlevel="Trace" writeTo="blackhole" final="true" />
      </rules>
    </nlog>
    
    0 讨论(0)
  • 2021-01-11 10:13

    My solution is to use an adapter pattern that uses Console.Writeline, until a more sane version of NLog becomes available.

    using System;
    public static class Log
    {
        public static void Write(string message)
        {
            Console.WriteLine($"{DateTime.Now}: {message}");
        }
    }
    
    0 讨论(0)
  • 2021-01-11 10:19

    In DotNet Core 2 you can use the start up class now and clean up the code a bit to look more like the web one.

    And as a bonus a way to start your app inside the DI container using ConsoleApp

    Program.cs

    static void Main(string[] args)
    {
        IServiceCollection services = new ServiceCollection();
    
        Startup startup = new Startup();
        startup.ConfigureServices(services);
    
        IServiceProvider serviceProvider = services.BuildServiceProvider();
    
        // entry to run app
        serviceProvider.GetService<ConsoleApp>().Run();
    }
    

    Startup.cs

    public class Startup
    {
        IConfigurationRoot Configuration { get; }
    
        public Startup()
        {
            var builder = new ConfigurationBuilder()
              .SetBasePath(Directory.GetCurrentDirectory())
              .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
    
            Configuration = builder.Build();
        }
    
    
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<IConfigurationRoot>(Configuration);
    
            services.AddSingleton<IMyConfiguration, MyConfiguration>();
    
            services.AddLogging(loggingBuilder => {
               loggingBuilder.AddNLog("nlog.config");
            });
    
            services.AddTransient<ConsoleApp>();
        }
    }
    

    ConsoleApp.cs

    public class ConsoleApp
    {
        private readonly ILogger<ConsoleApp> _logger;
        private readonly IMyConfiguration _config;
    
        public ConsoleApp(IMyConfiguration configurationRoot, ILogger<ConsoleApp> logger)
        {
            _logger = logger;
            _config = configurationRoot;
        }
    
    
        public void Run()
        {
            var test = _config.YourItem;
    
            _logger.LogCritical(test);
    
            System.Console.ReadKey();
        }
    }
    

    Configuration.cs

    public class MyConfiguration : IMyConfiguration
    {
    
        IConfigurationRoot _configurationRoot;
        public MyConfiguration(IConfigurationRoot configurationRoot)
        {
            _configurationRoot = configurationRoot;
        }
    
        public string YourItem => _configurationRoot["YourItem"];
    }
    
    
    public interface IMyConfiguration
    {
        string YourItem { get; }
    }
    
    0 讨论(0)
提交回复
热议问题