Write logs with TraceSource

Source: Internet
Author: User

Write logs with TraceSource

When Microsoft introduced the first version of the. NET framework, Debug and trace two classes were available in the "System.Diagnostics" namespace to help us complete logging for debug and trace information. In the. NET Framework 2.0, Microsoft introduced TraceSource and optimized the tracking log system, and the optimized tracking log system was streamlined in. NET core.. net Core's log model to integrate TraceSource with Tracesourceloggerprovider, before formally introducing this logger, let's start by understanding the three core objects in the TraceSource tracking log system. [This article has been synced to the "ASP. NET Core Framework"]

Directory
One, TraceSource-based tracking log system
Second, Tracesourcelogger
Third, Tracesourceloggerprovider

One, TraceSource-based tracking log system

For this tracesource-based tracking log system, in addition to TraceSource, it also has an additional core object, which is TraceListener and Sourceswitch, respectively, as shown in the relationship between the three. Write implementation of log messages on TraceListener, we can register a set of TraceListener on a tracesource. When we use TraceSource to record a trace log, the log messages are distributed to every TraceListener registered and they write the log messages to the corresponding destination. Each tracesource has a sourceswitch, which plays the role of log filtering. Specifically, Sourceswitch defines the appropriate filtering conditions to help TraceSource decide whether the trace log should be distributed to TraceListener if the specified log message does not meet the filter criteria. TraceSource will not perform any substantive logging work.

As shown below is the definition of TraceSource. Each tracesource has a name that typically represents the name of the application, service, or component to which the trace log is written. We can call its three set of trace methods (TraceData, TraceEvent, and TraceInformation) to record the trace log. Because these methods all label a Conditionaleattribute attribute and conditionally compile the "TRACE", calls to these methods are only valid in applications that are compiled for TRACE mode.

   1:public class TraceSource
   2: {
   3: Public     tracelistenercollection Listeners {get;}
   4: Public     string             Name {get;}
   5: Public     sourceswitch         Switch {get; set;}
   
   7: Public     TraceSource (string name);
   8: Public     TraceSource (string name, Sourcelevels defaultlevel);
   9:    
  Ten:     [Conditional ("TRACE")]
  One: public     void TraceData (TraceEventType eventtype, int ID, object data);
  :     [Conditional ("TRACE")]
  : Public     void TraceData (TraceEventType eventtype, int id, params object[] data);
  
  :     [Conditional ("TRACE")]
  : Public     void TraceEvent (TraceEventType eventtype, int id);
  :     [Conditional ("TRACE")]
  : Public     void TraceEvent (TraceEventType eventtype, int ID, string message);
  :     [Conditional ("TRACE")]
  : Public      void TraceEvent (TraceEventType eventtype, int ID, string format, params object[] args);
  
  :     [Conditional ("TRACE")]
  : Public     void TraceInformation (String message);
  :     [Conditional ("TRACE")]
  : Public     void TraceInformation (string format, params object[] args);  
  26:}

Trace logs recorded through the three methods of TraceData, TraceEvent, and TraceInformation have an event type represented by the enumeration type TraceEventType, which is equivalent to the log level mentioned earlier. The smaller the value of these enumerated entries of TraceEventType means that the higher the rank, the loglevel that defines the log level is reversed. When calling the TraceData and TraceEvent methods, we need to explicitly specify the event type for the trace log being written, while the TraceInformation method uses the information type by default.

   1:public enum TraceEventType
   2: {
   3:     Critical         = 1,
   4:     Error            = 2,
   5:     Warning          = 4,
   6:     Information      = 8,
   7:     Verbose          = 16,
   8:}

The TraceEventType enumeration also has another enumeration named Sourcelevels, which, in addition to the five specific event types, has an additional two options all and off, which are sourceswitch used to filter the log. When calling the constructor to create the TraceSource, we can specify a Sourcelevels enumeration value as the default level. If this level is not explicitly set, the TraceSource is created with a class of off, which means that the record for the tracking log is forbidden by default.

   1: [Flags]
   2:public enum Sourcelevels
   3: {
   4:     All             =-1,
   5:     Off             = 0,
   6:     Critical        = 1,
   7:     Error           = 3,
   8:     Warning         = 7
   9:     Information     = 15,
  Ten:     Verbose         = 31
  11:}

The TraceSource that we create is the Sourcelevels enumeration that specifies (or defaults) the log level to create a Sourceswitch object with the following definition, and the TraceSource switch property returns an object. As the name implies, Sourceswitch is a switch that uses the Shouldtrace method to determine whether a write operation for a type of trace log should be on or off. As shown in the following code fragment, the results returned by the Shouldtrace method are computed based on the trace log level returned by the Level property, and the Sourcelevels enumeration that represents the trace log rank was originally provided by tracesource at initialization time.

   1:public class Sourceswitch:switch
   2: {
   3: Public     sourcelevels level {get;set;}
   
   5: Public     sourceswitch (string name);
   6: Public     sourceswitch (string displayName, string defaultswitchvalue);
   
   8: Public     bool Shouldtrace (TraceEventType EventType)
   9:     {
  Ten:         return (base. Switchsetting & EventType) > 0);
  One:     }    
  12:}

