C#实现自动化Log日志
2013-08-29 11:05
369 查看
在开发项目的时候,我们不免要使用Log记录日志,使用最多的是Log4Net和EntLib Log,在需要记录日志的代码处加入log.Write(日志信息),假设我需要跟踪业务方法,记录方法的传递参数,执行时间,返回数据等;或者我需要查看方法的调用关系,希望进入方法的时候自动记录参数信息,出方法时记录结果和执行时间信息。这时就是一个典型的AOP运用,Java在AOP方面是很容易实现的,因为java有类加载器。但是.Net在AOP方面就不怎么容易,严格意义上.Net没有真正的AOP。这话并不代表.Net不能实现AOP,比如:PostSharp和Enterprise
library就能实现。
先介绍一下PostSharp,我们知道.net代码将编译成MSIL(微软中间语言),然后CPU将MSIL的exe文件生成本地CPU的二进制文件格式,PostSharp就是在编译过程中加入IL代码,因而完成AOP功能。
缺点:编译器需要PostSharp组件,维护代码困难,因为IL代码不好识别;
优点:使用方便(PostSharp2是收费版,破解也比较方便,在此不介绍破解)
这里我重点介绍如何使用Enterprise Library实现自动化Log。
1.首先我们需要下载Enterprise Library,最新为5.0版本;
2.新建一个控制台项目,并添加以下程序集
Microsoft.Practices.EnterpriseLibrary.Common
Microsoft.Practices.EnterpriseLibrary.Logging
Microsoft.Practices.EnterpriseLibrary.PolicyInjection
Microsoft.Practices.ServiceLocation
Microsoft.Practices.Unity
Microsoft.Practices.Unity.Interception
3.添加AutoLogCallHandler类,实现ICallHandler接口
这个类是执行调用目标方法,在调用目标方法前获取方法的参数信息,并用EntLib Log记录日志;
方法结束后,再次记录日志,并统计执行时间和异常处理
[csharp]
view plaincopyprint?
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, GetNextHandlerDelegate 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);
//如果发生异常则,result.Exception != null
if (result.Exception !=
null) {
logWriter.Write("Exception:" + result.Exception.Message);
//必须将异常处理掉,否则无法继续执行
result.Exception = null;
}
sw.Stop();
logWriter.Write(string.Format("Exit method {0}, use {1}.",methodName, sw.Elapsed));
return result;
}
public int Order {
get; set; }
}
}
4.要自动化日志就需要创建一个标记属性,指定方法能自动进行日志
这里就创建AutoLogCallHandlerAttribute标记属性
[csharp]
view plaincopyprint?
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.创建实体类
注意:我在Work和ToString方法上方加上了AutoLogCallHandler属性,它是AutoLogCallHandlerAttribute的简写形式。用以指示这两个方法用AutoLogCallHandler的Invoke来处理。
[csharp]
view plaincopyprint?
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 is {0},{1} is working hard!",DateTime.Now.ToShortTimeString(),Name);
throw new Exception("Customer Exception");
}
[AutoLogCallHandler()]
public override
string ToString() {
return string.Format("I'm {0}.",Name);
}
}
}
6.测试代码
注意:必须使用PolicyInjection.Create<Employee>()来创建对象,不然无法实现。
[csharp]
view plaincopyprint?
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.还需要用EntLib的配置工具完成Log配置,将Log信息写入Trace.log文件中
[html]
view plaincopyprint?
<?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 File 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.FlatFileTraceListenerData, 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: {message}{newline}
Category: {category}{newline}
Priority: {priority}{newline}
EventId: {eventid}{newline}
Severity: {severity}{newline}
Title:{title}{newline}
Machine: {localMachine}{newline}
App Domain: {localAppDomain}{newline}
ProcessId: {localProcessId}{newline}
Process Name: {localProcessName}{newline}
Thread Name: {threadName}{newline}
Win32 ThreadId:{win32ThreadId}{newline}
Extended Properties: {dictionary({key} - {value}{newline})}"
name="Text Formatter"
/>
</formatters>
<categorySources>
<add
switchValue="All"
name="General">
<listeners>
<add
name="Flat File Trace Listener"
/>
</listeners>
</add>
</categorySources>
<specialSources>
<allEvents
switchValue="All"
name="All Events"
/>
<notProcessed
switchValue="All"
name="Unprocessed Category"
/>
<errors
switchValue="All"
name="Logging Errors & Warnings">
<listeners>
<add
name="Flat File Trace Listener"
/>
</listeners>
</errors>
</specialSources>
</loggingConfiguration>
<startup>
<supportedRuntime
version="v4.0"
sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
好了,测试一下,控制台输入:
Now is 14:03,Lele is working hard!
I'm Lele.
再看看Trace.log文件内容:
[plain]
view plaincopyprint?
---------------------------------------- Timestamp: 2012/3/19 6:03:00 Message: Enter method Work Category: General Priority: -1 EventId: 1 Severity: Information Title: Machine: PC4 App Domain: AutoLog.exe ProcessId: 4200 Process Name: D:\Codes\Enterprise Library\Enterprise Library Demos\PIAB\Demo\AutoLog\bin\Debug\AutoLog.exe Thread Name: Win32 ThreadId:4000 Extended Properties: ---------------------------------------- ---------------------------------------- Timestamp: 2012/3/19 6:03:00 Message: Exception:Customer Exception Category: General Priority: -1 EventId: 1 Severity: Information Title: Machine: PC4 App Domain: AutoLog.exe ProcessId: 4200 Process Name: D:\Codes\Enterprise Library\Enterprise Library Demos\PIAB\Demo\AutoLog\bin\Debug\AutoLog.exe Thread Name: Win32 ThreadId:4000 Extended Properties: ---------------------------------------- ---------------------------------------- Timestamp: 2012/3/19 6:03:00 Message: Exit method Work, use 00:00:00.0024272. Category: General Priority: -1 EventId: 1 Severity: Information Title: Machine: PC4 App Domain: AutoLog.exe ProcessId: 4200 Process Name: D:\Codes\Enterprise Library\Enterprise Library Demos\PIAB\Demo\AutoLog\bin\Debug\AutoLog.exe Thread Name: Win32 ThreadId:4000 Extended Properties: ---------------------------------------- ---------------------------------------- Timestamp: 2012/3/19 6:03:00 Message: Enter method ToString Category: General Priority: -1 EventId: 1 Severity: Information Title: Machine: PC4 App Domain: AutoLog.exe ProcessId: 4200 Process Name: D:\Codes\Enterprise Library\Enterprise Library Demos\PIAB\Demo\AutoLog\bin\Debug\AutoLog.exe Thread Name: Win32 ThreadId:4000 Extended Properties: ---------------------------------------- ---------------------------------------- Timestamp: 2012/3/19 6:03:00 Message: Exit method ToString, use 00:00:00.0001410. Category: General Priority: -1 EventId: 1 Severity: Information Title: Machine: PC4 App Domain: AutoLog.exe ProcessId: 4200 Process Name: D:\Codes\Enterprise Library\Enterprise Library Demos\PIAB\Demo\AutoLog\bin\Debug\AutoLog.exe Thread Name: Win32 ThreadId:4000 Extended Properties: ----------------------------------------
实现了自动化Log后,回过头来再看第5步,Employee继承了MarshalByRefObject,一般我们的业务类或数据访问类都有基类,那么我们就需要使用接口
这里我添加一个IEmployee接口,里面就Work方法(ToString是重写Object的)。
[csharp]
view plaincopyprint?
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 is {0},{1} is working hard!",DateTime.Now.ToShortTimeString(),Name);
throw new Exception("Customer Exception");
}
[AutoLogCallHandler()]
public override
string ToString() {
return string.Format("I'm {0}.",Name);
}
}
}
然后在测试类改动一下
[csharp]
view plaincopyprint?
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);
}
}
}
此为大牛:http://blog.csdn.net/qing2005/article/details/7368738
library就能实现。
先介绍一下PostSharp,我们知道.net代码将编译成MSIL(微软中间语言),然后CPU将MSIL的exe文件生成本地CPU的二进制文件格式,PostSharp就是在编译过程中加入IL代码,因而完成AOP功能。
缺点:编译器需要PostSharp组件,维护代码困难,因为IL代码不好识别;
优点:使用方便(PostSharp2是收费版,破解也比较方便,在此不介绍破解)
这里我重点介绍如何使用Enterprise Library实现自动化Log。
1.首先我们需要下载Enterprise Library,最新为5.0版本;
2.新建一个控制台项目,并添加以下程序集
Microsoft.Practices.EnterpriseLibrary.Common
Microsoft.Practices.EnterpriseLibrary.Logging
Microsoft.Practices.EnterpriseLibrary.PolicyInjection
Microsoft.Practices.ServiceLocation
Microsoft.Practices.Unity
Microsoft.Practices.Unity.Interception
3.添加AutoLogCallHandler类,实现ICallHandler接口
这个类是执行调用目标方法,在调用目标方法前获取方法的参数信息,并用EntLib Log记录日志;
方法结束后,再次记录日志,并统计执行时间和异常处理
[csharp]
view plaincopyprint?
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, GetNextHandlerDelegate 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);
//如果发生异常则,result.Exception != null
if (result.Exception !=
null) {
logWriter.Write("Exception:" + result.Exception.Message);
//必须将异常处理掉,否则无法继续执行
result.Exception = null;
}
sw.Stop();
logWriter.Write(string.Format("Exit method {0}, use {1}.",methodName, sw.Elapsed));
return result;
}
public int Order {
get; set; }
}
}
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, GetNextHandlerDelegate 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); //如果发生异常则,result.Exception != null if (result.Exception != null) { logWriter.Write("Exception:" + result.Exception.Message); //必须将异常处理掉,否则无法继续执行 result.Exception = null; } sw.Stop(); logWriter.Write(string.Format("Exit method {0}, use {1}.",methodName, sw.Elapsed)); return result; } public int Order { get; set; } } }
4.要自动化日志就需要创建一个标记属性,指定方法能自动进行日志
这里就创建AutoLogCallHandlerAttribute标记属性
[csharp]
view plaincopyprint?
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 };
}
}
}
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.创建实体类
注意:我在Work和ToString方法上方加上了AutoLogCallHandler属性,它是AutoLogCallHandlerAttribute的简写形式。用以指示这两个方法用AutoLogCallHandler的Invoke来处理。
[csharp]
view plaincopyprint?
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 is {0},{1} is working hard!",DateTime.Now.ToShortTimeString(),Name);
throw new Exception("Customer Exception");
}
[AutoLogCallHandler()]
public override
string ToString() {
return string.Format("I'm {0}.",Name);
}
}
}
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 is {0},{1} is working hard!",DateTime.Now.ToShortTimeString(),Name); throw new Exception("Customer Exception"); } [AutoLogCallHandler()] public override string ToString() { return string.Format("I'm {0}.",Name); } } }
6.测试代码
注意:必须使用PolicyInjection.Create<Employee>()来创建对象,不然无法实现。
[csharp]
view plaincopyprint?
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);
}
}
}
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.还需要用EntLib的配置工具完成Log配置,将Log信息写入Trace.log文件中
[html]
view plaincopyprint?
<?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 File 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.FlatFileTraceListenerData, 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: {message}{newline}
Category: {category}{newline}
Priority: {priority}{newline}
EventId: {eventid}{newline}
Severity: {severity}{newline}
Title:{title}{newline}
Machine: {localMachine}{newline}
App Domain: {localAppDomain}{newline}
ProcessId: {localProcessId}{newline}
Process Name: {localProcessName}{newline}
Thread Name: {threadName}{newline}
Win32 ThreadId:{win32ThreadId}{newline}
Extended Properties: {dictionary({key} - {value}{newline})}"
name="Text Formatter"
/>
</formatters>
<categorySources>
<add
switchValue="All"
name="General">
<listeners>
<add
name="Flat File Trace Listener"
/>
</listeners>
</add>
</categorySources>
<specialSources>
<allEvents
switchValue="All"
name="All Events"
/>
<notProcessed
switchValue="All"
name="Unprocessed Category"
/>
<errors
switchValue="All"
name="Logging Errors & Warnings">
<listeners>
<add
name="Flat File Trace Listener"
/>
</listeners>
</errors>
</specialSources>
</loggingConfiguration>
<startup>
<supportedRuntime
version="v4.0"
sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
<?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 File 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.FlatFileTraceListenerData, 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: {message}{newline} Category: {category}{newline} Priority: {priority}{newline} EventId: {eventid}{newline} Severity: {severity}{newline} Title:{title}{newline} Machine: {localMachine}{newline} App Domain: {localAppDomain}{newline} ProcessId: {localProcessId}{newline} Process Name: {localProcessName}{newline} Thread Name: {threadName}{newline} Win32 ThreadId:{win32ThreadId}{newline} Extended Properties: {dictionary({key} - {value}{newline})}" name="Text Formatter" /> </formatters> <categorySources> <add switchValue="All" name="General"> <listeners> <add name="Flat File Trace Listener" /> </listeners> </add> </categorySources> <specialSources> <allEvents switchValue="All" name="All Events" /> <notProcessed switchValue="All" name="Unprocessed Category" /> <errors switchValue="All" name="Logging Errors & Warnings"> <listeners> <add name="Flat File Trace Listener" /> </listeners> </errors> </specialSources> </loggingConfiguration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> </startup> </configuration>
好了,测试一下,控制台输入:
Now is 14:03,Lele is working hard!
I'm Lele.
再看看Trace.log文件内容:
[plain]
view plaincopyprint?
---------------------------------------- Timestamp: 2012/3/19 6:03:00 Message: Enter method Work Category: General Priority: -1 EventId: 1 Severity: Information Title: Machine: PC4 App Domain: AutoLog.exe ProcessId: 4200 Process Name: D:\Codes\Enterprise Library\Enterprise Library Demos\PIAB\Demo\AutoLog\bin\Debug\AutoLog.exe Thread Name: Win32 ThreadId:4000 Extended Properties: ---------------------------------------- ---------------------------------------- Timestamp: 2012/3/19 6:03:00 Message: Exception:Customer Exception Category: General Priority: -1 EventId: 1 Severity: Information Title: Machine: PC4 App Domain: AutoLog.exe ProcessId: 4200 Process Name: D:\Codes\Enterprise Library\Enterprise Library Demos\PIAB\Demo\AutoLog\bin\Debug\AutoLog.exe Thread Name: Win32 ThreadId:4000 Extended Properties: ---------------------------------------- ---------------------------------------- Timestamp: 2012/3/19 6:03:00 Message: Exit method Work, use 00:00:00.0024272. Category: General Priority: -1 EventId: 1 Severity: Information Title: Machine: PC4 App Domain: AutoLog.exe ProcessId: 4200 Process Name: D:\Codes\Enterprise Library\Enterprise Library Demos\PIAB\Demo\AutoLog\bin\Debug\AutoLog.exe Thread Name: Win32 ThreadId:4000 Extended Properties: ---------------------------------------- ---------------------------------------- Timestamp: 2012/3/19 6:03:00 Message: Enter method ToString Category: General Priority: -1 EventId: 1 Severity: Information Title: Machine: PC4 App Domain: AutoLog.exe ProcessId: 4200 Process Name: D:\Codes\Enterprise Library\Enterprise Library Demos\PIAB\Demo\AutoLog\bin\Debug\AutoLog.exe Thread Name: Win32 ThreadId:4000 Extended Properties: ---------------------------------------- ---------------------------------------- Timestamp: 2012/3/19 6:03:00 Message: Exit method ToString, use 00:00:00.0001410. Category: General Priority: -1 EventId: 1 Severity: Information Title: Machine: PC4 App Domain: AutoLog.exe ProcessId: 4200 Process Name: D:\Codes\Enterprise Library\Enterprise Library Demos\PIAB\Demo\AutoLog\bin\Debug\AutoLog.exe Thread Name: Win32 ThreadId:4000 Extended Properties: ----------------------------------------
---------------------------------------- Timestamp: 2012/3/19 6:03:00 Message: Enter method Work Category: General Priority: -1 EventId: 1 Severity: Information Title: Machine: PC4 App Domain: AutoLog.exe ProcessId: 4200 Process Name: D:\Codes\Enterprise Library\Enterprise Library Demos\PIAB\Demo\AutoLog\bin\Debug\AutoLog.exe Thread Name: Win32 ThreadId:4000 Extended Properties: ---------------------------------------- ---------------------------------------- Timestamp: 2012/3/19 6:03:00 Message: Exception:Customer Exception Category: General Priority: -1 EventId: 1 Severity: Information Title: Machine: PC4 App Domain: AutoLog.exe ProcessId: 4200 Process Name: D:\Codes\Enterprise Library\Enterprise Library Demos\PIAB\Demo\AutoLog\bin\Debug\AutoLog.exe Thread Name: Win32 ThreadId:4000 Extended Properties: ---------------------------------------- ---------------------------------------- Timestamp: 2012/3/19 6:03:00 Message: Exit method Work, use 00:00:00.0024272. Category: General Priority: -1 EventId: 1 Severity: Information Title: Machine: PC4 App Domain: AutoLog.exe ProcessId: 4200 Process Name: D:\Codes\Enterprise Library\Enterprise Library Demos\PIAB\Demo\AutoLog\bin\Debug\AutoLog.exe Thread Name: Win32 ThreadId:4000 Extended Properties: ---------------------------------------- ---------------------------------------- Timestamp: 2012/3/19 6:03:00 Message: Enter method ToString Category: General Priority: -1 EventId: 1 Severity: Information Title: Machine: PC4 App Domain: AutoLog.exe ProcessId: 4200 Process Name: D:\Codes\Enterprise Library\Enterprise Library Demos\PIAB\Demo\AutoLog\bin\Debug\AutoLog.exe Thread Name: Win32 ThreadId:4000 Extended Properties: ---------------------------------------- ---------------------------------------- Timestamp: 2012/3/19 6:03:00 Message: Exit method ToString, use 00:00:00.0001410. Category: General Priority: -1 EventId: 1 Severity: Information Title: Machine: PC4 App Domain: AutoLog.exe ProcessId: 4200 Process Name: D:\Codes\Enterprise Library\Enterprise Library Demos\PIAB\Demo\AutoLog\bin\Debug\AutoLog.exe Thread Name: Win32 ThreadId:4000 Extended Properties: ----------------------------------------
实现了自动化Log后,回过头来再看第5步,Employee继承了MarshalByRefObject,一般我们的业务类或数据访问类都有基类,那么我们就需要使用接口
这里我添加一个IEmployee接口,里面就Work方法(ToString是重写Object的)。
[csharp]
view plaincopyprint?
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 is {0},{1} is working hard!",DateTime.Now.ToShortTimeString(),Name);
throw new Exception("Customer Exception");
}
[AutoLogCallHandler()]
public override
string ToString() {
return string.Format("I'm {0}.",Name);
}
}
}
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 is {0},{1} is working hard!",DateTime.Now.ToShortTimeString(),Name); throw new Exception("Customer Exception"); } [AutoLogCallHandler()] public override string ToString() { return string.Format("I'm {0}.",Name); } } }
然后在测试类改动一下
[csharp]
view plaincopyprint?
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);
}
}
}
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); } } }
此为大牛:http://blog.csdn.net/qing2005/article/details/7368738
相关文章推荐
- C#实现自动化Log日志
- [转] C#实现自动化Log日志
- C#日志记录设计与实现(BenXHLog)
- C# 实现一个Log日志文件 以每2Mb创建一个新的日志
- c#实现记录每个线程的log日志
- C# 实现一个Log日志文件 以每2Mb创建一个新的日志
- C# 实现记录每个线程log日志
- c#程序定期把内存信息记录到log日志示例
- C#实现日志
- 【JAVA笔记——器】Spring Aop 实现Log日志系统——基本实现
- C#借助API实现黑盒自动化测试工具的编写
- 3_C# 实现VMS客户端——使用log4net 写日志
- C#实现日志记录 支持按日期多文件保存
- C# .NET 中实现 Microsoft Excel 自动化
- c#写log代码实现
- C# 实现 保存log到文件的类
- Android编程实现项目中异常捕获及对应Log日志文件保存功能
- 使用触发器实现记录oracle用户登录失败信息到alert.log日志文件
- 代码实现获取log日志