Configure Nlog with Elasticsearch in ASP.NET Core

It’s always nice to have logs from our applications. Nlog is a solid open-source library in .NET that supports save the logs. However, when we add elasticsearch to it, searching for specific logs will be simpler. In a short tutorial I will show you how to combine these two tools.

Example

In a first step we must to add the dependencies presented below.

<PackageReference Include="NLog.Extensions.Logging" Version="1.0.0-rtm-rc7" />
<PackageReference Include="NLog.Targets.ElasticSearch" Version="4.0.0-beta26" />
<PackageReference Include="NLog.Web.AspNetCore" Version="4.5.0-rc3" />
<PackageReference Include="NLog" Version="4.5.0-rc06" />

In NLog.config file we need to add extension for elasticsearch.

  <extensions>
    <add assembly="NLog.Targets.ElasticSearch"/>
  </extensions>

Then add specific target for Elasticsearch. NLog.conifg should looks like below (with additional comments for save nlog to file).

<?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"
      autoReload="true"
      internalLogLevel="Trace"
      internalLogFile="C\Log\internal-nlog.txt">

  <extensions>
    <add assembly="NLog.Targets.ElasticSearch"/>
  </extensions>
  <!-- the targets to write to -->
  <targets>
    <target name="ElasticSearch" xsi:type="BufferingWrapper" flushTimeout="5000">
      <target xsi:type="ElasticSearch"/>
    </target>
    <!-- write logs to file  -->
    <!--<target xsi:type="File" name="allfile" fileName="c:\Log\nlog-all-${shortdate}.log"/>

    --><!-- another file log, only own logs. Uses some ASP.NET core renderers --><!--
    <target xsi:type="File" name="ownFile-web" fileName="c:\Log\nlog-own-${shortdate}.log" />-->
  </targets>

  <!-- rules to map from logger name to target -->
  <rules>
    <!--All logs, including from Microsoft-->
    <logger name="*" minlevel="Debug" writeTo="ElasticSearch" />
    <!--<logger name="*" minlevel="Debug" writeTo="allfile" />
    --><!--Skip non-critical Microsoft logs and so log only own logs--><!--
    <logger name="Microsoft.*" minlevel="Trace" final="true" />
     --><!--BlackHole without writeTo--><!-- 
    <logger name="*" minlevel="Trace" writeTo="ownFile-web" />-->
  </rules>
</nlog>

In appsettings.json assign the appropriate address with port on which elasticsearch works.

"ElasticsearchUrl": "http://localhost:9200"

At the end we need to register IHttpContextAccessor.

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

And add code for read configuration and register NLog.

env.ConfigureNLog("NLog.config");
loggerFactory.AddNLog();

*Note that Nlog.config must have option selected in propertis: Copy to Output Directory to Copy always.

Now it’s enough to inject dependencies through the constructor and start to log “some” information.

private readonly ILogger<SomeClass> _logger;
public SomeClass(ILogger<SomeClass> logger) 
{
    _logger = logger;
}

public void SomeMethod()
{
    try
    {
        throw new Exception("FATAL ERROR");
    }
    catch (Exception e)
    {
        _logger.LogError($"{e.Message}, Track to error{e.StackTrace}");
        _logger.LogInformation("Error");
    }
}

In this way we can use the benefits of elasticsearch – typing the appropriate url in the browser like:

For searching logs http://localhost:9200/logstash-“date”/_search?q=error or check aliases on http://localhost:9200/_aliases etc.

API Elasticsearch documentation.

Leave a Reply

Your email address will not be published. Required fields are marked *