The TraceSource object itself is not responsible for writing to the trace log, it simply distributes the log write requests to the registered TraceListener and delegates them to the function of writing the log. These tracelistenter that are registered on TraceSource are saved to the collection object returned by its listeners property. All TraceListener are born as follows in this abstract TraceListener type, which defines the following two groups of TraceData and TraceEvent methods. When we call TraceSource's TraceData, TraceEvent, and TraceInformation methods, if we decide by sourceswitch that the write function for the current trace log should be turned on, Then the registered TraceListener TraceData or TraceEvent method will be called.

   1:public Abstract class Tracelistener:idisposable
   2: {
   3: ...     
   4: Public     virtual void TraceData (TraceEventCache eventcache, string source, TraceEventType eventtype, int id, object D ATA);
   5: Public     virtual void TraceData (TraceEventCache eventcache, string source, TraceEventType eventtype, int id, params object[] data);
   
   7: Public     virtual void traceevent (TraceEventCache eventcache, string source, TraceEventType eventtype, int id);
   8: Public     virtual void traceevent (TraceEventCache eventcache, string source, TraceEventType eventtype, int ID, string message);
   9: Public     virtual void traceevent (TraceEventCache eventcache, string source, TraceEventType eventtype, int id, Strin g format, params object[] args);
  10:}

Next we demonstrate how to create a tracesource and use it to record the trace log through a simple console application. Since TraceSource is defined in the NuGet package "System.Diagnostics.TraceSource", we need to add a dependency on this NuGet package in the Project.json file as follows. As with the example shown earlier, in order to provide support for Chinese encoding, we had to add a dependency on the NuGet package "System.Text.Encoding.CodePages".

   1: {
   2: ...   
   3:   "dependencies": {
   4: "     System.Diagnostics.TraceSource": "4.0.0",    
   5: "     System.Text.Encoding.CodePages": "4.0.1"
   6:   }
   7:}

Since TraceSource always uses the TraceListener that is registered on it to complete the log-writing process, we have customized the Consoletracelistener in the following way. As the name implies, Consoletracelistener is designed to output the trace logs distributed to it to the console. As shown in the following code snippet, this consoletracelistener simply overrides the Write and WriteLine methods, which invoke the same name method defined on the console type to output the formatted log message to the console.

   1:public class Consoletracelistener:tracelistener
   2: {
   3: Public     override void Write (String message) = Console.Write (message);
   4: Public     override void WriteLine (String message) = Console.WriteLine (message);
   5:}

We have created a TraceSource object in the main method as the entrance to the program. In addition to specifying the name of the TraceSource ("program") when calling the constructor, we also set a default tracking log level (Warning). Next we create a Consoletracelistener object and register it on the TraceSource object. After this, we call TraceSource's TraceEvent method to record three trace logs, which are followed by information, warining, and error, respectively.

   1:public class Program
   2: {
   3: Public     static void Main (string[] args)
   4:     {
   5:         //Register Encodingprovider support for Chinese encoding
   6:         Encoding.registerprovider (codepagesencodingprovider.instance);
   
   8:         TraceSource tracesource = new TraceSource (nameof (program), sourcelevels.warning);
   9:         traceSource.Listeners.Add (New Consoletracelistener ());
  
  One:         int eventId = 3721;
  :         tracesource.traceevent (traceeventtype.information, EventId, "upgrade to the latest. NET Core version ({0})", "1.0.0");
  Max:         tracesource.traceevent (traceeventtype.warning, eventId, "Concurrency is approaching upper limit ({0})", 200);
  :         tracesource.traceevent (Traceeventtype.error, eventId, "Database connection failed (database: {0}, user name: {1})", "TestDb", "sa");
  :     }
  16:}

After the program is run, we use the TraceSource recorded tracking log to output the registered Consoletracelistener as shown in the console. Since we have specified a default tracking log level warning when creating TraceSource, only two logs not below this level will be displayed on the console.

Second, Tracesourcelogger

The. NET core log model leverages a definition in the NuGet package "Microsoft.Extensions.Logging.TraceSource" The Tracesourcelogger type in the implementation is integrated with the TraceSource tracking log system. From the code snippet below, it is not difficult to see that a Tracesourcelogger object is actually an encapsulation of a TraceSource object, in the Log<state> method of implementation, It calls TraceSource's TraceEvent method to complete the write work for the log message.

   1:public class Tracesourcelogger:ilogger
   2: {
   3: Public     Tracesourcelogger (TraceSource tracesource);
   4: Public     IDisposable beginscope<tstate> (tstate state);
   5: Public     bool IsEnabled (LogLevel LogLevel);
   6: Public     void Log<tstate> (LogLevel LogLevel, EventId EventId, tstate State, Exception Exception, func< Tstate, Exception, string> formatter);
   7:}

