Logging Exceptions in ASP.NET Core Web API

logging exceptions in ASP.NET Core

Logging Exceptions in ASP.NET Core is a very important thing even in any web application. When we have a lot of users on our application so it will be very easy for us to track the exception and solve this by simply checking the exception records. We do not have to test a lot to find the error.

In this tutorial, we will learn how we can log errors into our database in the ASP.NET Core Web API project.

Tools:

We are using Visual Studio Community 2019, .NET Core version 5, and MSSQL Database.

Lets start:

To add exception logs we have to create a table in the database. Create a class/model.

public class ExceptionLog
    {
        public Guid Id { get; set; }
        public Guid? UserId { get; set; }
        public DateTime DataTime { get; set; }
        public string Reference { get; set; }
        public string IPInfo { get; set; }
        public string ErrorDescription { get; set; }
        public string Data { get; set; }
        public string StackTrace { get; set; }
    }

And Add this to “ApplicationDbContext.cs”.

public DbSet<ExceptionLog> ExceptionLogs { get; set; }

Now we have to create a service that will be called on every exception and save the exception logs into the database.

Create an interface.

public interface IExceptionServices
    {
        public Task<ResponseViewModel<object>> CreateLog(Exception ex, object requestBody);
    }

In this interface, we have a signature of the method that is taking two parameters as arguments one is exception and other is object.

Let’s implement this method.

public class ExceptionServices:IExceptionServices
    {
        public IConfiguration _configuration { get; }
        private readonly ApplicationDbContext _context;
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly UserManager<ApplicationUser> userManager;
        public ExceptionServices(ApplicationDbContext context,
            IHttpContextAccessor httpContextAccessor,
            IConfiguration configuration,
            UserManager<ApplicationUser> userManager
            )
        {
            _context = context;
            _httpContextAccessor = httpContextAccessor;
            _configuration = configuration;
            this.userManager = userManager;
        }
        public async Task<ResponseViewModel<object>> CreateLog(Exception ex, object requestBodyJson)
        {
            var exceptionLogObj = new ExceptionLog();
            exceptionLogObj.Data = JsonConvert.SerializeObject(requestBodyJson, new JsonSerializerSettings
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore
            });
            exceptionLogObj.DataTime = DateTime.Now;
            exceptionLogObj.ErrorDescription = ex.InnerException != null ? ex.InnerException.Message : 
            ex.Message;
            exceptionLogObj.IPInfo = 
            _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString();
            exceptionLogObj.StackTrace = ex.StackTrace;
            if (!string.IsNullOrEmpty(_httpContextAccessor.HttpContext.User.Identity.Name))
            {
                var user = await 
                this.userManager.FindByNameAsync(this._httpContextAccessor.HttpContext.User.Identity.Name);
                exceptionLogObj.UserId = user.Id;
            }
            exceptionLogObj.Reference = $"{_httpContextAccessor.HttpContext.Request.Path} , 
            {_httpContextAccessor.HttpContext.Request.Method}";
            // Or you can also instantiate inside using
            //using (ApplicationDbContext context = new ApplicationDbContext(null, optionsBuilder.Options))
            //{
            this._context.Add(exceptionLogObj);
            await this._context.SaveChangesAsync();
            //}
            return new ResponseViewModel<object>
            {
                Status = false,
                Message = ex.Message,
                Data = null,
                StatusCode = System.Net.HttpStatusCode.BadRequest.ToString()
            };
        }
    }

In this service, we are getting the exception and the other data like error description, IP Address, and stack trace and saving all the data into the database.

Now configure this service into the “Startup.cs” class.

services.AddTransient<IExceptionServices, ExceptionServices>();

After configuring this service into the startup class. We will inject this service into our all services or controllers so that we can save the exceptions logs.

public class CityServices: ICityServices
    {
        private readonly ApplicationDbContext _context;
        private readonly IExceptionServices _exceptionServices;
        private readonly IConfiguration configuration;
        public CityServices(ApplicationDbContext context,IExceptionServices exceptionServices,IConfiguration config)
        {
            _context = context;
            _exceptionServices = exceptionServices;
            configuration = config;
        }
        public async Task<ResponseViewModel<object>> UploadData(IFormFile file)
        {
            try
            {
                
                var fileextension = Path.GetExtension(file.FileName);
                var filename = Guid.NewGuid().ToString() + fileextension;
                var filepath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot","uscities", filename);
                
                using (FileStream fs = System.IO.File.Create(filepath))
                {
                    file.CopyTo(fs);
                }
                if(fileextension == ".csv")
                {
                    await AddCsv(filepath);
                }
                else
                {
                   await AddExcel(filepath);
                }
                return new ResponseViewModel<object>
                {
                    Status = true,
                    Message = "Cities Updated Successfully",
                    StatusCode = System.Net.HttpStatusCode.OK.ToString()
                };
            }
            catch (Exception e)
            {
                await _exceptionServices.CreateLog(e, null);
                throw e;
            }
        }
}

Now before throwing an exception we will call the method to save exception. Like we have described above.

Logging in ASP.NET Core Web API

