Log4Net是一款开源的框架,功能比较强大,支持多种方式的日志信息记录,在.NET平台开发,使用Log4Net框架是一个不错的选择,log4Net的使用是非常简单的,需要引用log4Net的dll,然后配置一下配置文件就可以使用了如:在要打印日志的地方LogManager.GetLogger(typeof(Program)).Debug("信息"); 。
(2)写一个类KanqLogImpl继承LogImpl和实现IKanqLog接口
(3)创建一个类KanqLogManager,去模仿LogManager重写里面的方法,具体可以去看开源的代码,如下
发现log4Net还是蛮强大的,比较好扩展,扩展后能够满足系统的开发要求,以上就是对Log4Net的扩展。
注意:
1)Appender:可以将日志输出到不同的地方,不同的输出目标对应不同的Appender:RollingFileAppender(滚动文件)、AdoNetAppender(数据库)、SmtpAppender (邮件)等。Log4Net还可以设定多个Appender,可以实现同时将日志记录到文件、数据、发送邮件等;
2)level(级别):标识这条日志信息的重要级别。None>Fatal>ERROR>WARN>DEBUG>INFO>ALL,设定一个Level,那么低于这个Level的日志是不会被写到Appender中的。3)除了Log4Net,还有Enterprise Library中的Logging Application Block、Apache的CommonLog 以及NLog等,都差不多。
在我最近做的一个项目中需要使用对系统的日志信息和异常信息进行记录,在使用中发现如果仅仅使用log4Net是无法满足要求的,因此,我们需要对log4Net进行扩展,下面我就详细说说如何对log4Net进行扩展以满足系统开发的要求:
(1)我们需要自己写一个接口IKanqLog
public interface IKanqLog
{
void Info(string title, int ErrLevelNum, object message);
void Info(string title, int ErrLevelNum, object message, Exception t);
void Warn(string title,int ErrLevelNum, object message);
void Warn(string title, int ErrLevelNum, object message, Exception t);
void Error(string title,int ErrLevelNum, object message);
void Error(string title,int ErrLevelNum, object message, Exception t);
void Fatal(string title, int ErrLevelNum, object message);
void Fatal(string title, int ErrLevelNum, object message, Exception t);
void Info(int dailyType, int operateType,string operateUser,string remark, object message);
void Info(int dailyType, int operateType, string operateUser, string remark, object message, Exception t);
void Warn(int dailyType, int operateType, string operateUser, string remark, object message);
void Warn(int dailyType, int operateType, string operateUser, string remark, object message, Exception t);
void Error(int dailyType, int operateType, string operateUser, string remark, object message);
void Error(int dailyType, int operateType, string operateUser, string remark, object message, Exception t);
void Fatal(int dailyType, int operateType, string operateUser, string remark, object message);
void Fatal(int dailyType, int operateType, string operateUser, string remark, object message, Exception t);
}
(2)写一个类KanqLogImpl继承LogImpl和实现IKanqLog接口
public class KanqLogImpl:LogImpl,IKanqLog
{
private readonly static Type ThisDeclaringType = typeof(KanqLogImpl);
public KanqLogImpl(ILogger logger)
: base(logger)
{
}
public void Info(string title, int ErrLevelNum, object message)
{
Info(title, ErrLevelNum, message, null);
}
public void Info(string title, int ErrLevelNum, object message, System.Exception t)
{
if (this.IsInfoEnabled)
{
LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Info, message, t);
loggingEvent.Properties["ErrTitle"] = title;
loggingEvent.Properties["ErrorLevelNum"] = ErrLevelNum;
Logger.Log(loggingEvent);
}
}
public void Warn(string title, int ErrLevelNum, object message)
{
Warn(title, ErrLevelNum, message, null);
}
public void Warn(string title, int ErrLevelNum, object message, System.Exception t)
{
if (this.IsWarnEnabled)
{
LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Warn, message, t);
loggingEvent.Properties["ErrTitle"] = title;
loggingEvent.Properties["ErrorLevelNum"] = ErrLevelNum;
Logger.Log(loggingEvent);
}
}
public void Error(string title, int ErrLevelNum, object message)
{
Error(title, ErrLevelNum, message,null);
}
public void Error(string title, int ErrLevelNum, object message, System.Exception t)
{
if (this.IsErrorEnabled)
{
LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Error, message, t);
loggingEvent.Properties["ErrTitle"] = title;
loggingEvent.Properties["ErrorLevelNum"] = ErrLevelNum;
Logger.Log(loggingEvent);
}
}
public void Fatal(string title, int ErrLevelNum, object message)
{
Fatal(title, ErrLevelNum, message, null);
}
public void Fatal(string title, int ErrLevelNum, object message, System.Exception t)
{
if (this.IsFatalEnabled)
{
LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Fatal, message, t);
loggingEvent.Properties["ErrTitle"] = title;
loggingEvent.Properties["ErrorLevelNum"] = ErrLevelNum;
Logger.Log(loggingEvent);
}
}
public void Info(int dailyType, int operateType, string operateUser, string remark, object message)
{
Info(dailyType, operateType, operateUser, remark, message, null);
}
public void Info(int dailyType, int operateType, string operateUser, string remark, object message, System.Exception t)
{
if (this.IsInfoEnabled)
{
LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Info, message, t);
loggingEvent.Properties["DailyType"] = dailyType;
loggingEvent.Properties["OperateType"] = operateType;
loggingEvent.Properties["OperateUser"] = operateUser;
loggingEvent.Properties["OperateRemark"] = remark;
Logger.Log(loggingEvent);
}
}
public void Warn(int dailyType, int operateType, string operateUser, string remark, object message)
{
Warn(dailyType, operateType, operateUser, remark, message, null);
}
public void Warn(int dailyType, int operateType, string operateUser, string remark, object message, System.Exception t)
{
if (this.IsWarnEnabled)
{
LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Warn, message, t);
loggingEvent.Properties["DailyType"] = dailyType;
loggingEvent.Properties["OperateType"] = operateType;
loggingEvent.Properties["OperateUser"] = operateUser;
loggingEvent.Properties["OperateRemark"] = remark;
Logger.Log(loggingEvent);
}
}
public void Error(int dailyType, int operateType, string operateUser, string remark, object message)
{
Error(dailyType, operateType, operateUser, remark, message, null);
}
public void Error(int dailyType, int operateType, string operateUser, string remark, object message, System.Exception t)
{
if (this.IsErrorEnabled)
{
LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Error, message, t);
loggingEvent.Properties["DailyType"] = dailyType;
loggingEvent.Properties["OperateType"] = operateType;
loggingEvent.Properties["OperateUser"] = operateUser;
loggingEvent.Properties["OperateRemark"] = remark;
Logger.Log(loggingEvent);
}
}
public void Fatal(int dailyType, int operateType, string operateUser, string remark, object message)
{
Fatal(dailyType, operateType, operateUser, remark, message, null);
}
public void Fatal(int dailyType, int operateType, string operateUser, string remark, object message, System.Exception t)
{
if (this.IsFatalEnabled)
{
LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Fatal, message, t);
loggingEvent.Properties["DailyType"] = dailyType;
loggingEvent.Properties["OperateType"] = operateType;
loggingEvent.Properties["OperateUser"] = operateUser;
loggingEvent.Properties["OperateRemark"] = remark;
Logger.Log(loggingEvent);
}
}
}
(3)创建一个类KanqLogManager,去模仿LogManager重写里面的方法,具体可以去看开源的代码,如下
private static IKanqLog WrapLogger(ILogger logger)
{
return (IKanqLog)s_wrapperMap.GetWrapper(logger);
}
private static IKanqLog[] WrapLoggers(ILogger[] loggers)
{
IKanqLog[] results = new IKanqLog[loggers.Length];
for(int i=0; i<loggers.Length; i++)
{
results[i] = WrapLogger(loggers[i]);
}
return results;
}
private static ILoggerWrapper WrapperCreationHandler(ILogger logger)
{
return new KanqLogImpl(logger);
}
(4)最重要的是,配置config文件,具体部分配置如下:
<appender name="AdoNetAppender_Oracle" type="log4net.Appender.AdoNetAppender">
<bufferSize value="1" />
<connectionType value="System.Data.OracleClient.OracleConnection, System.Data.OracleClient, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<connectionString value="data source=192.168.1.188/orcl;Persist Security Info=True;User ID=ywgl;Password=ywgl" />
<commandText value="INSERT INTO YWGL_ErrorInfo(Title,ErrorContent,ErrorLevel,CreateTime) VALUES (:Title,:ErrorContent,:ErrorLevel,:CreateTime)"/>
<parameter>
<parameterName value=":Title"/>
<dbType value="String"/>
<size value="200"/>
<layout type="log4net.Layout.PatternLayout" value="%property{ErrTitle}"/>
</parameter>
<parameter>
<parameterName value=":ErrorContent"/>
<dbType value="String"/>
<size value="4000"/>
<layout type="log4net.Layout.PatternLayout" value="%message"/>
<param name="LevelMin" value="INFO"/>
<param name="LevelMax" value="ERROR"/>
</parameter>
<parameter>
<parameterName value=":ErrorLevel"/>
<dbType value="Int16"/>
<layout type="log4net.Layout.PatternLayout" value="%property{ErrorLevelNum}"/>
</parameter>
<parameter>
<parameterName value=":CreateTime"/>
<dbType value="DateTime"/>
<layout type="log4net.Layout.PatternLayout" value="%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff}"/>
</parameter>
</appender>
发现log4Net还是蛮强大的,比较好扩展,扩展后能够满足系统的开发要求,以上就是对Log4Net的扩展。