.NET Core Web API Logging Using NLog In Event Log

.NET Core Web API Logging Using NLog In Event Log

Nlog is a useful tool for logging the errors and such information in the Event Log. In here, let us see the process of using Nlog for error logging in .NET Core Web API.

Let's get started.

  • Open Visual Studio and create a new project.
  • Select ASP.NEt Core Web Application.
  • Select API as a template and click the OK button.

image.png

Add the Nlog.WindowsEventLog NuGet package.

image.png

Let's create an interface having each kind of different methods to store the logs like Debug, Warning, Information, Error etc.

namespace CoreNLogEventLog  
{  
    public interface ILog  
    {  
        void Information(string message);  
        void Warning(string message);  
        void Debug(string message);  
        void Error(string message);  
    }  
}

Implement the above interface in the class and also, get the CurrentClassLogger through LogManager of Nlog, i.e., logger.

Initialize an instance of LogEventInfo with the log level type, loggername, and message.

    using NLog;  
    using System;  
    using System.Collections.Generic;  

    namespace CoreNLogEventLog  
    {  
        public class LogNLog : ILog  
        {  
            private static ILogger logger = LogManager.GetCurrentClassLogger();  

            public LogNLog()  
            {  
            }  

            public void Debug(string message)  
            {  
                Logger logger = LogManager.GetLogger("EventLogTarget");  
                var logEventInfo = new LogEventInfo(LogLevel.Error, "EventLogMessage", $"{message}, generated at {DateTime.UtcNow}.");  
                logger.Log(logEventInfo);  
                //LogManager.Shutdown();  
            }  

            public void Error(string message)  
            {  
                logger.Error(message);  
            }  

            public void Information(string message)  
            {  
                logger.Info(message);  
            }  

            public void Warning(string message)  
            {  
                logger.Warn(message);  
            }  
        }  
    }

In the startup.cs, load the configuration for Nlog. For now, give the name like nlog.config and give the root path. In the next step, we will add this file and provide the configuration.

Also, we need to add a singleton service of type Ilog with an implementation type LogNLog.

using System;  
using System.Collections.Generic;  
using System.IO;  
using System.Linq;  
using System.Threading.Tasks;  
using Microsoft.AspNetCore.Builder;  
using Microsoft.AspNetCore.Hosting;  
using Microsoft.AspNetCore.Mvc;  
using Microsoft.Extensions.Configuration;  
using Microsoft.Extensions.DependencyInjection;  
using Microsoft.Extensions.Logging;  
using Microsoft.Extensions.Options;  
using NLog;  

namespace CoreNLogEventLog  
{  
    public class Startup  
    {  
        public Startup(IConfiguration configuration)  
        {  
            LogManager.LoadConfiguration(String.Concat(Directory.GetCurrentDirectory(), "/nlog.config"));  
            Configuration = configuration;  
        }  

        public IConfiguration Configuration { get; }  

        // This method gets called by the runtime. Use this method to add services to the container.  
        public void ConfigureServices(IServiceCollection services)  
        {  
            services.AddMvc();  

            services.AddSingleton<ILog, LogNLog>();  
        }  

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.  
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)  
        {  
            if (env.IsDevelopment())  
            {  
                app.UseDeveloperExceptionPage();  
            }  

            app.UseMvc();  
        }  
    }  
}

In nlog.config, we need to configure two paths for logging. One is InternalLog and another is actual log which we want to write. So first, provide the internal log file path to the attribute internalLogFile and second, provide the actual path in the target. Add the assembly which we have added through NuGet package under extensions. Also, configure the rule where we are mentioning that Error as a minimum level and write to the EventLog.

<?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="D:\AKKI_DEV\RND\CoreNLogEventLog\CoreNLogEventLog\LOG\InnerLog.txt">  
    <extensions>  
        <add assembly="Nlog.WindowsEventLog" />  
  </extensions>      
    <variable name="appName" value="NLogEventLog" />  
<targets>  
  <target xsi:type="EventLog"  
  name="eventlog"  
  source="${appName}"  
  layout="${message}${newline}${exception:format=ToString}" Log="Application" machinename="."/>  
</targets>   
  <rules>  
        <logger name="*" writeTo="eventlog" minlevel="Error" />  
  </rules>  
</nlog>

When we create a project with Web API, the values controller will be added with the default CRUD operation. So, let's use the GET method of that controller and try to add a log in the same. Here, we have called the debug kind of log methods from the Controller.

using Microsoft.AspNetCore.Mvc;  
using System.Collections.Generic;  

namespace CoreNLogEventLog.Controllers  
{  
    [Route("api/[controller]")]  
    public class ValuesController : Controller  
    {  

   private ILog logger;  
        public ValuesController(ILog logger)  
        {  
            this.logger = logger;  
        }  


        // GET api/values  
        [HttpGet]  
        public IEnumerable<string> Get()  
        {  
            logger.Debug("Get API called of Values Controller");  

            return new string[] { "value1", "value2" };  
        }  

        // GET api/values/5  
        [HttpGet("{id}")]  
        public string Get(int id)  
        {  
            return "value";  
        }  

        // POST api/values  
        [HttpPost]  
        public void Post([FromBody]string value)  
        {  
        }  

        // PUT api/values/5  
        [HttpPut("{id}")]  
        public void Put(int id, [FromBody]string value)  
        {  
        }  

        // DELETE api/values/5  
        [HttpDelete("{id}")]  
        public void Delete(int id)  
        {  
        }  
    }  
}

Run the application and the GET method of values controller is called. We can see the result of the API.

image.png

Open the "Run" window and type eventvwr which will open the Event Viewer.

image.png

Select the application from the left panel and you can see your log highlighted as below.

image.png

You can download the sample application from here.