JefferyZhou

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

 

在游戏的开发周期中,不管是前台还是后台,系统一般会采用一个持久化的日志系统来记录运行情况。
而在产品发布的时候,前台大都会把日志系统关掉或者采用加密的日志的记录高级别的运行信息(一些运行异常等)。
开启日志后,就需要考虑一个维护策略,比如多久删除一次,何时写入文件,日志文件限制多大,怎么分割等。
综合考虑如下几点:  
 1。必须尽可能的快,不影响性能
 2。必须限制大小
 3。必须是线程安全的
 4。必须能够具备加解密接口
 5。必须能够分模块记录日志
 6。必须动态可调日志级别
 
考虑到上面的各种需求,设计一个按线程和模块独立记录,位于内存的循环日志.
日志系统,最终的记录员是模块,所以执行记录操作的泪是------- 模块日志buff,
定位到当前线程的相应模块,需要一个管理者,这个管理者是----- 线程日志buff,
定位到当前需要调用的线程buffer,当然是日志系统了----------- 内存日志系统IMemLogSys
需求当中的 1. 2.  由 模块日志buff(IModuleBuffer)完成
需求当中的 3. 4. 6.  由 内存日志系统(IMemLogSys)完成
需求当中的 5.  由 线程日志buff(IThreadBuffer)完成
所以把需求分解后,后面需求的变更都是由相应的类来负责,做到职责单一。
(上面为了限制大小,其实需要定义一个预设值,最大线程数,最大模块数)
上面的分析,大概是系统接口设计如下:

在游戏的开发周期中,不管是前台还是后台,系统一般会采用一个持久化的日志系统来记录运行情况。而在产品发布的时候,前台大都会把日志系统关掉或者采用加密的日志的记录高级别的运行信息(一些运行异常等)。开启日志后,就需要考虑一个维护策略,比如多久删除一次,何时写入文件,日志文件限制多大,怎么分割等。

综合考虑如下几点:  

 1。必须尽可能的快,不影响性能

 2。必须限制大小

 3。必须是线程安全的

 4。必须能够具备加解密接口

 5。必须能够分模块记录日志

 6。必须动态可调日志级别 考虑到上面的各种需求,

 

设计一个按线程和模块独立记录,位于内存的循环日志.
日志系统,最终的记录员是模块,所以

执行记录操作的泪是------- 模块日志buff,

定位到当前线程的相应模块,需要一个管理者,

这个管理者是----- 线程日志buff,

定位到当前需要调用的线程buffer,

当然是日志系统了----------- 内存日志系统IMemLogSys


需求当中的 1. 2.  由 模块日志buff(IModuleBuffer)完成

需求当中的 3. 4. 6.  由 内存日志系统(IMemLogSys)完成

需求当中的 5.  由 线程日志buff(IThreadBuffer)完成


所以把需求分解后,后面需求的变更都是由相应的类来负责,做到职责单一。
(上面为了限制大小,其实需要定义一个预设值,最大线程数,最大模块数)
上面的分析,大概是系统接口设计如下:

 

 

//模块buffer
class IModuleBuffer
{
public:
	virtual WriteLog( const TCHAR* pszFormat, ...);									//写日志
	virtual const TCHAR* GetMemLog()const;											//获取当前模块的日志信息
	virtual const TCHAR* GetModuleName()const;
};

//线程buffer, 用来管理线程中的 模块Buffer
template<int nMaxModuleNum>
class IThreadBuffer
{
public:
	static const unsinged int m_snMaxModuleNum = nMaxModuleNum;
	typedef unsigned int ThreadID;
	
	IModuleBuffer* FindModuleBuffer(const TCHAR* pszModuleName)const;
	IModuleBuffer* AllocBuffer(const TCHAR* pszModuleName);
	
	bool	FreeBuffer(const IModuleBuffer* pModuleBuffer);
	
	ThreadID GetThreadID()const;
};

//封装一下系统相关的线程操作接口
class IOSInterfaceImp
{
	typedef unsigned int ProcessID;
	typedef unsigned int ThreadID;
	
	virtual ProcessID 	GetMainProcessID()const;
	virtual ThreadID 	GetMainThreadID()const;
	virtual ThreadID 	GetCurrentTreadID()const;
}

//内存日志系统的接口类,
//用来管理线程buffer, 
//并提供外部访问接口
//管理加解密
template<int nMaxThreadNum>
class IMemLogSys
{
public:
	static const unsigned int m_snMaxThreadNum = nMaxThreadNum;
#define p_in_ 					//输入
#define p_out_					//输出
#define p_in_out_				//输入 && 输出

	typedef enum E_IMEMLOGSYS_LEVEL{ E_IMEMLOGSYS_NORMAL, E_IMEMLOGSYS_WARING, E_IMEMLOGSYS_ERROR}E_IMEMLOGSYS_LEVEL;
	typedef enum E_IMEMLOGSYS_DEE{ E_IMEMLOGSYS_ENCRYPTION, E_IMEMLOGSYS_DEENCRYPTION, }E_IMEMLOGSYS_DEE;
	typedef bool pfn_Encryption( p_in_out_ TCHAR*, p_in_ E_IMEMLOGSYS_DEE eWay);		//加解密函数
	
	virtual void WriteLog(const TCHAR* pszModuleName, const TCHAR* pszFormat, ...);			//写内存日志
	virtual void OutPutLogToFile(const TCHAR* pszFilePath);									//输出内存日志
	virtual void RegisterEncryption(pfn_Encryption pfnEncryFunc);							//注册加解密
	virtual void RegisterLogLevel(E_IMEMLOGSYS_LEVEL eLevel);								//设置日志级别
};

 

 

 

Sign Clown 2010.7.3 . 12:39 . HYPD
[本文原创,转载请注明出处,在文章末尾提供原文链接http://www.cnblogs.com/JefferyZhou/,否则一旦发现,将按字节每人民币收费,绝不论价]
posted on 2010-07-03 12:40  JefferyZhou  阅读(3661)  评论(0编辑  收藏  举报