系统位置 \wojilu\Log
一个日志系统,可以说简单,一个类就可以实现了,类里面也只需要大概10行代码就可以了。
using System; using System.Diagnostics; using System.Collections.Generic; using System.Web; using System.IO; /// <summary> /// Summary description for clsException /// </summary> public static class clsException{ public static void ExceptionDealer(String ex) { String LogFileName = UrlBase + @" \LOG\Error.log " ; StreamWriter Errlog = new StreamWriter(LogFileName, true ); Errlog.WriteLine( " Date-Time: " + DateTime.Now.ToString()); Errlog.WriteLine( " Exception: " + ex.ToString()); Errlog.Close(); Errlog = null ; }} 这样一个类,可以进行异常的日志了。不过,这个是懒人的日志类,下面看看做框架的同志是怎么设计日志类的。
1.定义日志消息等级:
一个日志,应该有多个等级,普通的信息,警告,错误。。。。先来一个枚举。
using System; namespace wojilu.Log { public enum LogLevel { None, Fatal, Error, Warn, Info, Debug, All } 当然,如果要做的足够复杂的话,我们还可以定义一个ILogLevel的接口,这样就可以自定义LogLevel了。例如ASP_Err,Game_Info等等。什么都可以自定义,才是王道阿。。。
2.每种LOG都要有自己的输出方式,OK,这里就要用上接口了。ILOG接口。。。
1 using System; 2 namespace wojilu { 3 4 /// <summary> 5 /// ÈÕÖ¾½Ó¿Ú 6 /// </summary> 7 public interface ILog { 8 9 void Debug( String message ); 10 void Info( String message ); 11 void Warn( String message ); 12 void Error( String message ); 13 void Fatal( String message ); 14 15 String TypeName { set ; } 16 } 17 18 } 不但输出需要统一接口,连Message信息,我们也要统一接口,继续增加接口
1 using System; 2 3 namespace wojilu.Log { 4 5 /// <summary> 6 /// ÈÕÖ¾ÐÅÏ¢½Ó¿Ú 7 /// </summary> 8 public interface ILogMsg { 9 10 String LogLevel { get ; set ; } 11 DateTime LogTime { get ; set ; } 12 String Message { get ; set ; } 13 String TypeName { get ; set ; } 14 } 15 16 } 3.有了接口,我们可以定义自己的Logger了,为了安全,我们可以定义一个空的Logger,虽然它什么都不做,但是我们还是想要定义它。企业级,就是要什么都想得到。下面这个Logger,用了等于没有用,有点像抽象类,不过他的确是一个具体类。
1 using System; 2 using wojilu; 3 4 namespace wojilu.Log { 5 6 /// <summary> 7 /// 使用 null 模式的日志工具 8 /// </summary> 9 internal class NullLogger : ILog { 10 11 public void Debug( String message ) { 12 } 13 14 public void Info( String message ) { 15 } 16 17 public void Warn( String message ) { 18 } 19 20 public void Error( String message ) { 21 } 22 23 public void Fatal( String message ) { 24 } 25 26 27 public String TypeName { 28 set { } 29 } 30 31 } 32 } 稍微正常一点的LOGGER,向文件系统写日志
/// <summary> /// 文件日志工具,所有日志会被写入磁盘 /// </summary> internal class FileLogger : ILog { private LogLevel _levelSetting; private LogMessage _msg; public FileLogger() { _levelSetting = LogConfig.Instance.Level; _msg = new LogMessage(); } public void Debug( String message ) { _msg.LogTime = DateTime.Now; _msg.Message = message; _msg.LogLevel = " debug " ; System.Diagnostics.Debug.Write( LoggerUtil.GetFormatMsg( _msg ) ); if (_levelSetting >= LogLevel.Debug) { LoggerUtil.WriteFile( _msg ); } }。。。。。。 public String TypeName { set { _msg.TypeName = value; } } 当然,还可以向DB插入日志:
1 /// <summary> 2 /// 存储到数据库的日志(尚未实现,请勿使用) 3 /// </summary> 4 internal class LoggerForDB : ILog { 5 6 private LogLevel _levelSetting; 7 private LogMsg _msg; 8 9 public LoggerForDB() { 10 _levelSetting = LogConfig.Instance.Level; 11 _msg = new LogMsg(); 12 } 当然,如果可以的话,你还可以向你们家的电视机输入TVLogger。,或者是向打印机出LOG,PrinterLogger
4.不管怎么样,我们需要配置,日志也需要配置
我们要一个配置类
1 /// <summary> 2 /// 日志配置文件,默认配置文件在 /framework/config/log.config,日志文件在 /framework/log/log.txt 中 3 /// </summary> 4 public class LogConfig { 5 6 /// <summary> 7 /// 日志配置信息(全局缓存) 8 /// <remarks> 9 /// logLevel 的值(不区分大小写):none, debug, info, warn, error, fatal, all; 10 /// logFile 和 logProvider 通常不用填写 11 /// </remarks> 12 /// <example> 13 /// 配置文件的格式(一行一条配置,键值之间用冒号分开)。 14 /// <code> 15 /// logLevel : info 16 /// logFile : log/log.txt 17 /// logProvider : wojilu.Log.FileLogger 18 /// </code> 19 /// </example> 20 /// </summary> 21 public static readonly LogConfig Instance = new LogConfig(); 22 23 private LogConfig() { 24 25 String absPath = getConfigAbsPath(); 26 27 if (strUtil.IsNullOrEmpty( absPath )) { 28 loadDefault(); 29 return ; 30 } 5.作为企业级的程序员,我们还需要管理者,不管怎么样,你要用日志系统,你必须要向管理者申请,不申请不能使用。现在都很流行factory,或者Assistent类,不管要什么,都通过工厂或者助手要。但是,很多系统其实工厂只是生产一种东西,只不过参数不一样。
1 /// <summary> 2 /// 日志管理对象,通常用于获取日志工具 3 /// </summary> 4 /// <example> 5 /// 一般在类的第一行定义 6 /// <code> 7 /// private static readonly ILog logger = LogManager.GetLogger( typeof( ObjectBase ) ); 8 /// </code> 9 /// 然后可以在其他方法中使用 10 /// <code> 11 /// logger.Info( "your message" ); 12 /// </code> 13 /// </example> 14 public class LogManager { 15 16 private LogManager() { 17 } 18 19 /// <summary> 20 /// 获取一个日志工具 21 /// </summary> 22 /// <param name="type"> 对象类型 </param> 23 /// <returns> 返回日志工具 </returns> 24 public static ILog GetLogger( Type type ) { 25 return GetLogger( type.FullName ); 26 } 27 28 /// <summary> 29 /// 获取一个日志工具 30 /// </summary> 31 /// <param name="typeName"> 对象类型 </param> 32 /// <returns> 返回日志工具 </returns> 33 public static ILog GetLogger( String typeName ) { 34 ILog log = getLogger(); 35 log.TypeName = typeName; 36 return log; 37 } 6.我们还要Until,他可以帮我们处理一些不归任何类处理的功能,这里是最能发挥想象力的地方了。
1 /// <summary> 2 /// 日志处理工具 3 /// </summary> 4 public class LoggerUtil { 5 6 private static Object objLock = new object (); 7 8 /// <summary> 9 /// sql 日志的前缀 10 /// </summary> 11 public static readonly String SqlPrefix = " sql= " ; 12 13 /// <summary> 14 /// 在 web 系统中,记录 sql 执行的次数 15 /// </summary> 16 public static void LogSqlCount() { 17 18 if (CurrentRequest.getItem( " sqlcount " ) == null ) { 19 CurrentRequest.setItem( " sqlcount " , 1 ); 20 } 21 else { 22 CurrentRequest.setItem( " sqlcount " , (( int )CurrentRequest.getItem( " sqlcount " )) + 1 ); 23 } 这个就是企业级的日志系统。不管怎么样,麻雀虽小,五脏俱全。该有的都要有,即使只是做日志也要成规模。
如果你感兴趣的话,wojilu的ORM系统也可以单独使用啊。。。。。还有IOC系统,缓存系统。。。。包罗万象,应有竟有。
重复发明的轮子,可以拼出一部车了。