DEV Community

Cover image for Using NLog in a .NET 5 Console Application with Dependency Injection and send logs to AWS CloudWatch
Satish Yadav
Satish Yadav

Posted on • Updated on

Using NLog in a .NET 5 Console Application with Dependency Injection and send logs to AWS CloudWatch

Description

Explains how to setup NLog as logging provider for .NET 5 Console Application and Dependency Injection).

Demonstrated with a .NET 5 Console application. Example project can also be found on GitHub.

0. Create a new .NET 5 console project

1. Add dependency in csproj manually or using NuGet

Install:

e.g.

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.0" />
    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.0" />
    <PackageReference Include="NLog" Version="4.6.5" />
    <PackageReference Include="NLog.Extensions.Logging" Version="1.5.1" />
  </ItemGroup>
Enter fullscreen mode Exit fullscreen mode

2. Create a nlog.config file.

Create nlog.config (lowercase all) file in the root of your application project (File Properties: Copy Always)

We use this example:

<?xml version="1.0" encoding="utf-8" ?>
<!-- XSD manual extracted from package NLog.Schema: https://www.nuget.org/packages/NLog.Schema-->
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xsi:schemaLocation="NLog NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      internalLogFile="c:\temp\skylogs\nlog-internal.log"
      internalLogLevel="Info" >

  <!-- the targets to write to -->
  <targets>
    <!-- write logs to file -->
    <target xsi:type="File" name="logfile" fileName="c:\temp\skylogs\skylogs.log"
            layout="${longdate}|${level}|${message} |${all-event-properties} ${exception:format=tostring}" />
    <target xsi:type="Console" name="logconsole"
            layout="${longdate}|${level}|${message} |${all-event-properties} ${exception:format=tostring}" />
  </targets>

  <!-- rules to map from logger name to target -->
  <rules>
    <logger name="*" minlevel="Trace" writeTo="logfile,logconsole" />
  </rules>
</nlog>
Enter fullscreen mode Exit fullscreen mode

It is recommended to read the NLog Tutorial. For more detailed information about config file can be found here.

If you like to include other targets or layout renderers, check the Platform support.

Ensure to configure your project-file to copy NLog.config to the output directory:

 <ItemGroup>
     <None Update="nlog.config" CopyToOutputDirectory="Always" />
 </ItemGroup>
Enter fullscreen mode Exit fullscreen mode

3. Update your program

3.1 Create your Person class

public class Person
{
      public string Name { get; set; }
      private readonly ILogger<Person> _logger;

      public Person(ILogger<Person> logger)
      {
          _logger = logger;
      }

      public void Talk(string text)
      {
          _logger.LogInformation("Person {name} spoke {text}", Name, text);
      }
}
Enter fullscreen mode Exit fullscreen mode

3.2 Setup the Dependency injector (DI) container

private static IServiceProvider BuildDi(IConfiguration config)
{
   return new ServiceCollection()
           //Add DI Classes here
         .AddTransient<Person>() 
         .AddLogging(loggingBuilder =>
         {
             // configure Logging with NLog
             loggingBuilder.ClearProviders();
             loggingBuilder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
             loggingBuilder.AddNLog(config);
         })
         .BuildServiceProvider();
}
Enter fullscreen mode Exit fullscreen mode

3.3 Add required usings

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog;
using NLog.Extensions.Logging;
Enter fullscreen mode Exit fullscreen mode

3.4 Update your Main()

First create the DI container, then get your Person and start running!

static void Main(string[] args)
{
    var logger = LogManager.GetCurrentClassLogger();
    try
    {
        var config = new ConfigurationBuilder()
           .SetBasePath(System.IO.Directory.GetCurrentDirectory())
           .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
           .Build();

        var servicesProvider = BuildDi(config);

        using (servicesProvider as IDisposable)
        {
            var person = servicesProvider.GetRequiredService<Person>();
            person.Name = "Sky";
            person.Talk("Hello");

            Console.WriteLine("Press ANY key to exit");
            Console.ReadKey();
        }
    }
    catch (Exception ex)
    {
        // NLog: catch any exception and log it.
        logger.Error(ex, "Stopped program because of exception");
        throw;
    }
    finally
    {
        // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
        LogManager.Shutdown();
    }
}
private static IServiceProvider BuildDi(IConfiguration config)
{
    return new ServiceCollection()
         //Add DI Classes here
       .AddTransient<Person>() // Runner is the custom class
       .AddLogging(loggingBuilder =>
       {
           // configure Logging with NLog
           loggingBuilder.ClearProviders();
           loggingBuilder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
           loggingBuilder.AddNLog(config);
       })
       .BuildServiceProvider();
}
Enter fullscreen mode Exit fullscreen mode

4 Example output

2021-05-22 12:33:20.8486|Info|Person Sky spoke Hello |name=Sky, text=Hello 
Enter fullscreen mode Exit fullscreen mode

Send Logs to AWS CloudWatch

Here's a sample nlog.config to send NLog logs directly to CloudWatch Logs log group.

<?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"
      throwConfigExceptions="true">
  <extensions>
    <add assembly="NLog.AWS.Logger" />
  </extensions>
  <targets>
    <target name="aws" type="AWSTarget" logGroup="NLog.ConfigExample" region="us-east-1"/>
  </targets>
  <rules>
    <logger name="*" minlevel="Info" writeTo="aws" />
  </rules>
</nlog>
Enter fullscreen mode Exit fullscreen mode

The AWS credentials will be found using the standard AWS SDK for .NET credentials search path. In this case it will look for a profile named default, search for environment variables or search for an instance profile on an EC2 instance. To use a specific AWS credential profile use the profile attribute on the target.

Configure NLog Targets for output

Next step, see Configure NLog with nlog.config

Originally posted at:
https://blog.satishyadav.com/net-core-console-nlog-with-di/

Top comments (0)