qing2005 original Address C # automate log log
In the development of the project, we can not help but use log logging, the most used is log4net and EntLib log, in the need to log the code to add log. Write (log information), suppose I need to track business methods, record methods of passing parameters, execution time, return data, and so on, or I need to see the method of the call relationship, I want to enter the method when the parameter information is automatically recorded, the method to record the results and execution time information. This is a typical AOP application, and Java is easy to implement in terms of AOP because Java has a classloader. But. NET is not very easy in terms of AOP, in strict sense. NET does not have real AOP. That doesn't mean. NET cannot implement AOP, for example: Postsharp and Enterprise Library can be realized.
To introduce Postsharp, we know that. NET code will be compiled into MSIL (Microsoft intermediate Language), and then the CPU will generate the MSIL EXE file in the local CPU binary file format, Postsharp is to add IL code during the compilation process, thus completing the AOP function.
Disadvantage: The compiler needs to postsharp components, maintenance code difficult, because the IL code is not recognized;
Advantages: Easy to use (PostSharp2 is the charge version, crack is also more convenient, this does not introduce crack)
Here I focus on how to use Enterprise Library to automate log.
1. First we need to download the Enterprise Library, the latest version 5.0;
2. Create a new console project and add the following assemblies
Microsoft.Practices.EnterpriseLibrary.Common
Microsoft.Practices.EnterpriseLibrary.Logging
Microsoft.Practices.EnterpriseLibrary.PolicyInjection
Microsoft.Practices.ServiceLocation
Microsoft.Practices.Unity
Microsoft.Practices.Unity.Interception
3. Add Autologcallhandler class to implement Icallhandler interface
This class is to execute the call target method, obtain the parameter information of the method before calling the target method, and log the logs with EntLib log;
Log is logged again after the method finishes, and the execution time and exception handling are counted
Using System; Using System.Collections.Generic; Using System.Linq; Using System.Text; Using Microsoft.Practices.Unity.InterceptionExtension; Using Microsoft.Practices.EnterpriseLibrary.Logging; Using Microsoft.Practices.EnterpriseLibrary.Common.Configuration; Using System.Diagnostics; Using System.Reflection; Namespace AutoLog {public class Autologcallhandler:icallhandler {private LogWriter LogWriter = Enterpriselibrarycontainer.current.getinstance<logwriter> (); Public Autologcallhandler () {} public Imethodreturn Invoke (imethodinvocation input, Getnexthandlerdele Gate GetNext) {StringBuilder SB = null; ParameterInfo pi = null; String methodName = input. Methodbase.name; Logwriter.write (String. Format ("Enter method" + methodName)); if (input. Arguments! = NULL && input. Arguments.count > 0) {sb = new StringBuilder (); for (int i = 0; i < input. Arguments.count; i++) {pi = input. Arguments.getparameterinfo (i); Sb. Append (pi. Name). Append (":"). Append (input. Arguments[i]). Appendline (); } logwriter.write (sb.) ToString ()); } Stopwatch SW = new Stopwatch (); Sw. Start (); Imethodreturn result = GetNext () (input, getNext); If an exception occurs, result is. Exception! = NULL if (result. Exception! = null) {Logwriter.write ("Exception:" + result. Exception.Message); You must dispose of the exception, or you cannot proceed with result execution. Exception = null; } SW. Stop (); Logwriter.write (String. Format ("Exit method {0}, use {1}". ", MethodName, SW. Elapsed)); return result; } public int Order {get; set;} } }
4. To automate the log, you need to create a tag attribute that specifies how the method can automatically log
The Autologcallhandlerattribute tag attribute is created here
Using System; Using System.Collections.Generic; Using System.Linq; Using System.Text; Using Microsoft.Practices.Unity.InterceptionExtension; Using Microsoft.Practices.EnterpriseLibrary.Logging; Using System.Diagnostics; Using Microsoft.Practices.EnterpriseLibrary.Common.Configuration; namespace AutoLog {public class Autologcallhandlerattribute:handlerattribute {public override Icallhandler Createhandler (Microsoft.Practices.Unity.IUnityContainer container) { return new Autologcallhandler () {Order = This. Order};}} }
5. Create an entity class
Note: I added the Autologcallhandler property above the work and ToString method, which is the shorthand form of autologcallhandlerattribute. Used to indicate that the two methods are handled with the Autologcallhandler invoke.
Using System; Using System.Collections.Generic; Using System.Linq; Using System.Text; Using Microsoft.Practices.Unity; namespace AutoLog {public class Employee:marshalbyrefobject {public Employee () {} public string Name {get; set;} [Autologcallhandler ()] public void work () { Console.WriteLine (' Now ' {0},{1} is working hard! ", DateTime.Now.ToShortTimeString (), Name); C13/>throw new Exception ("Customer Exception"); [Autologcallhandler ()] public override string ToString () { return string. Format ("I ' m {0}.", Name);}}}
6. Test code
Note: You must use Policyinjection.create<employee> () to create the object, otherwise it cannot be implemented.
Using System; Using System.Collections.Generic; Using System.Linq; Using System.Text; Using Microsoft.Practices.EnterpriseLibrary.PolicyInjection; Using Microsoft.Practices.Unity; Using Microsoft.Practices.EnterpriseLibrary.Logging; Using Microsoft.Practices.EnterpriseLibrary.Common.Configuration; Namespace AutoLog { class program { private static logwriter LogWriter = Enterpriselibrarycontainer.current.getinstance<logwriter> (); static void Main (string[] args) { Employee emp = policyinjection.create<employee> (); Emp. Name = "Lele"; Emp. Work (); Console.WriteLine (EMP);}}}
7. You also need to complete the log configuration with the EntLib Configuration tool and write the log information to the Trace.log file
<?xml version= "1.0"?> <configuration> <configSections> <section name= " Loggingconfiguration "Type=" Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, version=5.0.505.0, Culture=neutral, publickeytoken= 31bf3856ad364e35 "requirepermission=" true "/> </configSections> <loggingconfiguration name=" "Tracingenabled=" true "defaultcategory=" General "> <listeners> <add name=" Flat F Ile Trace Listener "Type=" Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, version=5.0.505.0, Culture=neutral, publickeytoken= 31bf3856ad364e35 "Listenerdatatype=" Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FlatF Iletracelistenerdata, Microsoft.Practices.EnterpriseLibrary.Logging, version=5.0.505.0, Culture=neutrAl, publickeytoken=31bf3856ad364e35 "filename=" Trace.log "formatter=" Text formatter "/> </listeners> <formatters> <add type= "Microsoft.Practices.EnterpriseLibrary . Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, version=5.0.505.0, culture= Neutral, publickeytoken=31bf3856ad364e35 "template=" Timestamp: {timestamp}{newline} Message: {Me Ssage}{newline} Category: {category}{newline} priority: {Priority}{newline} EventId: {eventid}{newline} Severity: {severity}{newline} Title:{title}{newline} machine: {localmachine}{newline} App Domain: {Locala Ppdomain}{newline} ProcessId: {localprocessid}{newline} Process Name: {localprocessname}{newline} Thread Na Me: {threadname}{newline} Win32 Threadid:{win32threadid}{newline} Extended Properties: {Dictionary ({key}-{Valu E}{newline})} "nAme= "Text Formatter"/> </formatters> <categorySources> <add Switchvalue= "All" Name= "General" > <listeners> <add name= "Flat Fi Le Trace Listener "/> </listeners> </add> </categorys ources> <specialSources> <allevents switchvalue= "All" name= "all Events"/> <notprocessed switchvalue= "All" name= "unprocessed Category"/> <errors Switchvalu E= "All" Name= "Logging Errors & Warnings" > <listeners> <add N Ame= "Flat File Trace Listener"/> </listeners> </errors> </specialSources> </loggingConfiguration> <startup> <supportedruntime version= "v4.0" sku= ". NEtframework,version=v4.0 "/> </startup> </configuration>
Well, test it, console input:
14:03,lele is working hard!
I ' m Lele.
And look at the contents of the Trace.log file:
----------------------------------------Timestamp: -/3/ + 6:Geneva:xxMessage:enter method Work Category:general:-1EventId:1severity:information Title:Machine:PC4 App Domain:AutoLog.exe ProcessId:4200Process name:d:\codes\enterprise library\enterprise Library Demos\piab\demo\autolog\bin\debug\autolog.exe Thread name:win32 ThreadId:4000Extended Properties:---------------------------------------- ----------------------------------------Timestamp: -/3/ + 6:Geneva:xxMessage:Exception:Customer Exception category:general Priority:-1EventId:1severity:information Title:Machine:PC4 App Domain:AutoLog.exe ProcessId:4200Process name:d:\codes\enterprise library\enterprise Library Demos\piab\demo\autolog\bin\debug\autolog.exe Thread name:win32 ThreadId:4000Extended Properties:---------------------------------------- ----------------------------------------Timestamp: -/3/ + 6:Geneva:xxMessage:exit method Work, usexx:xx:00.0024272. Category:general Priority:-1EventId:1severity:information Title:Machine:PC4 App Domain:AutoLog.exe ProcessId:4200Process name:d:\codes\enterprise library\enterprise Library Demos\piab\demo\autolog\bin\debug\autolog.exe Thread name:win32 ThreadId:4000Extended Properties:---------------------------------------- ----------------------------------------Timestamp: -/3/ + 6:Geneva:xxMessage:enter Method ToString category:general Priority:-1EventId:1severity:information Title:Machine:PC4 App Domain:AutoLog.exe ProcessId:4200Process name:d:\codes\enterprise library\enterprise Library Demos\piab\demo\autolog\bin\debug\autolog.exe Thread name:win32 ThreadId:4000Extended Properties:---------------------------------------- ----------------------------------------Timestamp: -/3/ + 6:Geneva:xxMessage:exit method ToString, usexx:xx:00.0001410. Category:general Priority:-1EventId:1severity:information Title:Machine:PC4 App Domain:AutoLog.exe ProcessId:4200Process name:d:\codes\enterprise library\enterprise Library Demos\piab\demo\autolog\bin\debug\autolog.exe Thread name:win32 ThreadId:4000Extended Properties:----------------------------------------
View Code
After realizing the automation log, looking back to the 5th step, employee inherited the MarshalByRefObject, generally our business class or data access class have a base class, then we need to use the interface
Here I add a iemployee interface, inside the work method (ToString is overriding object).
Using System.Collections.Generic; Using System.Linq; Using System.Text; Using Microsoft.Practices.Unity; namespace AutoLog {Public interface IEmployee { void work (); } public class Employee:iemployee {public Employee () { //this. Name = "Lele"; } public string Name {get; set;} [Autologcallhandler ()] public void work () { Console.WriteLine (' Now ' {0},{1} is working hard! ", DateTime.Now.ToShortTimeString (), Name); C17/>throw new Exception ("Customer Exception"); [Autologcallhandler ()] public override string ToString () { return string. Format ("I ' m {0}.", Name);}}}
And then change it in the test class.
Using System; Using System.Collections.Generic; Using System.Linq; Using System.Text; Using Microsoft.Practices.EnterpriseLibrary.PolicyInjection; Using Microsoft.Practices.Unity; Using Microsoft.Practices.EnterpriseLibrary.Logging; Using Microsoft.Practices.EnterpriseLibrary.Common.Configuration; Namespace AutoLog { class program { private static logwriter LogWriter = Enterpriselibrarycontainer.current.getinstance<logwriter> (); static void Main (string[] args) { iemployee emp = Policyinjection.create<employee, iemployee> (); Emp. Work (); Console.WriteLine (EMP);}}}
[Go] C # implement automated log log