log4net在.net中的应用
log4x是一个日志记录组件,有java和dotnet等多个中版本,dotnet的版本叫log4net,提供分级别的日志记录功能,有关log4x的详细信息可以查阅其reference,这里不多说。我仅以一个例子的形式说明log4net的配置及使用方式。
首先在项目里引入log4net的dll:
我这里给出一个下载/Files/zyip/log4net.rar,您只需下载并加入项目引用即可使用。
log4net需要一个配置文件,该文件可以取任意名字,这里给出一个实例:
Code
<log4net>
<!-- Define some output appenders -->
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] <%X{auth}> - %m%n" />
</layout>
</appender>
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="1" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<!--<connectionString value="data source=[database server];initial catalog=[database name];integrated security=false;persist security info=True;User ID=[user];Password=[password]" />-->
<connectionString value="Data Source=.\sqlexpress;Initial Catalog=SchoolMIS1ForBS;User ID=zy;password=123456"/>
<commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" />
<parameter>
<parameterName value="@log_date" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
<parameterName value="@thread" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%thread" />
</layout>
</parameter>
<parameter>
<parameterName value="@log_level" />
<dbType value="String" />
<size value="50" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level" />
</layout>
</parameter>
<parameter>
<parameterName value="@logger" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%logger" />
</layout>
</parameter>
<parameter>
<parameterName value="@message" />
<dbType value="String" />
<size value="4000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
<parameter>
<parameterName value="@exception" />
<dbType value="String" />
<size value="2000" />
<layout type="log4net.Layout.ExceptionLayout" />
</parameter>
</appender>
<!-- FileAppender appends to a log and it is manually managed or size -->
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<param name="File" value="log.txt" />
<!-- Example using environment variables in params -->
<!-- <param name="File" value="${TMP}\\ApplicationKit.log" /> -->
<param name="AppendToFile" value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n" />
</layout>
</appender>
<!-- Setup the root category, add the appenders and set the default level -->
<!--<root>
<level value="ALL" />
<appender-ref ref="AdoNetAppender" />
</root>-->
<!-- ApplicationKit category - the presentation UI -->
<logger name="log">
<!--<level value="DEBUG" />-->
<level value="info" />
<appender-ref ref="AdoNetAppender" />
</logger>
</log4net>
<log4net>
<!-- Define some output appenders -->
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] <%X{auth}> - %m%n" />
</layout>
</appender>
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="1" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<!--<connectionString value="data source=[database server];initial catalog=[database name];integrated security=false;persist security info=True;User ID=[user];Password=[password]" />-->
<connectionString value="Data Source=.\sqlexpress;Initial Catalog=SchoolMIS1ForBS;User ID=zy;password=123456"/>
<commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" />
<parameter>
<parameterName value="@log_date" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
<parameterName value="@thread" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%thread" />
</layout>
</parameter>
<parameter>
<parameterName value="@log_level" />
<dbType value="String" />
<size value="50" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level" />
</layout>
</parameter>
<parameter>
<parameterName value="@logger" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%logger" />
</layout>
</parameter>
<parameter>
<parameterName value="@message" />
<dbType value="String" />
<size value="4000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
<parameter>
<parameterName value="@exception" />
<dbType value="String" />
<size value="2000" />
<layout type="log4net.Layout.ExceptionLayout" />
</parameter>
</appender>
<!-- FileAppender appends to a log and it is manually managed or size -->
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<param name="File" value="log.txt" />
<!-- Example using environment variables in params -->
<!-- <param name="File" value="${TMP}\\ApplicationKit.log" /> -->
<param name="AppendToFile" value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n" />
</layout>
</appender>
<!-- Setup the root category, add the appenders and set the default level -->
<!--<root>
<level value="ALL" />
<appender-ref ref="AdoNetAppender" />
</root>-->
<!-- ApplicationKit category - the presentation UI -->
<logger name="log">
<!--<level value="DEBUG" />-->
<level value="info" />
<appender-ref ref="AdoNetAppender" />
</logger>
</log4net>
这个配置是将日志信息输出到sql数据库的,数据库还需要相应的表,创建表的sql语句如下:
Code
CREATE TABLE [dbo].[Log] (
[Id] [int] IDENTITY (1, 1) NOT NULL,
[Date] [datetime] NOT NULL,
[Thread] [varchar] (255) NOT NULL,
[Level] [varchar] (50) NOT NULL,
[Logger] [varchar] (255) NOT NULL,
[Message] [varchar] (4000) NOT NULL,
[Exception] [varchar] (2000) NULL
)
CREATE TABLE [dbo].[Log] (
[Id] [int] IDENTITY (1, 1) NOT NULL,
[Date] [datetime] NOT NULL,
[Thread] [varchar] (255) NOT NULL,
[Level] [varchar] (50) NOT NULL,
[Logger] [varchar] (255) NOT NULL,
[Message] [varchar] (4000) NOT NULL,
[Exception] [varchar] (2000) NULL
)
下面就可以调用log4net编程了,为了方便使用,我封装了一个类:
Code
public class Log
{
//FATAL > ERROR > WARN > INFO > DEBUG
private static string DefaultName = "log";
static Log()
{
//string path = @"C:\ConsoleApplication1\ConsoleApplication1\log.config";
string path = System.Web.HttpContext.Current.Server.MapPath(@"~\log.config");
log4net.Config.XmlConfigurator.Configure(new FileInfo(path));
}
//static ~Log()
//{
// log4net.LogManager.Shutdown();
//}
public static log4net.ILog GetLog(string logName)
{
log4net.ILog log = log4net.LogManager.GetLogger(logName);
return log;
}
public static void debug(string message)
{
log4net.ILog log = log4net.LogManager.GetLogger(DefaultName);
if (log.IsDebugEnabled)
{
log.Debug(message);
}
log = null;
}
public static void debug(string message,Exception ex)
{
log4net.ILog log = log4net.LogManager.GetLogger(DefaultName);
if (log.IsDebugEnabled)
{
log.Debug(message,ex);
}
log = null;
}
public static void error(string message)
{
log4net.ILog log = log4net.LogManager.GetLogger(DefaultName);
if (log.IsErrorEnabled)
{
log.Error(message);
}
log = null;
}
public static void error(string message,Exception ex)
{
log4net.ILog log = log4net.LogManager.GetLogger(DefaultName);
if (log.IsErrorEnabled)
{
log.Error(message,ex);
}
log = null;
}
public static void fatal(string message)
{
log4net.ILog log = log4net.LogManager.GetLogger(DefaultName);
if (log.IsFatalEnabled)
{
log.Fatal(message);
}
log = null;
}
public static void info(string message)
{
log4net.ILog log = log4net.LogManager.GetLogger(DefaultName);
if (log.IsInfoEnabled)
{
log.Info(message);
}
log = null;
}
public static void warn(string message)
{
log4net.ILog log = log4net.LogManager.GetLogger(DefaultName);
if (log.IsWarnEnabled)
{
log.Warn(message);
}
log = null;
}
}
public class Log
{
//FATAL > ERROR > WARN > INFO > DEBUG
private static string DefaultName = "log";
static Log()
{
//string path = @"C:\ConsoleApplication1\ConsoleApplication1\log.config";
string path = System.Web.HttpContext.Current.Server.MapPath(@"~\log.config");
log4net.Config.XmlConfigurator.Configure(new FileInfo(path));
}
//static ~Log()
//{
// log4net.LogManager.Shutdown();
//}
public static log4net.ILog GetLog(string logName)
{
log4net.ILog log = log4net.LogManager.GetLogger(logName);
return log;
}
public static void debug(string message)
{
log4net.ILog log = log4net.LogManager.GetLogger(DefaultName);
if (log.IsDebugEnabled)
{
log.Debug(message);
}
log = null;
}
public static void debug(string message,Exception ex)
{
log4net.ILog log = log4net.LogManager.GetLogger(DefaultName);
if (log.IsDebugEnabled)
{
log.Debug(message,ex);
}
log = null;
}
public static void error(string message)
{
log4net.ILog log = log4net.LogManager.GetLogger(DefaultName);
if (log.IsErrorEnabled)
{
log.Error(message);
}
log = null;
}
public static void error(string message,Exception ex)
{
log4net.ILog log = log4net.LogManager.GetLogger(DefaultName);
if (log.IsErrorEnabled)
{
log.Error(message,ex);
}
log = null;
}
public static void fatal(string message)
{
log4net.ILog log = log4net.LogManager.GetLogger(DefaultName);
if (log.IsFatalEnabled)
{
log.Fatal(message);
}
log = null;
}
public static void info(string message)
{
log4net.ILog log = log4net.LogManager.GetLogger(DefaultName);
if (log.IsInfoEnabled)
{
log.Info(message);
}
log = null;
}
public static void warn(string message)
{
log4net.ILog log = log4net.LogManager.GetLogger(DefaultName);
if (log.IsWarnEnabled)
{
log.Warn(message);
}
log = null;
}
}
由于debug和err经常需要记录错误信息(运行时抛出的exception),所以针对这两个方法我分别多给出了一个带exception的重载,其他方法根据需要您可以自己重载。
好了,基础设施搭建好了,下面看一下怎么使用
注:此前的代码可以移植到winform使用,以后的代码依赖asp.net运行环境,只能在asp.net中使用,移植需稍作修改
测试:
建立一个测试文件,修改pageload为如下代码:
Code
protected void Page_Load(object sender, EventArgs e)
{
//简单测试
Log.debug("sss");
Log.error("ddeeeedd");
Log.info("fff");
Response.Write("ok,log already recorded");
//这个是用于测试对运行时错误的记录,参考下一例子
//int i = 0;
//int k = 1;
//Response.Write(k/i);
//Log.error(Page.Request.Url.ToString());
//Log.error(Page.Request.Url.ToString(),new Exception("user throw error!"));
}
protected void Page_Load(object sender, EventArgs e)
{
//简单测试
Log.debug("sss");
Log.error("ddeeeedd");
Log.info("fff");
Response.Write("ok,log already recorded");
//这个是用于测试对运行时错误的记录,参考下一例子
//int i = 0;
//int k = 1;
//Response.Write(k/i);
//Log.error(Page.Request.Url.ToString());
//Log.error(Page.Request.Url.ToString(),new Exception("user throw error!"));
}
应用举例:
在app_code里创建一个类,名为PageBase:
Code
/// <summary>
/// Summary description for PageBase
/// </summary>
public class PageBase : Page
{
protected override void OnError(EventArgs e)
{
Exception err = Server.GetLastError();
Log.error(Request.Url.ToString(), err);
}
}
/// <summary>
/// Summary description for PageBase
/// </summary>
public class PageBase : Page
{
protected override void OnError(EventArgs e)
{
Exception err = Server.GetLastError();
Log.error(Request.Url.ToString(), err);
}
}
以后项目中的web文件如果是从这个类继承,当发生运行时错误时就会被系统记录,有兴趣的话可以使用上例中被注释的部分测试。