visual C++实现MFC动态库运用debugview输出日志3:使用单例模式实现CLog类

本文介绍了一个使用单例模式实现的日志类CLog,该类能够记录日志到指定路径的文件中,并支持多种日志保存类型。通过检查特定文件的存在与否来决定日志的保存方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用单例模式实现CLog类

头文件:

/************************************************************************
* 功能描述:日志类.
* 其它说明:使用单例模式实现
************************************************************************/
#ifndef _LOG_
#define _LOG_

#pragma once
#include "afxmt.h"

#define LOG_SAVE_NONE 0x00
#define LOG_SAVE_HDLSO 0x01
#define LOG_SAVE_OCT 0x02
#define LOG_SAVE_TRACING_HDLSO 0x10
#define LOG_SAVE_TRACING_SMALLHDLSO 0x20
#define LOG_SAVE_TRACING_ORIGINALOCT 0x30
#define LOG_SAVE_TRACING_REGISRESULT 0x40


#ifndef MPTDLL
#define MPTEXPORT __declspec(dllimport)
#else
#define MPTEXPORT __declspec(dllexport)
#endif

class MPTEXPORT CLog
{
public:
	static CLog *m_plog;
	static CMutex *m_mutex;
private:
	FILE * m_fp;
	CLog(void);

	void InitSaveImageMask();

public:
	static CLog *GetInstance();
	void WriteLog(LPCTSTR str, ...);
	void WriteLog(CString str, ...);
	~CLog(void);

	bool CheckSaveDataMask(unsigned int mask);

private:
	unsigned int m_nSaveImageMask;///< 保存图像掩码
	
};

#endif

实现文件:

#include "StdAfx.h"
#include "Log.h"
#include <share.h>
#include "debugviewhelper.h"
#include <shlwapi.h>
#include "MyDirectory.h"

CLog *CLog::m_plog = NULL;
CMutex *CLog::m_mutex = new CMutex();

CLog::CLog(void)
	:m_nSaveImageMask(LOG_SAVE_NONE)
{
	CMyDirectory mDirectory;
	CString str = mDirectory.GetCurrentPath();
	str += _T("log.txt");
	
	m_fp = _tfsopen((LPCTSTR)str, _T("w+, ccs=UTF-8"), _SH_DENYNO);

	InitSaveImageMask();
}

CLog::~CLog(void)
{
	if (m_mutex != NULL)
	{
		delete m_mutex;
		m_mutex = NULL;
	}
	if (m_plog != NULL)
	{
		delete m_plog;
		m_plog = NULL;
	}
}

CLog * CLog::GetInstance()
{
	if (m_plog != NULL)
	{
		return m_plog;
	}
	else
	{
		 m_mutex->Lock();
		 if (m_plog == NULL)
		 {
			 m_plog = new CLog();		 
		 }
		 m_mutex->Unlock();
		 return m_plog;
	}
}

void CLog::WriteLog(LPCTSTR str, ...)
{
	if(!m_fp || (_tcslen(str) == 0))
		return;

	TCHAR buffer[1024];
	memset(buffer, 0, sizeof(buffer));
	va_list maker;
	
	va_start(maker, str);
	_vsntprintf_s(buffer, sizeof(buffer)/sizeof(TCHAR) - 1, str, maker);
	va_end(maker);

	CTime tm = CTime::GetCurrentTime();
	
	/*_ftprintf_s(m_fp, _T("%4d-%02d-%02d %02d:%02d:%02d %s\r\n"), 
	tm.GetYear(),
	tm.GetMonth(),
	tm.GetDay(),
	tm.GetHour(),
	tm.GetMinute(),
	tm.GetSecond(), 
	buffer);
	fflush(m_fp);*/

	DI << buffer;
}