When we call TraceSource's TraceEvent method to write the trace log, we need to specify the event type of the trace log, which is determined by the log level provided, and the following table shows the simple mapping between the log level and the trace event type. Since TraceSource calls its Sourceswitch Shouldtrace method to determine if it really needs to write a trace log message for the current distribution, when the IsEnabled method of Tracesourcelogger is called, It also converts the specified log level to the trace event type in such a mapping relationship, and calls the Shouldtrace method as a parameter, and the return value of the method is the return value of the IsEnabled method.

Log level

Trace Event Type

Trace

Verbose

Debug

Verbose

Information

Information

Warning

Warning

Error

Error

Critical

Critical

The Beginscope<tstate> method of Tracesourcelogger Returns a Tracesourcescope object, although this is a common type, but this object does not have any scope control. It does not itself carry any information about the current log context, so tracesourcelogger, like the Debuglogger and Eventloglogger described earlier, does not actually provide support for the log context.

Third, Tracesourceloggerprovider

The tracesourcelogger corresponds to a loggerprovider type of tracesourceloggerprovider. As shown in the following code snippet, when we create a Tracesourceloggerprovider object, we need to provide a sourceswitch and TraceListener object (optional). In the Createlogger method that is implemented, Tracesourceloggerprovider creates a TraceSource object based on the specified name, which takes the sourceswitch specified at initialization, The pre-specified TraceListener is also registered with the TraceSource object, and the Createlogger method will eventually return the Tracesourcelogger created from this tracesource.

   1:public class Tracesourceloggerprovider:iloggerprovider
   2: {   
   3: Public     Tracesourceloggerprovider (Sourceswitch rootsourceswitch);
   4: Public     tracesourceloggerprovider (Sourceswitch rootsourceswitch, TraceListener roottracelistener);
   
   6: Public     ILogger Createlogger (string name);
   7: Public     void Dispose ();   
   8:}

It is worth mentioning that Tracesourceloggerprovider does not create TraceSource objects frequently in the Createlogger method, but rather chooses the tracesource that will be created to be cached according to the specified name. So when the Createlogger method is called, Tracesourceloggerprovider will see if there is a ready-made tracesource in the cache based on the specified name. If present, the returned Tracesourcelogger is created directly from it. The new TraceSource is created only if it is determined that a tracesource with the same name was never created. We can call the following two extension methods Addtracesource to create tracesourceloggerprovider and register them on the specified loggerfactory based on the specified Sourceswitch (or its name) and TraceListener 。

   1:public Static Class Tracesourcefactoryextensions
   2: {
   3: Public     static Iloggerfactory Addtracesource (this iloggerfactory factory, Sourceswitch Sourceswitch, TraceListener listener);
   4: Public     static Iloggerfactory Addtracesource (this iloggerfactory factory, string switchname, TraceListener Listener);
   5:}

Next we demonstrate the logging for Debuglogger with a simple example. We created an empty console application, and after adding the necessary dependencies, we wrote the following procedure in the main method. As shown in the following code snippet, we created a loggerfactory with dependency injection and called the extension method Addtracesource method to create and register a Tracesourceloggerprovider object. After using Loggerfactory to create the Logger object, we used the latter to record three log messages.

   1:public class Program
   2: {
   3: Public     static void Main (string[] args)
   4:     {
   5:         //Register Encodingprovider support for Chinese encoding
   6:         Encoding.registerprovider (codepagesencodingprovider.instance);
   
   8:         ILogger logger = new Servicecollection ()
   9:                 . Addlogging ()
  Ten:                 . Buildserviceprovider ()
  One:                 . Getservice<iloggerfactory> ()
  A:                 . Addtracesource (New Sourceswitch (nameof (program), "Warning"), New Consoletracelistener ())
  :                 . Createlogger<program> ();
  
  
  :         int eventId = 3721;
  
  :         logger. Loginformation (EventId, "upgrade to the latest. NET Core version ({version})", "1.0.0");
  :         logger. Logwarning (eventId, "concurrency close to upper limit ({maximum})", 200);
  :         logger. LogError (eventId, "Database connection failed (database: {db}, user name: {user})", "TestDb", "sa");
  :     }
  22:}

We create and register Tracesourceloggerprovider with the call extension method Addtracesource, which specifies a sourceswitch for warning levels, The specified TraceListener is a custom consoletracelistener, so only two log messages with a level of no less than warning will be output to the console as shown in this consoletracelistener.

. NET core Log [1]: Logging with a unified pattern
. NET core Log [2]: Write log to console
. NET core Log [3]: Write Log to debug window
. NET core logs [4]: Write logs with EventLog
. NET core logs [5]: Write logs with TraceSource

Write logs with TraceSource

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: info-contact@alibabacloud.com 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.