系统位置 \wojilu\Log
一个日志系统,可以说简单,一个类就可以实现了,类里面也只需要大概10行代码就可以了。
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.定义日志消息等级:
一个日志,应该有多个等级,普通的信息,警告,错误。。。。先来一个枚举。
namespace wojilu.Log {
public enum LogLevel {
None,
Fatal,
Error,
Warn,
Info,
Debug,
All
}
当然,如果要做的足够复杂的话,我们还可以定义一个ILogLevel的接口,这样就可以自定义LogLevel了。例如ASP_Err,Game_Info等等。什么都可以自定义,才是王道阿。。。
2.每种LOG都要有自己的输出方式,OK,这里就要用上接口了。ILOG接口。。。
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信息,我们也要统一接口,继续增加接口
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,用了等于没有用,有点像抽象类,不过他的确是一个具体类。
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>
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插入日志:
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.不管怎么样,我们需要配置,日志也需要配置
我们要一个配置类
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类,不管要什么,都通过工厂或者助手要。但是,很多系统其实工厂只是生产一种东西,只不过参数不一样。
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,他可以帮我们处理一些不归任何类处理的功能,这里是最能发挥想象力的地方了。
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系统,缓存系统。。。。包罗万象,应有竟有。
重复发明的轮子,可以拼出一部车了。