通过继承log4net.Layout.PatternLayout类,使用log4net.Core.LoggingEvent类的方法得到了要输出的message类的名称,然后通过反射得到各个属性的值,使用PatternLayout类AddConverter方法传入得到的值。这里注意要引用用到的类的命名空间。
代码见附注8.2。
配置文件其他地方不用改动,只是需要改动<appender>中的<layout>。例如:
<layout type="TGLog.ExpandLayout2.ReflectionLayout,TGLog">
<param name="ConversionPattern"
value="记录时间:%date 操作者ID:%property{Operator}
操作类型:%property{Action}%n 消息描述:%property{Message}%n 异常:%exception%n " />
</layout>
其中<layout>的type由原来的log4net.Layout.PatternLayout换为自定义的TGLog.ExpandLayout2.ReflectionLayout(TGLog.ExpandLayout2为命名空间)。%property{Operator}输出的即为message类对象的属性Operator的值。数据库配置同样,相应的字段如果是自定义的,则输出选用自定义的<layout>。例:
<!--动作类型-->
<parameter>
<parameterName value="@action_type" />
<dbType value="Int16" />
<layout type="TGLog.ExpandLayout2.ReflectionLayout,TGLog">
<conversionPattern value="%property{ActionType}" />
</layout>
</parameter>
和一般使用方法基本相同,只是传入的参数是一个自定义的类,类的属性和配置文件中<layout>所有的%property{属性}是一致的,即%property{属性}在输出的时候就查找传入message类中有无对应的属性,如果有就输出值,没有则输出null。例:
log4net.ILog log = log4net.LogManager.GetLogger("ReflectionLayout");
try
{
log.Debug(new LogMessage(
1,
"操作对象:0",
(int)TGLog.ActionType.Other,
"这是四个参数测试")
);
}
catch(Exception ec)
{
log.Error(new LogMessage(
1,
"操作对象:0",
(int)TGLog.ActionType.Other,
"这是全部参数测试",
"192.168.1.1",
"MyComputer",
"Maxthon(MyIE2)Fans"),
ec
);
}
LogMessage的全部属性的构造方法如下:
public LogMessage(
int operatorID,
string operand,
int ActionType,
string message,
string ip,
string machineName,
string browser
)
{
this.ActionType = ActionType;
this.Operator = operatorID;
this.Message = message;
this.Operand = operand;
this.IP = ip;
this.Browser = browser;
this.MachineName = machineName;
}
这种方式是通过构造一个名为IMyLog接口,是继承Ilog接口而来,然后分别在MyLogImpl,MyLogManager重新实现IMyLog接口,增加了每种方法的参数。MyLogImpl,MyLogManager分别继承LogImpl,LogManager而来。
代码分别见8.3、8.4、8.5:
配置文件其他地方不用改动,只是需要改动<appender>中的<layout>元素name为ConversionPattern的value中输出格式。例如:
<layout type=" log4net.Layout.PatternLayout ">
<param name="ConversionPattern"
value="记录时间:%date 操作者ID:%property{Operator}
操作类型:%property{Action}%n 消息描述:%property{Message}%n 异常:%exception%n " />
</layout>
%property{参数}中的参数在MyLogImpl类中定义,如语句:
loggingEvent.Properties["Operator"] = operatorID;
就定义了Operator输出参数,即%property{Operator}输出的即为IMyLog中的参数operatorID的值。
数据库配置同样。例:
<!--动作类型-->
<parameter>
<parameterName value="@action_type" />
<dbType value="Int16" />
<layout type=" log4net.Layout.PatternLayout ">
<conversionPattern value="%property{ActionType}" />
</layout>
</parameter>
先引用IMyLog ,MyLogManager所在的命名空间,创建一个IMyLog对象,myLog的5 个方法,每个方法都有四个重载,增加了多参数的重载。例:
IMyLog myLog = MyLogManager.GetLogger("ExpandILog");
try
{
myLog.Debug("这是一个参数重载测试!");
}
catch(Exception ec)
{
log.Error(
1,
"操作对象:0",
(int)TGLog.ActionType.Other,
"这是全部参数测试",
"192.168.1.1",
"MyComputer",
"Maxthon(MyIE2)Fans",
ec
);
}
Log4net 功能很多,这里只是对已经尝试用过的功能总结一下,普通写日志已经足够。需要注意的是:
1. Log4net本身也有一些缺陷,比如一个记录引起了log4net本身的异常,就会使后面的日志无法记录下来,尤其是在写入数据库时。例如使用6.1扩展后,int型的属性在<appender >的元素<bufferSize>设置不为1时,<dbTypevalue="Int32" />时,就不能输出到数据库,而<dbType value="Int16" />则没任何问题。
2. Log4net本身出现了异常,比如配置文件出现错误,有些日志输出方式会记录下这些异常,例如应用程序控制台;有些则不会输出这些错误,如数据库与文件。
3. 扩展时也会留下一些问题。例如在使用6.1扩展输出字段时就会出现,在log.debug(object message)中,如果message是一个自定义的类,属性与配置文件中输出设置也一致,构造函数时也只构造一个参数的实例,写文件与写数据库都成功,而将message按没有扩展的方式直接传入一个字符串,即log.debug(“信息内容”)使用则只能写入文件,而数据库则没写入。自定义的Layout 就是继承默认的PatternLayout,本来不应该出错,但出现了问题。原因分析是自定义的message类有类型为int的属性,作为一个对象传入时在默认值0,而直接使用字符串则int型的字段得不到默认值,引发异常。所以建议在有扩展存在时,最好多设几个<logger>,区分清楚,按照统一的形式记录日志,不要混合使用。
4. 配置文件的设置一定要准确,在一点不正确就会导致日志不能正常输出,所以在配置时先从最简单的开始,同时输出方式选择一种能输出log4net本身异常的方式,成功后一点一点加在新配置,这样出错了也容易找到那个地方配置有问题。
5. log4net扩展性很强,几乎所有的组件都可以重写,在配置文件中配置好就可以使用。
转换字符 |
效果 |
a |
等价于appdomain |
appdomain |
引发日志事件的应用程序域的友好名称。(使用中一般是可执行文件的名字。) |
c |
等价于 logger |
C |
等价于 type |
class |
等价于 type |
d |
等价于 date |
date |
发生日志事件的本地时间。 使用 DE>%utcdate 输出UTC时间。date后面还可以跟一个日期格式,用大括号括起来。DE>例如:%date{HH:mm:ss,fff}或者%date{dd MMM yyyy HH:mm:ss,fff}。如果date后面什么也不跟,将使用ISO8601 格式 。 日期格式和.Net中DateTime类的ToString方法中使用的格式是一样。 另外log4net还有3个自己的格式Formatter。 它们是 "ABSOLUTE", "DATE"和"ISO8601"分别代表 AbsoluteTimeDateFormatter, DateTimeDateFormatter和Iso8601DateFormatter。例如: %date{ISO8601}或%date{ABSOLUTE}。 它们的性能要好于ToString。 |
exception |
异常信息 日志事件中必须存了一个异常对象,如果日志事件不包含没有异常对象,将什么也不输出。异常输出完毕后会跟一个换行。一般会在输出异常前加一个换行,并将异常放在最后。 |
F |
等价于 file |
file |
发生日志请求的源代码文件的名字。 警告:只在调试的时候有效。调用本地信息会影响性能。 |
identity |
当前活动用户的名字(Principal.Identity.Name). 警告:会影响性能。(我测试的时候%identity返回都是空的。) |
l |
等价于 location |
L |
等价于 line |
location |
引发日志事件的方法(包括命名空间和类名),以及所在的源文件和行号。 警告:会影响性能。没有pdb文件的话,只有方法名,没有源文件名和行号。 |
level |
日志事件等级 |
line |
引发日志事件的行号 警告:会影响性能。 |
logger |
记录日志事件的Logger对象的名字。 可以使用精度说明符控制Logger的名字的输出层级,默认输出全名。 注意,精度符的控制是从右开始的。例如:logger 名为 "a.b.c", 输出模型为 %logger{2} ,将输出"b.c"。 |
m |
等价于 message |
M |
等价于 method |
message |
由应用程序提供给日志事件的消息。 |
mdc |
MDC (旧为:ThreadContext.Properties) 现在是事件属性的一部分。 保留它是为了兼容性,它等价于 property。 |
method |
发生日志请求的方法名(只有方法名而已)。 警告:会影响性能。 |
n |
等价于 newline |
newline |
换行符 |
ndc |
NDC (nested diagnostic context) |
p |
等价于 level |
P |
等价于 property |
properties |
等价于 property |
property |
输出事件的特殊属性。例如: %property{user} 输出user属性。属性是由loggers或appenders添加到时间中的。 有一个默认的属性"DE>log4net:HostName"总是会有。DE> %property将输出所有的属性 。 (扩展后可以使用)
|
r |
等价于 timestamp |
t |
等价于 thread |
timestamp |
从程序启动到事件发生所经过的毫秒数。 |
thread |
引发日志事件的线程,如果没有线程名就使用线程号。 |
type |
引发日志请求的类的全名。. 可以使用精度控制符。例如: 类名是 "log4net.Layout.PatternLayout", 格式模型是%type{1} 将输出"PatternLayout"。(也是从右开始的。) 警告:会影响性能。 |
u |
等价于 identity |
username |
当前用户的WindowsIdentity。(类似:HostName\Username) 警告:会影响性能。 |
utcdate |
发生日志事件的UTC时间。DE>后面还可以跟一个日期格式,用大括号括起来。DE>例如:%utcdate{HH:mm:ss,fff}或者%utcdate{dd MMM yyyy HH:mm:ss,fff}。如果utcdate后面什么也不跟,将使用ISO8601 格式 。 日期格式和.Net中DateTime类的ToString方法中使用的格式是一样。 另外log4net还有3个自己的格式Formatter。 它们是 "ABSOLUTE", "DATE"和"ISO8601"分别代表 AbsoluteTimeDateFormatter, DateTimeDateFormatter和Iso8601DateFormatter。例如: %date{ISO8601}或%date{ABSOLUTE}。 它们的性能要好于ToString。 |
w |
等价于 username |
x |
等价于 ndc |
X |
等价于 mdc |
% |
%%输出一个百分号 |
关于调用本地信息(caller location information)的说明:
%type %file %line %method %location %class %C %F %L %l %M 都会调用本地信息。这样做会影响性能。本地信息使用System.Diagnostics.StackTrace得到。.Net 1.0 不支持System.Diagnostics.StackTrace 类。
本地信息在调试模式下可以正常获取,在非调试模式下可能获取不到,或只能获取一部分。(根据我的测试,其实是需要有一个程序数据库(.pdb)文件。)
%property属性要用代码来设置才能使用(也就是扩展一下),
默认属性log4net:HostName不用设置。
转义字符的修饰符:
Format modifier |
left justify |
minimum width |
maximum width |
comment |
%20logger |
false |
20 |
none |
如果logger名不足20个字符,就在左边补空格。 |
%-20logger |
true |
20 |
none |
如果logger名不足20个字符,就在右边补空格。 |
%.30logger |
NA |
none |
30 |
超过30个字符将截断。 |
%20.30logger |
false |
20 |
30 |
logger名要在20到30之间,少了在左边补空格,多了截断。 |
%-20.30logger |
true |
20 |
30 |
logger名要在20到30之间,少了在右边补空格,多了截断。 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using log4net.Layout; using log4net.Layout.Pattern; using System.Reflection; using System.Collections; using FastReflectionLib; namespace TGLog.ExpandLayout2 { public class ReflectionLayout : PatternLayout { public ReflectionLayout() { this.AddConverter("property", typeof(ReflectionPatternConverter)); } } public class ReflectionPatternConverter : PatternLayoutConverter { protected override void Convert( System.IO.TextWriter writer, log4net.Core.LoggingEvent loggingEvent ) { if (Option != null) { // 写入指定键的值 WriteObject( writer, loggingEvent.Repository, LookupProperty(Option, loggingEvent) ); } else { // 写入所有关键值对 WriteDictionary( writer, loggingEvent.Repository, loggingEvent.GetProperties() ); } } /// <summary> /// 通过反射获取传入的日志对象的某个属性的值 /// </summary> /// <param name="property"></param> /// <returns></returns> private object LookupProperty( string property, log4net.Core.LoggingEvent loggingEvent) { object propertyValue = string.Empty; PropertyInfo propertyInfo = loggingEvent.MessageObject.GetType().GetProperty(property); if (propertyInfo != null) { propertyValue = propertyInfo.GetValue(loggingEvent.MessageObject, null); } return propertyValue; } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using log4net.Core; namespace TGLog.ExpandILog { public class MyLogImpl : LogImpl, IMyLog { /// <summary> /// The fully qualified name of this declaring type not the type of any subclass. /// </summary> private readonly static Type ThisDeclaringType = typeof(MyLogImpl); public MyLogImpl(ILogger logger) : base(logger) { } #region Implementation of IMyLog public void Debug(int operatorID, string operand, int actionType,object message, string ip, string browser, string machineName) { Debug(operatorID, operand, actionType, message, ip, browser, machineName, null); } public void Debug(int operatorID, string operand, int actionType,object message, string ip, string browser, string machineName, System.Exception t) { if (this.IsDebugEnabled) { LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Info, message, t); loggingEvent.Properties["Operator"] = operatorID; loggingEvent.Properties["Operand"] = operand; loggingEvent.Properties["ActionType"] = actionType; loggingEvent.Properties["IP"] = ip; loggingEvent.Properties["Browser"] = browser; loggingEvent.Properties["MachineName"] = machineName; Logger.Log(loggingEvent); } } public void Info(int operatorID, string operand, int actionType, object message, string ip, string browser, string machineName) { Info(operatorID, operand, actionType, message, ip, browser, machineName, null); } public void Info(int operatorID, string operand, int actionType, object message, string ip, string browser, string machineName, System.Exception t) { if (this.IsInfoEnabled) { LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Info, message, t); loggingEvent.Properties["Operator"] = operatorID; loggingEvent.Properties["Operand"] = operand; loggingEvent.Properties["ActionType"] = actionType; loggingEvent.Properties["IP"] = ip; loggingEvent.Properties["Browser"] = browser; loggingEvent.Properties["MachineName"] = machineName; Logger.Log(loggingEvent); } } public void Warn(int operatorID, string operand, int actionType, object message, string ip, string browser, string machineName) { Warn(operatorID, operand, actionType, message, ip, browser, machineName, null); } public void Warn(int operatorID, string operand, int actionType, object message, string ip, string browser, string machineName, System.Exception t) { if (this.IsWarnEnabled) { LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Info, message, t); loggingEvent.Properties["Operator"] = operatorID; loggingEvent.Properties["Operand"] = operand; loggingEvent.Properties["ActionType"] = actionType; loggingEvent.Properties["IP"] = ip; loggingEvent.Properties["Browser"] = browser; loggingEvent.Properties["MachineName"] = machineName; Logger.Log(loggingEvent); } } public void Error(int operatorID, string operand, int actionType, object message, string ip, string browser, string machineName) { Error(operatorID, operand, actionType, message, ip, browser, machineName, null); } public void Error(int operatorID, string operand, int actionType, object message, string ip, string browser, string machineName, System.Exception t) { if (this.IsErrorEnabled) { LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Info, message, t); loggingEvent.Properties["Operator"] = operatorID; loggingEvent.Properties["Operand"] = operand; loggingEvent.Properties["ActionType"] = actionType; loggingEvent.Properties["IP"] = ip; loggingEvent.Properties["Browser"] = browser; loggingEvent.Properties["MachineName"] = machineName; Logger.Log(loggingEvent); } } public void Fatal(int operatorID, string operand, int actionType, object message, string ip, string browser, string machineName) { Fatal(operatorID, operand, actionType, message, ip, browser, machineName, null); } public void Fatal(int operatorID, string operand, int actionType, object message, string ip, string browser, string machineName, System.Exception t) { if (this.IsFatalEnabled) { LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Info, message, t); loggingEvent.Properties["Operator"] = operatorID; loggingEvent.Properties["Operand"] = operand; loggingEvent.Properties["ActionType"] = actionType; loggingEvent.Properties["IP"] = ip; loggingEvent.Properties["Browser"] = browser; loggingEvent.Properties["MachineName"] = machineName; Logger.Log(loggingEvent); } } #endregion Implementation of IMyLog } }
#region Copyright & License // // Copyright 2001-2005 The Apache Software Foundation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #endregion using System; using System.Reflection; using System.Collections; using log4net; using log4net.Core; using log4net.Repository; using log4net.Repository.Hierarchy; namespace TGLog.ExpandILog { public class MyLogManager { #region Static Member Variables /// <summary> /// The wrapper map to use to hold the <see cref="EventIDLogImpl"/> objects /// </summary> private static readonly WrapperMap s_wrapperMap = new WrapperMap(new WrapperCreationHandler(WrapperCreationHandler)); #endregion #region Constructor /// <summary> /// Private constructor to prevent object creation /// </summary> private MyLogManager() { } #endregion #region Type Specific Manager Methods /// <summary> /// Returns the named logger if it exists /// </summary> /// <remarks> /// <para>If the named logger exists (in the default hierarchy) then it /// returns a reference to the logger, otherwise it returns /// <c>null</c>.</para> /// </remarks> /// <param name="name">The fully qualified logger name to look for</param> /// <returns>The logger found, or null</returns> public static IMyLog Exists(string name) { return Exists(Assembly.GetCallingAssembly(), name); } /// <summary> /// Returns the named logger if it exists /// </summary> /// <remarks> /// <para>If the named logger exists (in the specified domain) then it /// returns a reference to the logger, otherwise it returns /// <c>null</c>.</para> /// </remarks> /// <param name="domain">the domain to lookup in</param> /// <param name="name">The fully qualified logger name to look for</param> /// <returns>The logger found, or null</returns> public static IMyLog Exists(string domain, string name) { return WrapLogger(LoggerManager.Exists(domain, name)); } /// <summary> /// Returns the named logger if it exists /// </summary> /// <remarks> /// <para>If the named logger exists (in the specified assembly's domain) then it /// returns a reference to the logger, otherwise it returns /// <c>null</c>.</para> /// </remarks> /// <param name="assembly">the assembly to use to lookup the domain</param> /// <param name="name">The fully qualified logger name to look for</param> /// <returns>The logger found, or null</returns> public static IMyLog Exists(Assembly assembly, string name) { return WrapLogger(LoggerManager.Exists(assembly, name)); } /// <summary> /// Returns all the currently defined loggers in the default domain. /// </summary> /// <remarks> /// <para>The root logger is <b>not</b> included in the returned array.</para> /// </remarks> /// <returns>All the defined loggers</returns> public static IMyLog[] GetCurrentLoggers() { return GetCurrentLoggers(Assembly.GetCallingAssembly()); } /// <summary> /// Returns all the currently defined loggers in the specified domain. /// </summary> /// <param name="domain">the domain to lookup in</param> /// <remarks> /// The root logger is <b>not</b> included in the returned array. /// </remarks> /// <returns>All the defined loggers</returns> public static IMyLog[] GetCurrentLoggers(string domain) { return WrapLoggers(LoggerManager.GetCurrentLoggers(domain)); } /// <summary> /// Returns all the currently defined loggers in the specified assembly's domain. /// </summary> /// <param name="assembly">the assembly to use to lookup the domain</param> /// <remarks> /// The root logger is <b>not</b> included in the returned array. /// </remarks> /// <returns>All the defined loggers</returns> public static IMyLog[] GetCurrentLoggers(Assembly assembly) { return WrapLoggers(LoggerManager.GetCurrentLoggers(assembly)); } /// <summary> /// Retrieve or create a named logger. /// </summary> /// <remarks> /// <para>Retrieve a logger named as the <paramref name="name"/> /// parameter. If the named logger already exists, then the /// existing instance will be returned. Otherwise, a new instance is /// created.</para> /// /// <para>By default, loggers do not have a set level but inherit /// it from the hierarchy. This is one of the central features of /// log4net.</para> /// </remarks> /// <param name="name">The name of the logger to retrieve.</param> /// <returns>the logger with the name specified</returns> public static IMyLog GetLogger(string name) { return GetLogger(Assembly.GetCallingAssembly(), name); } /// <summary> /// Retrieve or create a named logger. /// </summary> /// <remarks> /// <para>Retrieve a logger named as the <paramref name="name"/> /// parameter. If the named logger already exists, then the /// existing instance will be returned. Otherwise, a new instance is /// created.</para> /// /// <para>By default, loggers do not have a set level but inherit /// it from the hierarchy. This is one of the central features of /// log4net.</para> /// </remarks> /// <param name="domain">the domain to lookup in</param> /// <param name="name">The name of the logger to retrieve.</param> /// <returns>the logger with the name specified</returns> public static IMyLog GetLogger(string domain, string name) { return WrapLogger(LoggerManager.GetLogger(domain, name)); } /// <summary> /// Retrieve or create a named logger. /// </summary> /// <remarks> /// <para>Retrieve a logger named as the <paramref name="name"/> /// parameter. If the named logger already exists, then the /// existing instance will be returned. Otherwise, a new instance is /// created.</para> /// /// <para>By default, loggers do not have a set level but inherit /// it from the hierarchy. This is one of the central features of /// log4net.</para> /// </remarks> /// <param name="assembly">the assembly to use to lookup the domain</param> /// <param name="name">The name of the logger to retrieve.</param> /// <returns>the logger with the name specified</returns> public static IMyLog GetLogger(Assembly assembly, string name) { return WrapLogger(LoggerManager.GetLogger(assembly, name)); } /// <summary> /// Shorthand for <see cref="LogManager.GetLogger(string)"/>. /// </summary> /// <remarks> /// Get the logger for the fully qualified name of the type specified. /// </remarks> /// <param name="type">The full name of <paramref name="type"/> will /// be used as the name of the logger to retrieve.</param> /// <returns>the logger with the name specified</returns> public static IMyLog GetLogger(Type type) { return GetLogger(Assembly.GetCallingAssembly(), type.FullName); } /// <summary> /// Shorthand for <see cref="LogManager.GetLogger(string)"/>. /// </summary> /// <remarks> /// Get the logger for the fully qualified name of the type specified. /// </remarks> /// <param name="domain">the domain to lookup in</param> /// <param name="type">The full name of <paramref name="type"/> will /// be used as the name of the logger to retrieve.</param> /// <returns>the logger with the name specified</returns> public static IMyLog GetLogger(string domain, Type type) { return WrapLogger(LoggerManager.GetLogger(domain, type)); } /// <summary> /// Shorthand for <see cref="LogManager.GetLogger(string)"/>. /// </summary> /// <remarks> /// Get the logger for the fully qualified name of the type specified. /// </remarks> /// <param name="assembly">the assembly to use to lookup the domain</param> /// <param name="type">The full name of <paramref name="type"/> will /// be used as the name of the logger to retrieve.</param> /// <returns>the logger with the name specified</returns> public static IMyLog GetLogger(Assembly assembly, Type type) { return WrapLogger(LoggerManager.GetLogger(assembly, type)); } #endregion #region Extension Handlers /// <summary> /// Lookup the wrapper object for the logger specified /// </summary> /// <param name="logger">the logger to get the wrapper for</param> /// <returns>the wrapper for the logger specified</returns> private static IMyLog WrapLogger(ILogger logger) { return (IMyLog)s_wrapperMap.GetWrapper(logger); } /// <summary> /// Lookup the wrapper objects for the loggers specified /// </summary> /// <param name="loggers">the loggers to get the wrappers for</param> /// <returns>Lookup the wrapper objects for the loggers specified</returns> private static IMyLog[] WrapLoggers(ILogger[] loggers) { IMyLog[] results = new IMyLog[loggers.Length]; for (int i = 0; i < loggers.Length; i++) { results[i] = WrapLogger(loggers[i]); } return results; } /// <summary> /// Method to create the <see cref="ILoggerWrapper"/> objects used by /// this manager. /// </summary> /// <param name="logger">The logger to wrap</param> /// <returns>The wrapper for the logger specified</returns> private static ILoggerWrapper WrapperCreationHandler(ILogger logger) { return new MyLogImpl(logger); } #endregion } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using log4net; namespace TGLog.ExpandILog { public interface IMyLog : ILog { void Debug(int operatorID, string operand, int actionType, object message, string ip, string browser, string machineName); void Debug(int operatorID, string operand, int actionType,object message, string ip, string browser, string machineName, Exception t); void Info(int operatorID, string operand, int actionType, object message, string ip, string browser, string machineName); void Info(int operatorID, string operand, int actionType, object message, string ip, string browser, string machineName, Exception t); void Warn(int operatorID, string operand, int actionType, object message, string ip, string browser, string machineName); void Warn(int operatorID, string operand, int actionType, object message, string ip, string browser, string machineName, Exception t); void Error(int operatorID, string operand, int actionType, object message, string ip, string browser, string machineName); void Error(int operatorID, string operand, int actionType, object message, string ip, string browser, string machineName, Exception t); void Fatal(int operatorID, string operand, int actionType, object message, string ip, string browser, string machineName); void Fatal(int operatorID, string operand, int actionType, object message, string ip, string browser, string machineName, Exception t); } }