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.