分享
 
 
 

Windows平台下程序日志的设计和实现(下:代码)

王朝system·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

1、CConfiguration.cs

using System;

using System.Collections.Specialized;

using System.Xml;

using System.Configuration;

namespace com.lenovo.zhangyuk.logger

{

/// <summary>

/// CConfiguration 的摘要说明。

/// </summary>

public class CConfiguration

{

// 程序全局配置(配置文件相应内容在内存中的映射)

private static NameValueCollection _configration = new NameValueCollection();

private CConfiguration()

{

}

/// <summary>

/// 取配置项

/// </summary>

/// <param name="key"></param>

/// <returns></returns>

public static string getConfiguration( string key )

{

// 如果第一次取配置项,那么将所有配置项从文件读入内存,否则从内存中取出。

if( _configration.Count==0 )

{

_configration = ConfigurationSettings.AppSettings;

}

return (null != _configration[key]) ? _configration[key].ToString().Trim() : "";

}

}

}

2、ILogger.cs

using System;

using System.Diagnostics;

namespace com.lenovo.zhangyuk.logger

{

/// <summary>

/// 日志输出级别

/// </summary>

public enum enumLevel

{

DEBUG,

INFO,

WARN,

ERROR,

FATAL

}

/// <summary>

/// 日志内容,参考 myLogEntryWrittenArgs

/// </summary>

public class myEventLogEntry

{

/// <summary>

/// 日志源,用以记载日志的来源

/// </summary>

public string Source = "";

/// <summary>

/// 日志内容

/// </summary>

public string Message = "";

/// <summary>

/// 写入日志的时间

/// </summary>

public DateTime TimeWritten = DateTime.Now;

/// <summary>

/// 日志的类型,可以参考 EventLogEntryType 的定义

/// </summary>

public enumLevel Type = enumLevel.INFO;

}

/// <summary>

/// 日志外部处理函数的参数

/// </summary>

public class myLogEntryWrittenArgs : EventArgs

{

public myLogEntryWrittenArgs()

{

Entry = new myEventLogEntry();

}

public myEventLogEntry Entry;

}

/// <summary>

/// 日志外部的处理入口函数声明

/// </summary>

public delegate void myLogEntryWrittenHandler( object sender, myLogEntryWrittenArgs e );

/// <summary>

///

/// 根据日志输出级别写日志

///

/// 特性:

///

/// 1、可以根据日志输出级别写日志

///

/// 日志的输出级别:DEBUG < INFO < WARN < ERROR < FATAL

///

/// 例如,日志级别是 INFO,则调用 debug() 不会输出,调用其他方法会输出;

/// 日志级别是 WARN,则调用 debug() 和 info() 不会输出,调用其他方法会输出。

///

/// 2、写日志时调用外部处理入口

///

/// 可以添加外部处理入口函数(声明见 myLogEntryWrittenHandler ),在写日志时,程序

/// 依次调用外部处理入口函数,调用着可以在外部处理入口函数中得到日志的相关信息。

/// 这里使用了观察者模式。

///

/// 例如:

/// private static ILogger logger = CLoggerFactory.getLogger();

/// public void logEntryWritten(object sender, myLogEntryWrittenArgs e)

/// {

/// //......

/// }

/// logger.addEntryWrittenHander( new myLogEntryWrittenHandler(this.logEntryWritten) );

///

/// 那么在写日志的时候,logEntryWritten()会被调用。

///

/// </summary>

public interface ILogger

{

// 写日志

void debug( string message, string source );

void info ( string message, string source );

void warn ( string message, string source );

void error( string message, string source );

void fatal( string message, string source );

// 设置和返回日志输出级别

void setLevel(enumLevel level);

enumLevel getLevel();

// 管理外部程序处理入口

void addEntryWrittenHander( Delegate handler );

void clearEntryWrittenHander();

void enableEntryWrittenHander( bool enabled );

}

}

3、CLoggerAbstract.cs

using System;

using System.IO;

using System.Diagnostics;

using System.Collections;

namespace com.lenovo.zhangyuk.logger

