ASP. NET Core Source Learning Logging

Source: Internet
Author: User
Tags hosting webhost

in ASP. NET 4.X, we typically use log4net, NLog, and so on to log logs, but when we reference some third-party class libraries that use different log frameworks, it's a bit confusing. The log system is built into ASP. NET core, and provides a unified log interface, and the ASP. The log interface is used to record logs, regardless of the specific implementation of the log, so that it can be configured in our application in a uniform way. And can be well integrated with the third-party log framework.

Register Log Service

ASP. NET Core uses dependency injection to better standardize our code. To use the log system, you first need to register and configure:

public void ConfigureServices(IServiceCollection services) { services.AddLogging(builder => { builder .AddConfiguration(loggingConfiguration.GetSection("Logging")) .AddFilter("Microsoft", LogLevel.Warning) .AddConsole(); });}

As above, through AddLogging , the log system is registered to the DI system, but the AddConfiguration global configuration of the log system, AddFilter is a few configuration of the log filter, and finally AddConsole added a Console log provider (log Output to a console).

Record log

When we need to log, we just need to inject through the constructor function ILogger<T> :

PublicClassTodocontroller:controller{PrivateReadOnly Itodorepository _todorepository;PrivateReadOnly ILogger _logger;Publictodocontroller (itodorepository todorepository, ILogger< todocontroller> logger) {_todorepository = todorepository; _logger = logger;} [HttpGet] public iactionresult GetById ( Span class= "Hljs-params" >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);}}     

ILogger<T>The T categories that represent journaling are very useful when we look at the logs, which are described later in this article.

Sample log Output

Using the example code above, when we run through the console, the access http://localhost:5000/api/todo/0 will see the following log output:[1] Request starting HTTP/1.1 GET http://localhost:5000/api/todo/invalididinfo:microsoft.aspnetcore.mvc.internal.controlleractioninvoker[1] Executing action method TodoApi.Controllers.TodoController.GetById (TODOAPI) with arguments (invalidid)-Modelstate I S Validinfo:todoapi.controllers.todocontroller[1002] Getting item Invalididwarn: Todoapi.controllers.todocontroller[4000] GetById (invalidid) not FOUND info:microsoft.aspnetcore.mvc.statuscoderesult[1] Executing Httpstatuscoderesult, setting HTTP status code 404info: Microsoft.aspnetcore.mvc.internal.controlleractioninvoker[2] Executed action TodoApi.Controllers.TodoController.GetById (TODOAPI) in[ 2] Request finished in 628.9188ms Span class= "Hljs-number" >404            

If we visit http://localhost:55070/api/todo/0 , we will see:

Microsoft.AspNetCore.Hosting.Internal.Webhost:Information:request starting HTTP/1.1 GET http://localhost:55070/api/todo/invalididmicrosoft.aspnetcore.mvc.internal.Controlleractioninvoker:Information:executing action Method TodoApi.Controllers.TodoController.GetById (TODOAPI) with arguments (Invalidid)- Modelstate is validtodoapi.controllers.Todocontroller:information:getting item invalididtodoapi.controllers. todocontroller:warning:getbyid (Invalidid) not FOUNDMICROSOFT.ASPNETCORE.MVC. statuscoderesult:information:executing HttpStatusCodeResult , setting HTTP status code 404microsoft.aspnetcore.mvc.internal. Controlleractioninvoker:information:executed action TodoApi.Controllers.TodoController.GetById (TODOAPI) in webhost:information:request finished in 19.0913ms 404   

In this example, we can see that we have logged the log of the ASP. NET Core framework itself, which is a feature that can be implemented by a unified logging framework.

Log category

Each logger that we create specifies a category. It can be any string, but the contract uses the fully qualified name of the Write class, such as "TodoApi.Controllers.TodoController". If you want to explicitly specify the kind of log, you can use ILoggerFactory the CreateLogger method in:

public class TodoController : Controller{    private readonly ILogger _logger; public TodoController(ILoggerFactory logger) { _logger = logger.CreateLogger("TodoApi.Controllers.TodoController"); }}

However, most of the time, we still use it ILogger<T> more conveniently:

public class TodoController : Controller{    private readonly ILogger _logger; public TodoController(ILogger<TodoController> logger) { _logger = logger; }}

This is equivalent to T invoking the method with the full qualified name of the type CreateLogger .

Log level

When we log, we need to specify the level of the log, which is very useful for our filtering logs, such as in a test environment where we want to provide very detailed log information, including some sensitive information, but in a production environment, we want to log only serious errors, simply by AddFilter Configure the filter level for the log.

