2017-06-30 3 views
7

Ich erstellt einen Consumer/Job, die ich als ein Prozess auf Linux in C# ausgeführt haben.Verkabelung und injizierte NLog in eine .Net-Core-Konsole-Anwendung

Der Prozess wird: auf

  1. Lesen einer Nachricht von RabbitMQ
  2. Änderungen an der Datenbank
  3. Fehler Log

Alle in der Dokumentation auf nlog über .net Kern sind aspnet Kern. Wenn ich versuche, eine ILogger Implementierung zu erhalten, gibt es null zurück. Hier

ist eine Ausnahme von Verkabelung und Nutzung:

static void ConfigureServices() 
{ 
     string environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); 

     var builder = new ConfigurationBuilder() 
      .SetBasePath(Path.Combine(AppContext.BaseDirectory)) 
      .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) 
      .AddJsonFile($"appsettings.{environment}.json", optional: true); 

     var services = new ServiceCollection(); 

     Configuration = builder.Build(); 

     [...] 

     services.AddLogging(); 

     ServiceProvider = services.BuildServiceProvider(); 

     var loggerFactory = ServiceProvider.GetService<ILoggerFactory>(); 
     loggerFactory.AddNLog(); 
} 

static void Main(string[] args) 
{ 
    ConfigureServices(); 

    var logger = ServiceProvider.GetService<NLog.ILogger>(); 

    logger.Debug("Logging"); 

    [...] 
} 

Sie nicht mit den Umgebungsvariablen ASPNETCORE_ENVIRONMENT verwechselt werden; Es wird nur verwendet, um zu bestimmen, welche appsettings.json verwendet werden soll.

Ich habe meinen Code auf dieser issue report basiert.

Schließlich sind dies die Pakete, die ich derzeit installiert habe.

<ItemGroup> 
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="1.1.2" /> 
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="1.1.2" /> 
    <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="1.1.2" /> 
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="1.1.2" /> 
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.1.2" /> 
    <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="1.1.2" /> 
    <PackageReference Include="NLog" Version="5.0.0-beta09" /> 
    <PackageReference Include="NLog.Extensions.Logging" Version="1.0.0-rtm-beta5" /> 
    <PackageReference Include="Npgsql" Version="3.2.4.1" /> 
    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="1.1.0" /> 
    </ItemGroup> 
+0

Resolve 'Microsoft.Extensions.Logging.ILogger' statt 'NLog.ILogger'. –

+0

@IlyaChumakov wird das nicht nur geben Sie mir die msft Logger und route alle meine Protokolle durch msft Protokollierung? –

+0

Eigentlich habe ich das gerade getestet, und "Logger" ist immer noch null. –

Antwort

13

komplettes minimalistisches Beispiel für NLog Verwendung in einer .NET-Core-Konsolenanwendung (basierend auf 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"); 

Referenzen:

<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> 
-4

Meine Lösung besteht darin, ein Adaptermuster zu verwenden, das Console.Writeline verwendet, bis eine normalere Version von NLog verfügbar wird.

+1

Wenn Sie Microsoft.Extensions.Logging verwenden, erhalten Sie Unterstützung für die strukturierte Protokollierung. Und die Fähigkeit, dynamische Filterung durchzuführen und Ihre Logging-Senke/Ziel mit Ihrer bevorzugten Wahl zu ersetzen. Wenn Sie nur eine Konsolenprotokollierung durchführen möchten, müssen Sie kein Protokollierungsframework auswählen. –

0

In DotNet Core 2 können Sie jetzt die Startup-Klasse verwenden und den Code ein wenig aufräumen, um mehr wie das Web zu sehen.

Und als Bonus eine Möglichkeit, Ihre App innerhalb des DI-Container zu beginnen 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.AddSingleton(new LoggerFactory() 
       .AddNLog() 
       .ConfigureNLog("nlog.config") 
       ); 

     services.AddLogging(); 

     services.AddTransient<ConsoleApp>(); 
    } 

} 

KonsolenApp.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; } 
}