{

/// <summary>

/// 日志处理的抽象类

///

/// 这里使用了基于继承的模板模式

/// 在CLoggerAbstract中实现了向各种日志源输出的通用操作

/// 向具体日志源输出的动作则通过虚函数_writeLog在子类实现

/// </summary>

abstract class CLoggerAbstract : ILogger

{

// 写日志时触发外部方法的HANDLE

private static ArrayList _entryWrittenEventHandler = new ArrayList();

// 写日志时是否触发外部方法

private static bool _bEnableEntryWritten = true;

// 日志输出级别,默认是 INFO

private static enumLevel _outputLevel = enumLevel.INFO;

// 抽象函数,具体的写日志操作由子类实现

public abstract void _writeLog(string message, string source, enumLevel type);

/// <summary>

/// 构造函数

/// </summary>

/// <param name="strEventSource"></param>

/// <param name="strEventLog"></param>

public CLoggerAbstract( enumLevel level )

{

_outputLevel = level;

}

/// <summary>

/// 设置日志输出级别

/// </summary>

/// <param name="level">级别</param>

public void setLevel(enumLevel level)

{

_outputLevel = level;

}

/// <summary>

/// 获得日志输出级别

/// </summary>

/// <returns>级别</returns>

public enumLevel getLevel()

{

return _outputLevel;

}

/// <summary>

/// 写调试信息

/// </summary>

/// <param name="message"></param>

public void debug( string message, string source )

{

if( _outputLevel <= enumLevel.DEBUG )

write( message, source, enumLevel.DEBUG );

}

/// <summary>

/// 写一般信息

/// </summary>

/// <param name="message"></param>

public void info( string message, string source )

{

if( _outputLevel <= enumLevel.INFO )

write( message, source, enumLevel.INFO );

}

/// <summary>

/// 写警告信息

/// </summary>

/// <param name="message"></param>

public void warn( string message, string source )

{

if( _outputLevel <= enumLevel.WARN )

write( message, source, enumLevel.WARN );

}

/// <summary>

/// 写错误信息

/// </summary>

/// <param name="message"></param>

public void error( string message, string source )

{

if( _outputLevel <= enumLevel.ERROR )

write( message, source, enumLevel.ERROR );

}

/// <summary>

/// 写严重错误信息

/// </summary>

/// <param name="message"></param>

public void fatal( string message, string source )

{

if( _outputLevel <= enumLevel.FATAL )

write( message, source, enumLevel.FATAL );

}

/// <summary>

/// 设置写日志时触发的外部方法

/// </summary>

/// <param name="handler">外部方法HANDLE</param>

public void addEntryWrittenHander( Delegate handler )

{

try

{

if( !_entryWrittenEventHandler.Contains(handler) )

_entryWrittenEventHandler.Add( handler );

}

catch( Exception ex )

{

this.warn("add entry written hander error:"+ex.Message, this.ToString());

}

}

/// <summary>

/// 清除写日志时触发的外部方法

/// </summary>

public void clearEntryWrittenHander()

{

try

{

_entryWrittenEventHandler.Clear();

}

catch( Exception ex )

{

this.warn("clear entry written hander error:"+ex.Message, this.ToString());

}

}

/// <summary>

/// 设置是否在写日志时触发的外部方法,默认为TRUE。

/// </summary>

/// <param name="enabled">是否</param>

public void enableEntryWrittenHander( bool enabled )

{

_bEnableEntryWritten = enabled;

}

/// <summary>

/// 将控制转给外部处理方法

/// </summary>

/// <param name="source"></param>

/// <param name="e"></param>

private void OnEntryWritten( string message, string source, enumLevel type)//object source, EntryWrittenEventArgs e)

{

if( _entryWrittenEventHandler.Count >0 )

{

myLogEntryWrittenArgs args = new myLogEntryWrittenArgs();

args.Entry.TimeWritten = DateTime.Now;

args.Entry.Message = message;

args.Entry.Type = type;

args.Entry.Source = source;

foreach( myLogEntryWrittenHandler aHandler in _entryWrittenEventHandler )

{

aHandler( this, args );

}

}

}

/// <summary>

/// 写事件日志

/// </summary>

/// <param name="strMessage">事件内容</param>

/// <param name="eventType">事件类别,错误、警告或者消息</param>

private void write( string message, string source, enumLevel type )

{

try

{

_writeLog( message, source, type );

OnEntryWritten( message, source, type );

}

catch( Exception ex )

{

Trace.WriteLine("Write logger error:" + ex.Message);

}

}

}

}