Logging is an essential part of any software application, as it allows developers to monitor and analyze the behavior of their code in real-time. ASP.NET Core Web API provides several built-in logging mechanisms that can be used to track application behavior and troubleshoot issues.

There are several types of logging available in ASP.NET Core, including console logging, debug logging, and file logging. Console logging writes log messages to the console window, while debug logging writes log messages to the debug output window. File logging, on the other hand, writes log messages to a file on disk.

Each log message is assigned a severity level, which determines the importance of the message. The most common logging levels are trace, debug, information, warning, error, and critical. Trace messages provide the most detailed information about application behavior, while critical messages indicate a severe error that requires immediate attention.

ASP.NET Core also supports several popular logging frameworks, including Serilog, NLog, and Log4Net. These frameworks provide additional features and customization options that can help developers better understand their application’s behavior.

When selecting a logging framework, it’s important to consider factors such as ease of use, performance, and the ability to integrate with other tools and services. Each logging framework has its own strengths and weaknesses, so it’s important to evaluate them carefully before making a decision.

Understanding Exceptions

Exceptions are a common occurrence in software development and can be defined as unexpected or abnormal conditions that occur during the execution of code. When an exception occurs, it disrupts the normal flow of the application and can cause errors, crashes, or unexpected behavior.

There are several reasons why exceptions occur. These include invalid user input, programming errors, system faults, network failures, and many more. It’s important to understand why exceptions occur in order to effectively handle and troubleshoot them.

Logging exceptions is crucial to identify and troubleshoot issues that arise during the execution of code. Exceptions can be logged to a file or a database, allowing developers to quickly identify the root cause of the issue and take necessary actions to resolve it.

When logging exceptions, it’s important to include as much information as possible, such as the type of exception, the method or line of code where it occurred, and any relevant stack traces or error messages. This information can be invaluable in troubleshooting the issue and fixing the problem.

In addition to logging exceptions, it’s important to handle them effectively in code. This can be done by using try-catch blocks to catch and handle exceptions as they occur. By handling exceptions in this way, developers can prevent the application from crashing and provide a more user-friendly experience.

Logging Exceptions in ASP.NET Core Web API

Logging exceptions is a crucial aspect of any ASP.NET Core Web API application. It allows developers to identify and troubleshoot issues that arise during the execution of code, leading to more stable and reliable software.

To enable exception logging in ASP.NET Core Web API, developers can use the built-in logging mechanisms or a logging framework such as Serilog, NLog, or Log4Net. These frameworks provide additional features and customization options that can help developers better understand their application’s behavior.

In ASP.NET Core, exception logging can be enabled by adding middleware to the application pipeline. The middleware can be configured to log exceptions to a file, a database, or any other destination of the developer’s choice. By logging exceptions to a file or database, developers can quickly identify the root cause of the issue and take necessary actions to resolve it.

Best practices for logging exceptions include logging as much information as possible, including the type of exception, the method or line of code where it occurred, and any relevant stack traces or error messages. It’s also important to log exceptions at the appropriate severity level, depending on the impact of the exception on the application’s behavior.

In addition to logging exceptions, it’s important to handle them effectively in code. This can be done by using try-catch blocks to catch and handle exceptions as they occur. By handling exceptions in this way, developers can prevent the application from crashing and provide a more user-friendly experience.

Finally, it’s important to regularly review and analyze logged exceptions to identify patterns or trends that may indicate underlying issues in the application. By analyzing logged exceptions, developers can proactively identify and resolve issues before they impact the user experience.

Analyzing Logged Exceptions

Analyzing logged exceptions is an important step in troubleshooting issues in ASP.NET Core Web API applications. By reviewing logged exceptions, developers can gain valuable insights into the behavior of their code and identify patterns or trends that may indicate underlying issues.

When analyzing logged exceptions, it’s important to review the information that has been logged, such as the type of exception, the method or line of code where it occurred, and any relevant stack traces or error messages. This information can help developers identify the root cause of the issue and take necessary actions to resolve it.

In addition to reviewing the information that has been logged, it’s important to analyze the frequency and severity of the exceptions. For example, if a particular exception occurs frequently or at a high severity level, it may indicate an underlying issue that needs to be addressed.

Analyzing logged exceptions can also help developers identify potential areas for improvement in their code. For example, if a particular exception is occurring frequently in a specific method or section of code, it may indicate that the code needs to be refactored or optimized.

In order to effectively analyze logged exceptions, it’s important to have a good understanding of the application’s behavior and the context in which the exceptions are occurring. This may require working closely with other members of the development team, as well as utilizing tools such as profiling and debugging tools.

Finally, it’s important to continually monitor and analyze logged exceptions in order to proactively identify and address issues before they impact the user experience. This can be done by setting up alerts or notifications for specific types of exceptions, or by regularly reviewing logs and analyzing trends.

Conclusion:

There are many approaches to do this save exception logs. But this is the most optimized and professional approach to do this task. Try this tutorial and if you do not understand anything or face any issue while applying this method. Do not hesitate to comment below. MYCODEBIT team will try to respond ASAP.

Leave a Reply