Common.Logging是一个通用日志接口,具体实现可采用log4net、EntLib的日志、NLog等。
Common.Logging.ILoggerFactoryAdapter接口
public interface ILoggerFactoryAdapter
{
ILog GetLogger(string name);
ILog GetLogger(Type type);
}
Common.Logging.ILog接口
public interface ILog
{
bool IsDebugEnabled { get; }
bool IsErrorEnabled { get; }
bool IsFatalEnabled { get; }
bool IsInfoEnabled { get; }
bool IsTraceEnabled { get; }
bool IsWarnEnabled { get; }
void Debug(object message);
void Debug(object message, Exception exception);
void Error(object message);
void Error(object message, Exception exception);
void Fatal(object message);
void Fatal(object message, Exception exception);
void Info(object message);
void Info(object message, Exception exception);
void Trace(object message);
void Trace(object message, Exception exception);
void Warn(object message);
void Warn(object message, Exception exception);
}
log4net是一个第三方开源组件,它设计的主要目的是组合,生成日志信息,同时将配置保存到各种存储介质或者展现平台中,在实际项目中,Log4net 可以保存系统运行情况,可以在系统出现异常时,根据保存的日志信息,查看当时系统的状态。
log4net是Log4j的.NET版本,用C#编写,它与Log4j一样,具有可配置性灵活、线程安全、对日志的级别管理方便等优点。
几乎所有的大型应用都会有自己的用于跟踪调试的API。因为一旦程序被部署以后,就不太可能再利用专门的调试工具了。然而一个管理员可能需要有一套强大的日志系统来诊断和修复配置上的问题。
经验表明,日志记录往往是软件开发周期中的重要组成部分。它具有以下几个优点:它可以提供应用程序运行时的精确环境,可供开发人员尽快找到应用程序中的Bug;一旦在程序中加入了Log 输出代码,程序运行过程中就能生成并输出日志信息而无需人工干预。另外,日志信息可以输出到不同的地方(控制台,文件等)以备以后研究之用。
Log4net就是为这样一个目的设计的,用于.NET开发环境的日志记录包。
log4net 有四种主要的组件,分别是Logger(记录器), Repository(库), Appender(附着器)以及 Layout(布局).
Common.Logging、log4net通常使用xml进行配置,在MVCQuick中使用编程方式进行配置。
实现代码
using System;s
namespace MVCQuick.Framework.Logging
{
///<summary>
/// The 7 possible logging levels
///</summary>
///<author>Gilles Bayon</author>
public enum LogLevel
{
///<summary>
/// All logging levels
///</summary>
All = 0,
///<summary>
/// A trace logging level
///</summary>
Trace = 1,
///<summary>
/// A debug logging level
///</summary>
Debug = 2,
///<summary>
/// A info logging level
///</summary>
Info = 3,
///<summary>
/// A warn logging level
///</summary>
Warn = 4,
///<summary>
/// An error logging level
///</summary>
Error = 5,
///<summary>
/// A fatal logging level
///</summary>
Fatal = 6,
///<summary>
/// Do not log anything.
///</summary>
Off = 7,
}
}
using System;
namespace MVCQuick.Framework.Logging
{
public class Log4NetLogger : Common.Logging.ILog
{
private log4net.Core.ILogger _logger = null;
private static readonly Type declaringType = typeof(Log4NetLogger);
public bool IsInfoEnabled
{
get
{
return this._logger.IsEnabledFor(log4net.Core.Level.Info);
}
}
public bool IsWarnEnabled
{
get
{
return this._logger.IsEnabledFor(log4net.Core.Level.Warn);
}
}
public bool IsErrorEnabled
{
get
{
return this._logger.IsEnabledFor(log4net.Core.Level.Error);
}
}
public bool IsFatalEnabled
{
get
{
return this._logger.IsEnabledFor(log4net.Core.Level.Fatal);
}
}
public bool IsDebugEnabled
{
get
{
return this._logger.IsEnabledFor(log4net.Core.Level.Debug);
}
}
public bool IsTraceEnabled
{
get
{
return this._logger.IsEnabledFor(log4net.Core.Level.Trace);
}
}
internal Log4NetLogger(log4net.ILog log)
{
this._logger = log.Logger;
}
public void Info(object message, Exception e)
{
this._logger.Log(Log4NetLogger.declaringType, log4net.Core.Level.Info, message, e);
}
public void Info(object message)
{
this._logger.Log(Log4NetLogger.declaringType, log4net.Core.Level.Info, message, null);
}
public void Debug(object message, Exception e)
{
this._logger.Log(Log4NetLogger.declaringType, log4net.Core.Level.Debug, message, e);
}
public void Debug(object message)
{
this._logger.Log(Log4NetLogger.declaringType, log4net.Core.Level.Debug, message, null);
}
public void Warn(object message, Exception e)
{
this._logger.Log(Log4NetLogger.declaringType, log4net.Core.Level.Warn, message, e);
}
public void Warn(object message)
{
this._logger.Log(Log4NetLogger.declaringType, log4net.Core.Level.Warn, message, null);
}
public void Trace(object message, Exception e)
{
this._logger.Log(Log4NetLogger.declaringType, log4net.Core.Level.Trace, message, e);
}
public void Trace(object message)
{
this._logger.Log(Log4NetLogger.declaringType, log4net.Core.Level.Trace, message, null);
}
public void Fatal(object message, Exception e)
{
this._logger.Log(Log4NetLogger.declaringType, log4net.Core.Level.Fatal, message, e);
}
public void Fatal(object message)
{
this._logger.Log(Log4NetLogger.declaringType, log4net.Core.Level.Fatal, message, null);
}
public void Error(object message, Exception e)
{
this._logger.Log(Log4NetLogger.declaringType, log4net.Core.Level.Error, message, e);
}
public void Error(object message)
{
this._logger.Log(Log4NetLogger.declaringType, log4net.Core.Level.Error, message, null);
}
}
}
using System;
namespace MVCQuick.Framework.Logging
{
public class Log4NetLoggerFactoryAdapter : Common.Logging.ILoggerFactoryAdapter
{
public Log4NetLoggerFactoryAdapter()
{
}
public Common.Logging.ILog GetLogger(string name)
{
return new Log4NetLogger(log4net.LogManager.GetLogger(name));
}
public Common.Logging.ILog GetLogger(Type type)
{
return new Log4NetLogger(log4net.LogManager.GetLogger(type));
}
}
}
using System;
namespace MVCQuick.Framework.Logging
{
public class Logger
{
private Common.Logging.ILog log;
public Logger()
{
}
public static void ConfigureConsoleOut()
{
Common.Logging.LogManager.Adapter =
new Common.Logging.Simple.ConsoleOutLoggerFactoryAdapter();
}
public static void ConfigureTrace()
{
Common.Logging.LogManager.Adapter =
new Common.Logging.Simple.TraceLoggerFactoryAdapter();
}
public static void ConfigureLog4Net(string filelogPath,
LogLevel displayLogLevel, LogLevel saveLogLevel)
{
log4net.Repository.Hierarchy.Logger root =
((log4net.Repository.Hierarchy.Hierarchy)log4net.LogManager.GetRepository()).Root;
root.AddAppender(GetConsoleAppender(GetLog4NetLevel(displayLogLevel)));
root.AddAppender(GetTraceAppender(GetLog4NetLevel(displayLogLevel)));
root.AddAppender(GetSiteFileAppender(filelogPath, GetLog4NetLevel(saveLogLevel)));
root.Repository.Configured = true;
log4net.Repository.Hierarchy.Logger nhibernate =
(log4net.Repository.Hierarchy.Logger)log4net.LogManager.GetLogger("NHibernate").Logger;
nhibernate.AddAppender(GetNHibernateFileAppender(filelogPath, GetLog4NetLevel(saveLogLevel)));
nhibernate.Additivity = false;
nhibernate.Repository.Configured = true;
log4net.Repository.Hierarchy.Logger spring =
(log4net.Repository.Hierarchy.Logger)log4net.LogManager.GetLogger("Spring").Logger;
spring.AddAppender(GetSpringFileAppender(filelogPath, GetLog4NetLevel(saveLogLevel)));
spring.Additivity = false;
spring.Repository.Configured = true;
Common.Logging.LogManager.Adapter = new Log4NetLoggerFactoryAdapter();
}
public static Logger GetLogger(string name)
{
Logger logger = new Logger();
logger.log = Common.Logging.LogManager.GetLogger(name);
return logger;
}
public static Logger GetLogger(Type type)
{
Logger logger = new Logger();
logger.log = Common.Logging.LogManager.GetLogger(type);
return logger;
}
public void Debug(object message)
{
log.Debug(message);
}
public void Debug(object message, Exception exception)
{
log.Debug(message, exception);
}
public void Error(object message)
{
log.Error(message);
}
public void Error(object message, Exception exception)
{
log.Error(message, exception);
}
public void Fatal(object message)
{
log.Fatal(message);
}
public void Fatal(object message, Exception exception)
{
log.Fatal(message, exception);
}
public void Info(object message)
{
log.Info(message);
}
public void Info(object message, Exception exception)
{
log.Info(message, exception);
}
public void Warn(object message)
{
log.Warn(message);
}
public void Warn(object message, Exception exception)
{
log.Warn(message, exception);
}
#region log4net
private static log4net.Appender.ConsoleAppender GetConsoleAppender(
log4net.Core.Level consoleLogLevel)
{
log4net.Appender.ConsoleAppender appender = new log4net.Appender.ConsoleAppender();
appender.Name = "Console";
appender.Layout = new log4net.Layout.PatternLayout(
"%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c - %m%n");
appender.Threshold = consoleLogLevel;
appender.ActivateOptions();
return appender;
}
private static log4net.Appender.TraceAppender GetTraceAppender(
log4net.Core.Level traceLogLevel)
{
log4net.Appender.TraceAppender appender = new log4net.Appender.TraceAppender();
appender.Name = "Trace";
appender.Layout = new log4net.Layout.PatternLayout(
"%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c - %m%n");
appender.Threshold = traceLogLevel;
appender.ActivateOptions();
return appender;
}
private static log4net.Appender.FileAppender GetSiteFileAppender(
string filelogPath, log4net.Core.Level fileLogLevel)
{
log4net.Appender.RollingFileAppender appender = new log4net.Appender.RollingFileAppender();
appender.Name = "SiteLog";
appender.AppendToFile = true;
appender.File = filelogPath + "\\Site.log";
appender.RollingStyle = log4net.Appender.RollingFileAppender.RollingMode.Size;
appender.MaxSizeRollBackups = 10;
appender.MaximumFileSize = "10MB";
appender.StaticLogFileName = true;
appender.Layout = new log4net.Layout.PatternLayout(
"%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c - %m%n");
appender.Threshold = fileLogLevel;
appender.ActivateOptions();
return appender;
}
private static log4net.Appender.FileAppender GetNHibernateFileAppender(
string filelogPath, log4net.Core.Level fileLogLevel)
{
log4net.Appender.RollingFileAppender appender = new log4net.Appender.RollingFileAppender();
appender.Name = "NHibernateLog";
appender.AppendToFile = true;
appender.File = filelogPath + "\\NHibernate.log";
appender.RollingStyle = log4net.Appender.RollingFileAppender.RollingMode.Size;
appender.MaxSizeRollBackups = 10;
appender.MaximumFileSize = "10MB";
appender.StaticLogFileName = true;
appender.Layout = new log4net.Layout.PatternLayout(
"%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c - %m%n");
appender.Threshold = fileLogLevel;
appender.ActivateOptions();
return appender;
}
private static log4net.Appender.FileAppender GetSpringFileAppender(
string filelogPath, log4net.Core.Level fileLogLevel)
{
log4net.Appender.RollingFileAppender appender = new log4net.Appender.RollingFileAppender();
appender.Name = "SpringLog";
appender.AppendToFile = true;
appender.File = filelogPath + "\\Spring.log";
appender.RollingStyle = log4net.Appender.RollingFileAppender.RollingMode.Size;
appender.MaxSizeRollBackups = 10;
appender.MaximumFileSize = "10MB";
appender.StaticLogFileName = true;
appender.Layout = new log4net.Layout.PatternLayout(
"%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c - %m%n");
appender.Threshold = fileLogLevel;
appender.ActivateOptions();
return appender;
}
private static log4net.Core.Level GetLog4NetLevel(LogLevel logLevel)
{
switch (logLevel)
{
case LogLevel.All:
return log4net.Core.Level.All;
case LogLevel.Trace:
return log4net.Core.Level.Trace;
case LogLevel.Debug:
return log4net.Core.Level.Debug;
case LogLevel.Info:
return log4net.Core.Level.Info;
case LogLevel.Warn:
return log4net.Core.Level.Warn;
case LogLevel.Error:
return log4net.Core.Level.Error;
case LogLevel.Fatal:
return log4net.Core.Level.Fatal;
default:
throw new ArgumentOutOfRangeException("logLevel", logLevel, "unknown log level");
}
#endregion log4net
}
}
}
单元测试代码
using System;
using NUnit.Framework;
using MVCQuick.Framework.Logging;
namespace MVCQuick.Framework.Tests
{
[TestFixture]
public class LoggingTests
{
[Test]
public void LoggerTest()
{
Logger.ConfigureLog4Net("C:", LogLevel.Debug, LogLevel.Warn);
Logger logger = Logger.GetLogger(typeof(LoggingTests));
logger.Debug("Debug");
logger.Error("Error");
logger.Fatal("Fatal");
logger.Info("Info");
logger.Warn("warn");
}
}
}
测试结果