4、CLoggerDatabase.cs

using System;

using System.IO;

using System.Diagnostics;

using System.Data;

using System.Data.OleDb;

namespace com.lenovo.zhangyuk.logger

{

/// <summary>

/// 向数据库写日志

/// </summary>

class CLoggerDatabase : CLoggerAbstract

{

// 数据库连接

private static OleDbConnection _connection = null;

// 向数据库写日志的带参数的SQL串,通常是一条带参数的INSERT语句

private static string _updateStr = "";

/// <summary>

/// 构造函数

/// </summary>

/// <param name="strUpdate">向数据库写日志的带参数的SQL串,通常是一条带参数的INSERT语句</param>

/// <param name="level">日志输出的级别</param>

public CLoggerDatabase( string strUpdate, enumLevel level ) : base(level)

{

if( null == _connection )

{

_connection = new OleDbConnection(CConfiguration.getConfiguration("database.connectionString"));

}

Trace.WriteLineIf( ( strUpdate.Length <=0 ), "error : update string is empty !" );

_updateStr = strUpdate;

}

/// <summary>

/// 向数据库写日志

/// override抽象类的相应函数

/// </summary>

/// <param name="message">日志内容</param>

/// <param name="source">日志源</param>

/// <param name="type">日志级别</param>

public override void _writeLog(string message, string source, enumLevel type)

{

try

{

OleDbCommand command = new OleDbCommand();

command.Connection = _connection;

command.CommandText = string.Format(_updateStr,

DateTime.Now.ToLocalTime(),

message,

source,

type.ToString());

command.CommandType = CommandType.Text;

_connection.Open();

command.ExecuteNonQuery();

_connection.Close();

}

catch( Exception ex )

{

_connection.Close();

throw ex;

}

}

}

}

5、CLoggerFile.cs

using System;

using System.IO;

using System.Diagnostics;

namespace com.lenovo.zhangyuk.logger

{

/// <summary>

/// 向文件写日志

/// </summary>

class CLoggerFile : CLoggerAbstract

{

// 文件句柄

private static Stream _fileStream = null;

/// <summary>

/// 构造函数

/// </summary>

/// <param name="strFileName">日志文件名</param>

/// <param name="level">日志输出的级别</param>

public CLoggerFile( string strFileName, enumLevel level ) : base(level)

{

Trace.WriteLineIf( ( strFileName.Length <=0 ), "error : logger file name is empty !" );

if( null == _fileStream )

{

_fileStream = new FileStream(strFileName, FileMode.OpenOrCreate, FileAccess.Write );

}

}

/// <summary>

/// 向文件写日志

/// override抽象类的相应函数

/// </summary>

/// <param name="message">日志内容</param>

/// <param name="source">日志源</param>

/// <param name="type">日志级别</param>

public override void _writeLog(string message, string source, enumLevel type)

{

try

{

_fileStream.Seek(0,SeekOrigin.End);

StreamWriter sw = new StreamWriter(_fileStream);

sw.WriteLine( DateTime.Now.ToString() + " " + type.ToString() + " " + source + " " + message);

sw.Flush();

}

catch( Exception ex )

{

throw ex;

}

}

}

}

6、CLoggerEvent.cs

using System;

using System.Diagnostics;

namespace com.lenovo.zhangyuk.logger