The ASP. NET Core Logging system provides six log levels by increasing the importance or severity of the order as follows:

    • Trace is used to record the most verbose log messages and is typically used only for development phase debugging issues. These messages may contain sensitive application data and therefore should not be used in production environments. The default should be disabled.

    • Debug This message is useful in the short term during the development phase. They contain information that may be useful for debugging, but have no long-term value. This is the most verbose log by default.

    • Information This message is used to track the general flow of the application. In contrast to Verbose level messages, these logs should have some long-term value.

    • Warning Use the warning level when an application has an error or other process exception or unexpected event that does not cause the program to stop for future investigation. Handle warning level exceptions in a common place.

    • Error logging is required when the application stops working due to certain failures. These messages should indicate the current activity or operation (such as the current HTTP request), rather than the application-wide failure.

    • Critical log at the critical level should be logged when an application or system crashes, encounters a catastrophic failure, and needs immediate attention. such as data loss, insufficient disk space, and so on.

Log Event ID

Each time we write a log, we can specify an event ID:

PublicClassloggingevents{PublicConstint get_item =1002; public const int GET_ITEM_ NOTFOUND = 4000;} public iactionresult GetById ( Span class= "Hljs-params" >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);}     

Event ID   is an integer that can associate a set of log events together. Similar to the log category, but more granular. And its output depends on the log provider, Console   provider output format, followed by the log category and wrapped in a pair of brackets:

info: TodoApi.Controllers.TodoController[1002] Getting item invalididwarn: TodoApi.Controllers.TodoController[4000] GetById(invalidid) NOT FOUND
Log formatted string

Each time a log is logged, a text message is provided, and in this message string we can use the named placeholder:

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);}

But the order of the placeholders determines which parameter to use, not its name, as in the following example:

string p1 = "parm1";string p2 = "parm2";_logger.LogInformation("Parameter values: {p2}, {p1}", p1, p2);

The output is:

Parameter values: parm1, parm2

What's the point of doing that?

The log framework uses this message format to enable the log provider to implement a semantic log, also known as a structured log. Because the parameter itself is passed to the log system, not just the formatted string, the log provider can store the value of the parameter as a field in a separate store. For example, if you use Azure Table Storage, we can use the following methods to log logs:

_logger.LogInformation("Getting item {ID} at {RequestTime}", id, DateTime.Now);

Each Azure Table can have ID and RequestTime attributes, which simplifies querying the log data, and you can find RequestTime all the logs in a specified range without having to spend the cost of parsing text messages.

Filter filters

Filters allow you to choose whether to output or ignore depending on the level and category of the log. We can specify different filters for different log providers, as shown in the following code, which allows the Console provider to ignore warning logs below the level, while the Debug provider ignores TodoApi the category's logs.

public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory){ loggerFactory .AddConsole(LogLevel.Warning) .AddDebug((category, logLevel) => (category.Contains("TodoApi") && logLevel >= LogLevel.Trace));}

We can also specify a global filter for all log providers, as in the following example, we ignore lower-level logs for log categories that start with "Microsoft" and "System" Warning :

public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory){ loggerFactory .AddFilter("Microsoft", LogLevel.Warning) .AddFilter("System", LogLevel.Warning) .AddFilter("SampleApp.Program", LogLevel.Debug) .AddDebug();}

We can put a set of logical operations in an ordered scope and append the scope 's identity to all the logs in the range. For example, we can handle transactions so that each operation log within a transaction contains the ID of the transaction.

Use Ilgger.beginscope<tstate>   method to create a   Scope and return a   IDisposable   Type, when we   Dispose , this   Scope   is finished, ideal for use with   using How to  :

public IActionResult GetById(string id){ TodoItem item; using (_logger.BeginScope("Message attached to logs created in the using block")) { _logger.LogInformation(LoggingEvents.GET_ITEM, "Getting item {ID}", id); item = _todoRepository.Find(id); if (item == null) { _logger.LogWarning(LoggingEvents.GET_ITEM_NOTFOUND, "GetById({ID}) NOT FOUND", id); return NotFound(); } } return new ObjectResult(item);}

Each log will include the Scope information:

info: TodoApi.Controllers.TodoController[1002]      => RequestId:0HKV9C49II9CK RequestPath:/api/todo/0 => TodoApi.Controllers.TodoController.GetById (TodoApi) => Message attached to logs created in the using block      Getting item 0warn: TodoApi.Controllers.TodoController[4000]      => RequestId:0HKV9C49II9CK RequestPath:/api/todo/0 => TodoApi.Controllers.TodoController.GetById (TodoApi) => Message attached to logs created in the using block      GetById(0) NOT FOUND

ASP. NET Core provides a unified logging framework that can be easily Startup configured through classes, flexibly integrates with third-party log frameworks, and is used in applications using dependency injection. This article summarizes the overall Logging system, in the next chapter, will analyze the Logging in the configuration of the source code.

Refer to Microsoft Official documentation: Introduction to Logging in ASP.

Rainy Night Dim original Link:

ASP. NET Core Source Learning Logging

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.