Exception Handling with a Centralized Logging System in Dotnet

Lawson Borges
By -
0

Exception Handling with a Centralized Logging System in Dotnet


Streamline Exception Handling with a Centralized Logging System in the world of software development, ensuring your application runs smoothly in a production environment is paramount. One aspect that demands meticulous attention is handling exceptions gracefully. While try-catch-finally blocks are a tried-and-true method, a smarter approach exists: Creating a generic exception-logging system and Exception Handling with a Centralized Logging System in Dotnet.



Exception Handling with a Centralized Logging System In MVC and WebAPI


The Pitfalls of Manual Exception Handling:
1)The DRY Principle: DRY, or "Don't Repeat Yourself," is a fundamental coding principle. Manual exception handling often leads to repetitive code scattered throughout your application. This redundancy not only clutters your codebase but also opens the door to potential bugs and inconsistencies.

2)Maintenance Woes: As time goes on, changes in your logging requirements are inevitable. When that happens, updating logging mechanisms manually across your entire application can be a daunting and error-prone task. This could result in a nightmare of inconsistencies and reliability issues.

Embracing a Generic Exception-Logging System:

The solution is elegantly simple: a centralized exception-logging system that acts as the cornerstone of your error-handling strategy.

Benefits at a Glance:

Centralized Logging: In this system, you funnel all your exceptions into a single, well-organized location. This not only simplifies your code but also makes it a breeze to trace and troubleshoot issues.

Effortless Maintenance: When logging requirements evolve (as they inevitably do), you won't need to painstakingly update logging code spread across your entire application. Instead, a single update to the generic logging system suffices, minimizing the risk of introducing errors.

Speedier Development: By integrating a generic logging system, you harness the power of tried-and-tested code. This efficiency translates to shorter development cycles and a more agile response to changing requirements.


Implementing a Generic Exception-Logging System:

Here's a simplified code snippet to illustrate how a generic exception-logging system might look in practice in .net 7:

In Program.cs file Add 

  1. builder.Services.AddControllers(options =>  
  2. {  
  3.     options.Filters.Add(typeof(ExceptionalHandler));  
  4. });  

Create an ExceptionalHandler.cs file 
  1. public class ExceptionalHandler : IExceptionFilter  
  2.    {  
  3.        private readonly IGenericService _genericService;  
  4.        private readonly IExceptionLogger _exceptionLogger;  
  5.   
  6.        public ExceptionalHandler(IGenericService genericService, IExceptionLogger exceptionLogger)  
  7.        {  
  8.            _genericService = genericService;  
  9.            _exceptionLogger = exceptionLogger;  
  10.        }  
  11.   
  12.        public void OnException(ExceptionContext context)  
  13.        {  
  14.            //log details  
  15.            _exceptionLogger.LogDetails(ExceptionLoggerType.DB, context.Exception, context.HttpContext.Request.Path);  
  16.            //process  
  17.   
  18.            context.Result = new ObjectResult(_genericService.GetResponse(ResponseStatusMessageType.InternalServerError))  
  19.            {  
  20.                StatusCode = 500  
  21.            };  
  22.        }  
  23.    }  

Create a ExceptionLogger.cs  file 

  1. public class ExceptionLogger : IExceptionLogger  
  2.     {  
  3.         private readonly IConfiguration _configuration;  
  4.         private readonly ISqlRepository _sqlRepository;  
  5.   
  6.         public ExceptionLogger(IConfiguration configuration, ISqlRepository sqlRepository)  
  7.         {  
  8.             _configuration = configuration;  
  9.             _sqlRepository = sqlRepository;  
  10.         }  
  11.   
  12.         /// <summary>  
  13.         /// Store log of the error details in file or database  
  14.         /// </summary>  
  15.         /// <param name="ExceptionLoggerType"></param>  
  16.         /// <param name="exception"></param>  
  17.         /// <param name="otherDetails"></param>  
  18.         /// <returns></returns>  
  19.         public async Task LogDetails(ExceptionLoggerType ExceptionLoggerType, Exception exception, string otherDetails = "")  
  20.         {  
  21.             switch (ExceptionLoggerType)  
  22.             {  
  23.                 case ExceptionLoggerType.File:  
  24.                     await LogInFile(exception, otherDetails);  
  25.                     break;  
  26.   
  27.                 case ExceptionLoggerType.DB:  
  28.                     await LogInDB(exception, otherDetails);  
  29.                     break;  
  30.   
  31.                 case ExceptionLoggerType.All:  
  32.                     await LogInDB(exception, otherDetails);  
  33.                     await LogInFile(exception, otherDetails);  
  34.                     break;  
  35.             }  
  36.         }  
  37.   
  38.         private async Task LogInFile(Exception exception, string otherDetails = "")  
  39.         {  
  40.             var filePath = _configuration["FilePath:LogFilePath"];  
  41.   
  42.             if (!Directory.Exists(filePath))  
  43.                 Directory.CreateDirectory(filePath);  
  44.   
  45.             filePath = filePath + DateTime.Today.ToString("dd-MM-yy") + ".txt";  
  46.   
  47.             if (!File.Exists(filePath))  
  48.                 File.Create(filePath).Dispose();  
  49.   
  50.             using var writer = new StreamWriter(filePath, true);  
  51.             writer.WriteLine("------------------------- Log starts from here -------------------------------------");  
  52.             writer.WriteLine("Date : " + DateTime.Now.ToString());  
  53.             writer.WriteLine("-----------------------------------------------------------------------------");  
  54.             writer.WriteLine($"Other details Log : {otherDetails}");  
  55.             writer.WriteLine("-----------------------------------------------------------------------------");  
  56.   
  57.             if (exception != null)  
  58.             {  
  59.                 writer.WriteLine(exception.GetType().FullName);  
  60.                 writer.WriteLine($"Message : {exception.Message}");  
  61.                 writer.WriteLine($"StackTrace : {exception.StackTrace}");  
  62.             }  
  63.   
  64.             writer.WriteLine("------------------------- Log ends here -------------------------------------");  
  65.             await writer.WriteLineAsync();  
  66.   
  67.             writer.Close();  
  68.             await writer.DisposeAsync();  
  69.         }  
  70.   
  71.         private async Task LogInDB(Exception exception, string source)  
  72.         {  
  73.             string procedure = _configuration["Procedure:PostException"];  
  74.   
  75.             try  
  76.             {  
  77.                 List<SqlParameter> parameters = new List<SqlParameter>  
  78.                 {  
  79.                     new SqlParameter("@source", source),  
  80.                     new SqlParameter("@message", exception.Message),  
  81.                     new SqlParameter("@type", exception.GetType().Name),  
  82.                     new SqlParameter("@stackTrace", exception.StackTrace),  
  83.                 };  
  84.   
  85.                 await Task.Run(() => _sqlRepository.ExecuteNonQuery(procedure, parameters));  
  86.             }  
  87.             catch (Exception ex)  
  88.             {  
  89.                 await LogInFile(ex, "LogInDB");  
  90.             }  
  91.         }  
  92.     }  

Conclusion:

Integrating a generic exception-logging system into your application is a strategic move that enhances code maintainability, reduces development time, and bolsters reliability. By centralizing exception handling and logging, you streamline your ability to adapt to changing requirements, setting your software up for success.

For a deeper dive into best practices for exception handling and logging, explore our comprehensive guide clicking here.

Incorporate these practices into your development workflow, and watch your application become more resilient and easier to manage in the long run.


Tags:

Post a Comment

0Comments

Post a Comment (0)