{

/// <summary>

/// 向系统写入日志

/// </summary>

class CLoggerEvent : CLoggerAbstract

{

// 事件日志

private static EventLog _eventLog = new EventLog();

// 事件日志名

private static string _eventName = "com.lenovo.zhangyu";

/// <summary>

/// 构造函数

/// </summary>

/// <param name="strEventName">事件日志名</param>

/// <param name="level">日志输出的级别</param>

public CLoggerEvent( string strEventName, enumLevel level ) : base(level)

{

_eventName = strEventName;

_eventLog.Log = _eventName;

_eventLog.EnableRaisingEvents = false;

}

/// <summary>

/// 向系统写入日志

/// override抽象类的相应函数

/// </summary>

/// <param name="message">日志内容</param>

/// <param name="source">日志源</param>

/// <param name="type">日志级别</param>

public override void _writeLog(string message, string source, enumLevel type)

{

try

{

if (!EventLog.SourceExists( source ))

{

EventLog.CreateEventSource( source,_eventName );

}

_eventLog.Source = source;

_eventLog.WriteEntry( message, myType2EventType( type ) );

}

catch( Exception ex )

{

throw ex;

}

}

/// <summary>

/// 将自定义的日志级别转换为系统约定的日志级别

/// DEBUG INFO --> Information

/// ERROR FATAL --> Error

/// WARN --> Warning

/// </summary>

/// <param name="type">自定义的日志级别</param>

/// <returns>系统约定的日志级别</returns>

private EventLogEntryType myType2EventType( enumLevel type )

{

EventLogEntryType eventType = EventLogEntryType.Information;

if( type == enumLevel.DEBUG || type == enumLevel.INFO )

eventType = EventLogEntryType.Information;

else if( type == enumLevel.ERROR || type == enumLevel.FATAL )

eventType = EventLogEntryType.Error;

else if( type == enumLevel.WARN )

eventType = EventLogEntryType.Warning;

return eventType;

}

}

}

7、CLoggerFactory.cs

using System;

using System.Collections;

using System.Reflection;

namespace com.lenovo.zhangyuk.logger

{

/// <summary>

/// CLoggerFactory 的摘要说明。

/// </summary>

public class CLoggerFactory

{

private CLoggerFactory()

{

}

/// <summary>

/// 根据配置文件中的设置创建日志类

/// </summary>

/// <returns></returns>

public static ILogger getLogger()

{

// 日志类型

string logger = CConfiguration.getConfiguration("logger.type");

// 日志名或日志文件名

string loggerName = CConfiguration.getConfiguration("logger.name");

// 日志级别

enumLevel level = str2enum( CConfiguration.getConfiguration("logger.level") );

// 创建日志类

if( logger.ToLower().Equals("file") ) // 文件日志

{

return new CLoggerFile( loggerName, level );

}

else if( logger.ToLower().Equals("database") ) // 数据库日志

{

return new CLoggerDatabase( loggerName, level );

}

else// if( logger.ToLower().Equals("system") ) // 缺省使用系统日志

{

return new CLoggerEvent( loggerName, level );

}

}

/// <summary>

/// 将string类型的日志输出级别转换成程序可识别的enum型

/// </summary>

/// <param name="strLevel">string类型的日志输出级别</param>

/// <returns>enumLevel类型的日志输出级别</returns>

private static enumLevel str2enum( string strLevel )

{

enumLevel level = 0;

if( strLevel.ToLower().Equals("debug") )

level = enumLevel.DEBUG;

else if( strLevel.ToLower().Equals("info") )

level = enumLevel.INFO;

else if( strLevel.ToLower().Equals("warn") )

level = enumLevel.WARN;

else if( strLevel.ToLower().Equals("error") )

level = enumLevel.ERROR;

else if( strLevel.ToLower().Equals("fatal") )

level = enumLevel.FATAL;

else

level = enumLevel.INFO;

return level;

}

}

}

8、

<?xml version="1.0" encoding="gb2312"?>

<configuration>

<appSettings>

<add key="database.connectionString" value="Provider=OraOLEDB.Oracle.1;Password=zy;User ID=zy;Data Source=mytest" />

<add key="logger.type" value="file" />

<add key="logger.level" value="debug" />

<add key="logger.name" value="c:\\mylog.txt"/>

</appSettings>

</configuration>

作者简介:张昱(e-zhangyu@vip.sina.com

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有