Logging and Error Handling | Exception Handling

Logging and Error Handling | Exception Handling , ANGULAR WITH CORE .NET AND MVC RAZOR ENGINE

 Logging and Error Handling | Exception handling Mechanism

Application logging plays a crucial role in tracking and identifying issues that may surface as well as in providing useful insights into the workflow processes of solutions. When things go wrong, one of the first sources to look at is the application’s log. Depending on the number of details that are logged, each entry represents an action that occurred at a specific date and time.

Logs can contain system-generated events as well as events explicitly defined by
the developer and are usually grouped into categories like errors, informational, and
warning. Application logs are application-specific, hence the name, and do not often
include OS-specific events.

Let's begin

Adding Logging 

Logging can be used anywhere in ASP.NET Core, and to create a log we merely need to inject an ILogger object that was previously registered in the DI container. Before logging can be used, the specific logging configuration first needs to be added to the host. Looking at the ILogger interface, it exposes a Log method that we can use to write the specific type of entry and exception to the configured logging providers:

namespace Microsoft.Extensions.Logging
{   
    public interface ILogger
    {        
        IDisposable BeginScope<TState>(TState state);
        bool IsEnabled(LogLevel logLevel);       
        void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception,          Func<TState, Exception, string> formatter);
    }
}


Have a look on below piece of code for adding log mechanism

using System;

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace My_First_API
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<IComponent, ComponentB>();
        }
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
        {
            logger.Log(LogLevel.Information, "Welcome in configure method", null);
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseRouting();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });
        }
    }
}

Now run your application and check below Image.




Check below LogLevel enumeration


  public enum LogLevel
    {
        //
        // Summary:
        //     Logs that contain the most detailed messages. These messages may contain sensitive
        //     application data. These messages are disabled by default and should never be
        //     enabled in a production environment.
        Trace = 0,
        //
        // Summary:
        //     Logs that are used for interactive investigation during development. These logs
        //     should primarily contain information useful for debugging and have no long-term
        //     value.
        Debug = 1,
        //
        // Summary:
        //     Logs that track the general flow of the application. These logs should have long-term
        //     value.
        Information = 2,
        //
        // Summary:
        //     Logs that highlight an abnormal or unexpected event in the application flow,
        //     but do not otherwise cause the application execution to stop.
        Warning = 3,
        //
        // Summary:
        //     Logs that highlight when the current flow of execution is stopped due to a failure.
        //     These should indicate a failure in the current activity, not an application-wide
        //     failure.
        Error = 4,
        //
        // Summary:
        //     Logs that describe an unrecoverable application or system crash, or a catastrophic
        //     failure that requires immediate attention.
        Critical = 5,
        //
        // Summary:
        //     Not used for writing log messages. Specifies that a logging category should not
        //     write any messages.
        None = 6
    }


Log Anatomy

When creating logs, we need to map it to a category string, which is used during the
output of the entry. As we saw in the previous section, a log is typically created to be used.

Check below piece of Code

   public class Program

    {

        private readonly ILoggerFactory loggerFactory;

        public Program(ILoggerFactory loggerFactory)

        {

            this.loggerFactory = loggerFactory;

            var constructorLogger = loggerFactory.CreateLogger("Program.ctor");

            constructorLogger.LogInformation("Logging from constructor!");

        }

}

inside a specific class, which is thus the Program.

Grouping and Filtering

At times it is necessary to capture more details of a given transaction or process. We can
group a set of logical operations with the same log information by using scopes, which
are IDisposable objects that result from calling ILogger.BeginScope<TState> and last
until they are disposed of. Let’s use a scope to group some of the log entries inside the
Configure method:

Have a look on below piece of code

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger, ILoggerFactory loggerFactory)
        {
            logger.Log(LogLevel.Information, "Welcome in configure method", null);
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
           
            var constructorLogger = loggerFactory.CreateLogger("Program.ctor");
            constructorLogger.LogInformation("Logging from constructor!");
            using (constructorLogger.BeginScope("You are in program class"))
            {
                constructorLogger.Log(LogLevel.Information, "You are in Program.ctor");
                constructorLogger.Log(LogLevel.Warning, "Warning message from Program.ctor");
                constructorLogger.Log(LogLevel.Error, "Error Message from Progream.ctor");
            }

            app.UseRouting();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });
        }



   

Note: You need to modify the below code also in the program.cs file to get the grouping and filtering.

 public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                }).ConfigureLogging(logging =>
                {
                    logging.AddConsole(x => x.IncludeScopes = true);    // You need to add this line
                });


Modify the above code and hit the F5 button to get the expected response, check below snapshot



Exception Mechanism

It is essential that our applications deal with any exception that might occur. This ties in
with the fact that logging is significant for debugging critical issues. As developers, we
tend to be lazy, and looking up problems in a log file isn’t always the best solution while
developing.

To help us gain instant insight into why a particular request goes wrong, we can
make use of special developer exception pages provided by ASP.NET Core. They are
HTML-based pages generated by the runtime that encapsulates all the useful information
around the problem, like the stack trace, for instance.

Check below piece of Code

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger, ILoggerFactory loggerFactory)
        {
            logger.Log(LogLevel.Information, "Welcome in configure method", null);
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
}

Note: We should enable this only in a development environment as we do not want to expose any sensitive information on production

With ❤️ Happy Coding

Comments

Post a Comment

Popular posts from this blog

React Native Fundamentals

What’s the Difference Between Razor and Blazor

How to disable table row in Angular