What's logging and tracing?
Logging (also called tracing) is used to record information about a program's execution for debugging and testing purposes. Developers, testers, and support engineers often use logging and tracing techniques to identify software problems, for post-deployment debugging, monitoring live systems, and auditing purposes.
Logging usually involves writing text messages to log files or sending data to monitoring applications. Advanced and modern logging tools also support logging of complex data structures, call stacks, threading behavior and also support real-time monitoring of applications over a network or on a local machine.
For the above logging and tracing purpose, the below mentioned third party logging framework or library is mainly used which still can be applicable within ASP.NET Core application.
- Log4Net
- NLog
- SeriLog
Built-in ASP.NET Core Logging
ASP.NET Core now has a built-in logging framework which we can use. It is designed as a logging API that developers can use to capture built-in ASP.NET logging as well as for their own custom logging. The logging API supports multiple output providers and is extensible to potentially be able to send your application logging anywhere.
Other logging frameworks like NLog and Serilog have even written providers for it. So, you can use the ILoggerFactory and it ends up working sort of the same. Logging acts as a facade above an actual logging library. By using it in this way, it also allows you to leverage all the power of a library, like NLog, to overcome any limitations the built-in Microsoft.Extensions.Logging API may have. The biggest of those is being able to actually write your logs to a file on disk!
How to add Logging Provider
Actually, logging provider is always required to fire some action to log data which can be displayed in the console or stored within a physical file located in the physical machine or cloud environment. To use a logging provider in ASP.NET Core, we need to install Microsoft.Extensions.Logging.Abstractions package from NuGet Manager. Basically, this package contains two interfaces – ILogger and ILoggerFactory.
ASP.NET Core dependency injection (DI) provides the ILoggerFactory instance. The AddConsole and AddDebug extension methods are defined in the Microsoft.Extensions.Logging.Console and Microsoft.Extensions.Logging.Debug packages. Each extension method calls the ILoggerFactory.AddProvider method, passing in an instance of the provider.
How to create Logs Data
To create logs in the application, we need to get an instance of ILogger object using Dependency Injection and store that data within a field. After this, we need to call the logging methods on those logger objects.
- public class TodoController : Controller
- {
- private readonly ITodoRepository _todoRepository;
- private readonly ILogger _logger;
- public TodoController(ITodoRepository todoRepository,
- ILogger<TodoController> logger)
- {
- _todoRepository = todoRepository;
- _logger = logger;
- }
- …………….
- }
- public IActionResult GetById(string id)
- {
- _logger.LogInformation(LoggingEvents.GET_ITEM, "Getting item {ID}", id);
- var item = _todoRepository.Find(id);
- if (item == null)
- {
- _logger.LogWarning(LoggingEvents.GET_ITEM_NOTFOUND, "GetById({ID}) NOT FOUND", id);
- return NotFound();
- }
- return new ObjectResult(item);
- }
What is Log Category?
A category is specified with each log that we create in our application. The category may be any string, but a best convention is to use the fully qualified name of the class from which the logs are written. For example: "EmployeeApi.Controllers.SaveController".
We specify the category when we create a logger object or request one from DI, and the category is automatically included with every log written by that logger. We can specify the category explicitly or we can use an extension method that derives the category from the type.
To specify the category explicitly, call CreateLogger on an ILoggerFactory instance, as shown below.
- public class TodoController : Controller
- {
- private readonly ITodoRepository _todoRepository;
- private readonly ILogger _logger;
- public TodoController(ITodoRepository todoRepository,
- ILoggerFactory logger)
- {
- _todoRepository = todoRepository;
- _logger = logger.CreateLogger("TodoApi.Controllers.TodoController");
- }
- ………………..
- }
About Log Level
Each time we write a log, we specify its LogLevel as per its importance. The log level indicates the degree of severity or importance. For example, we might write an Information log when a method ends normally; a Warning log when a method returns a 404 return code; and an Error log when you catch an unexpected exception.
- public IActionResult GetById(string id)
- {
- _logger.LogInformation(LoggingEvents.GET_ITEM, "Getting item {ID}", id);
- var item = _todoRepository.Find(id);
- if (item == null)
- {
- _logger.LogWarning(LoggingEvents.GET_ITEM_NOTFOUND, "GetById({ID}) NOT FOUND", id);
- return NotFound();
- }
- return new ObjectResult(item);
- }
The below table defines the different log levels mentioned within ASP.NET Core.
Log Level | Level value | Description |
Trace | 0 | For information that is valuable only to a developer debugging an issue. These messages may contain sensitive application data and so should not be enabled in a production environment. Disabled by default. |
Debug | 1 | For information that has short-term usefulness during development and debugging |
Information | 2 | For tracking the general flow of the application |
Warning | 3 | For abnormal or unexpected events in the application flow. These may include errors or other conditions that do not cause the application to stop |
Error | 4 | For errors and exceptions that cannot be handled. These messages indicate a failure in the current activity or operation (such as the current HTTP request), |
Critical | 5 | For failures that require immediate attention. Examples: data loss scenarios, out of disk space |
Given below is the built-in Logging Provider in ASP.NET Core.
- Console
- Debug
- EventSource
- EventLog
- TraceSource
- Azure App Service
TodoController.cs