Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

.NET Core 2.0 Angular 4, and MySQL Part 3 Logging with NLog

DZone's Guide to

.NET Core 2.0 Angular 4, and MySQL Part 3 Logging with NLog

Logging messages are a great way to find out what went wrong and where errors are in your code. Learn how to implement this in .NET Core.

· Web Dev Zone ·
Free Resource

Deploying code to production can be filled with uncertainty. Reduce the risks, and deploy earlier and more often. Download this free guide to learn more. Brought to you in partnership with Rollbar.

Why is logging so important during application development? Well, while your application is in the developing stage, it is very easy to debug the code and to find out what went wrong. But, can you debug in the production environment?

Of course not.

That is why logging messages are a great way to find out what went wrong and where errors happened in your code in the production environment. .NET Core has its own implementation of logging messages, but in all my projects, I prefer to create my own custom logger service.

This is what I am going to show you in this post.

If you want to see all the basic instructions and complete navigation for this series, please follow the following link: Introduction page for this tutorial.

For the previous part check out: Part 2 - Creating .NET Core WebApi project - Basic code preparations

Source code to download is available at this link: .NET Core, Angular 4 and MySQL. Part 3 - Source Code

This post is divided into several sections:

Creating Required Projects

Let's create two new projects. Name the first one Contracts. You are going to store interfaces inside this project. Name the second one LoggerService. You are going to use it for logger logic.

To create a new project, right click on the solution window, choose Add and then NewProject. Under .NET Core, choose Class Library (.NET Core) and name it Contracts.

Do the same thing for the second project, just name it LoggerService.

With these two projects in place, you need to reference them to your main project. In the main project inside solution explorer, right click on Dependencies and choose AddReference. Under Projects, click Solution and check both projects.

Also, add a reference from the Contracts project to the LoggerService project.

Creating Interface and Installing NLog

Our logger service will contain four methods of logging:

  • info messages
  • debug messages
  • warning messages
  • error messages

Consequently, you will create an interface, ILoggerManager, inside the Contracts project, containing those four method definitions.

Add the following code to the ILoggerManager interface:

namespace Contracts
{
    public interface ILoggerManager
    {
        void LogInfo(string message);
        void LogWarn(string message);
        void LogDebug(string message);
        void LogError(string message);
    }
}

Before you implement this interface inside the LoggerService project, you need to install the NLog library in our LoggerService project. NLog is a logging platform for .NET which will help us create and log our massages.

I'll show you two ways of how to add an NLog library into your project.

Example 1:

Example 2:

After a couple of seconds, NLog is up and running in your app.

Implementing Interface and nlog.config file

In the LoggerService project, create a new class, LoggerManager.

Add the following implementation:

using Contracts;
using NLog;
using System;

namespace LoggerService
{
    public class LoggerManager : ILoggerManager
    {
        private static ILogger logger = LogManager.GetCurrentClassLogger();

        public LoggerManager()
        {
        }

        public void LogDebug(string message)
        {
            logger.Debug(message);
        }

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

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

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

Now, we need to configure it and inject it into the Startup class in the ConfigureServices method.

NLog needs to have information about the folder to create log files in it, what the name of these files will be, and what a minimum level of logging is. Therefore, you need to create one text file in the main project with the name nlog.config and populate it as in the example below. You need to change the path of the internal log and filename parameters to your paths.

<?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:Projects\Blog-AccountOwner\Project\internal_logs\internallog.txt">

  <extensions>
    <add assembly="NLog.Extended" />
  </extensions>

  <targets>
    <target name="logfile" xsi:type="File"
            fileName="d:/Projects/Blog-AccountOwner/Project/logs/${shortdate}_logfile.txt"
            layout="${longdate} ${level:uppercase=true} ${message}"/>
  </targets>

