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.