void CLog::WriteLog(CString str, ...)
{
	if(!m_fp || (_tcslen(str)== 0))
		return;

	TCHAR buffer[1024];
	va_list maker;

	va_start(maker, str);
	_vsntprintf_s(buffer, sizeof(str)/sizeof(TCHAR) - 1, 1024, str, maker);
	va_end(maker);

	CTime tm = CTime::GetCurrentTime();

	_ftprintf_s(m_fp, _T("%4d-%02d-%02d %02d:%02d:%02d %s\r\n"), 
		tm.GetYear(),
		tm.GetMonth(),
		tm.GetDay(),
		tm.GetHour(),
		tm.GetMinute(),
		tm.GetSecond(), 
		buffer);
	fflush(m_fp);
}

void CLog::InitSaveImageMask()
{
	m_nSaveImageMask = LOG_SAVE_NONE;
	if (PathFileExists(_T("c:\\save_hdlso.txt")))
	{
		m_nSaveImageMask |= LOG_SAVE_HDLSO;
	}

	if (PathFileExists(_T("c:\\save_oct.txt")))
	{
		m_nSaveImageMask |= LOG_SAVE_OCT;
	}
	
	if(PathFileExists(_T("c:\\save_tracing_hdlso.txt")))
	{
		m_nSaveImageMask |= LOG_SAVE_TRACING_HDLSO;
	}
	
	if(PathFileExists(_T("c:\\save_tracing_smallhdlso.txt")))
	{
		m_nSaveImageMask |= LOG_SAVE_TRACING_SMALLHDLSO;
	}
	
	if(PathFileExists(_T("c:\\save_tracing_oct.txt")))
	{
		m_nSaveImageMask |= LOG_SAVE_TRACING_ORIGINALOCT;
	}
	
	if(PathFileExists(_T("c:\\save_tracing_regis.txt")))
	{
		m_nSaveImageMask |= LOG_SAVE_TRACING_REGISRESULT;
	}
}

bool CLog::CheckSaveDataMask(unsigned int mask)
{
	return (m_nSaveImageMask & mask) != 0 ? true : false;
}

 

////////////////////////////////////////////README//////////////////////////////////////////////////// // DebugLog--write some log for debug // //初衷: 版本开发的时候,有些功能点是可以项目无关的,比如是解析某个文件;开发完成之后,测试的话, // // 需要整改项目程序运行、测试,功能点的触发条件比较麻烦。所以,有的时候,对于这样的功能点, // // 我会选择进行本地开发,然后再合到项目中去. // // 但是,每次功能点开发的时候,一般用的是printf直接打屏,但是项目中用的是写文件,所以移植 // // 的时候还需要进行不少改动. // // 于是,我就想自己写个log,可以与项目的日志函数进行适配。那么,上面的问题可以得到比较好的 // // 解决(或者说是规避)。 // //附注:我不知道这样做有没有意义,也就是根据自己的经验,试着做了下。经验不足,水平有限,肯定会 // // 导致设计不足,不对,甚至是整个设计没有意义。如果是这样,希望能不吝交流、赐教. // // EMail: hu__haifeng@163.com // ////////////////////////////////////////////////////////////////////////////////////////////////////// //Version :0.5 // //Description:该版本打造了基本的架构,并且实现了不带参数的打印日志(仅仅是字符串),可以进行监督的测试.// // 由于我项目经验有限,仅仅见过两种不同的项目日志分隔,所以也只能以此为参考,不一定可以 // // 适配其他项目日志函数. // //Adapter :可以用宏定义来进行适配。比如: // // #ifdef __CLOG_H__ // // #define DEBUG(VAR) mylog.Print(__FILE__, __LINE__, VAR, LOG_DEBUG) // // #else // // #define DEBUG(VAR) function //项目用的标准的日志函数. // // #endif // // // //Plan :1.0版本写成可以带参数的日志。2.0版本实现客户端、服务器版本(可以支持不同的进程写日志)。// //////////////////////////////////////////////////////////////////////////////////////////////////////
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

haimianjie2012

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值