  <rules>
    <logger name="*" minlevel="Debug" writeTo="logfile" />
  </rules>
</nlog>

Configuring Logger Service

Setting up the configuration for a logger service is quite easy.

First, you must update the constructor in the Startup class with following code:

public Startup(IConfiguration configuration, ILoggerFactory loggerFactory)
{
    loggerFactory.ConfigureNLog(String.Concat(Directory.GetCurrentDirectory(), "/nlog.config"));
    Configuration = configuration;
}

ILoggerFactory has its implementation inside .NET Core and it serves the purpose of configuring the logging system inside it. With the extension method ConfigureNLog, we are forcing ILoggerFactory to apply the configuration of our new logger from the XML file.

Secondly, you need to add the logger service inside .NET Core's IOC container. There are three ways to do that:

  • By calling services.AddSingleton which will create the service the first time you request it and then every subsequent request is calling the same instance of the service. This means that all components are sharing the same service every time they need it. You are always using the same instance.
  • By calling services.AddScoped which will create the service once per request. That means whenever we send the HTTP request towards the application, a new instance of the service is created.
  • By calling services.AddTransient which will create the service each time the application requests it. This means that if during one request towards our application, multiple components need the service, this service will be created again for every single component that needs it.

So, in the ServiceExtensions class, add the following method:

public static void ConfigureLoggerService(this IServiceCollection services)
{
    services.AddSingleton<ILoggerManager, LoggerManager>();
}

Lastly, in ConfigureServices method invoke this extension method, right above services.AddMvc() with this code:

services.ConfigureLoggerService();

Every time you want to use a logger service, all you need to do is to inject it into the constructor of the class that is going to use that service. .NET Core will serve you that service from the IOC container and all of its features will be available to use. This type of injecting of objects is called Dependency Injection.

DI, IOC, and Logger Service Testing

What is exactly Dependency Injection(DI) and what is IOC (Inversion of Control)?

Dependency injection is a technique for achieving loose coupling between objects and their dependencies. It means that rather than instantiating objects every time it is needed, we can instantiate it once and then serve it in a class, most often, through a constructor method. This specific approach is also known as Constructor Injection.

In a system that is designed to use DI, you may find many classes requesting their dependencies via their constructor. In that case, it is helpful to have a class which will provide all instances to classes through the constructor. These classes are referred to as containers or, more specifically, Inversion of Control containers. An IOC container is essentially a factory that is responsible for providing instances of types that are requested from it.

For the testing purpose of the logger service, you could use ValuesController. You will find it in the main project in Controllers folder.

In Solution Explorer, open the Controllers folder and open the ValuesController class. Update it like this:

[Route("api/[controller]")]
public class ValuesController : Controller
{
    private ILoggerManager _logger;

    public ValuesController(ILoggerManager logger)
    {
        _logger = logger;
    }
    // GET api/values
    [HttpGet]
    public IEnumerable<string> Get()
    {
        _logger.LogInfo("Here is info message from our values controller.");
        _logger.LogDebug("Here is debug message from our values controller.");
        _logger.LogWarn("Here is warn message from our values controller.");
        _logger.LogError("Here is error message from our values controller.");

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

After that, start the application, and browse to http://localhost:5000/api/values. As a result, you will see an array of two strings. Now go to the folder that you have specified in nlog.config file, and check out the result. You should see four lines logged inside that file.

Conclusion

Now you have the working logger service, you will use through the entire development process.

By reading this post you've learned:

  • Why logging is important.
  • How to create an external service.
  • How to use an NLog library and how to configure it.
  • What DI and IOC are.
  • How to use DI and IOC for service injection.

Thank you for reading and see you soon in the next blog post where we will talk about repository pattern with entity framework core.

If you have any suggestions or questions please don't hesitate to leave the comment in the comments section below.

Deploying code to production can be filled with uncertainty. Reduce the risks, and deploy earlier and more often. Download this free guide to learn more. Brought to you in partnership with Rollbar.

Topics:
web dev ,.net core ,angular ,mysql

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}