开源一个C/C++日志类

前言

日志类可以作为一个练手项目,实现一个好的日志类并不容易,这里先出第一个版本,后期持续优化。功能简单对于新手非常友好,欢迎指正错误。

介绍

该日志类我命名为CClog,第一个C是class的意思,忽略这一点的话可以叫Clog。作用当然是日志记录,写日志操作是线程安全的,支持类似字符串Format的形式。

环境

基于Windows平台

使用案例Demo

// test.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include 
#include "Clog.h"
#include 

int _tmain(int argc, _TCHAR* argv[])
{
    //初始化工作,主要是创建目录、日志文件,必须只能在主线程完成-----线程不安全。
	CClog::InitClog("dir\\");
    //所有的写操作都是线程安全的
	CClog::Instance().WriteLog("test");
	CClog::Instance().WriteLogFormat("%d,%d,%d",110,112,1);
    //资源释放,线程不安全
	CClog::CloseClog();
	return 0;
}

需要注意的是:
初始化工作,主要是创建目录、日志文件,必须只能在主线程完成-----线程不安全。
所有的写操作都是线程安全的
资源释放,线程不安全

CClog.h

#pragma once

//////////////////////////////////////////////////////////////////////////
//         author:  wzy
//		   csdn:    https://blog.csdn.net/Think88666
//         date:    2019-09-05
//////////////////////////////////////////////////////////////////////////
#include 

class CClog
{
public:
	static bool InitClog(const char *szDstDir);
	static bool CloseClog();
	const static CClog &Instance();
private:
	static CClog *s_log;

private:
	CClog(void);

	FILE *m_hFile;
	char *m_szFileName;
	char *m_szFormatBuff;
	HANDLE m_hMutex;

public:
	~CClog(void);
	void WriteLog(const char *szInfo) const;
	void WriteLogFormat(const char *szFormat,...) const;
};

CClog.cpp

#include "StdAfx.h"
#include "Clog.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define F_OK 0   /* Check for file existence */
#define X_OK 1   /* Check for execute permission. */
#define W_OK 2   /* Check for write permission */
#define R_OK 4   /* Check for read permission */


#define _MUTEX_START_  	DWORD  d  = WaitForSingleObject(m_hMutex, INFINITE); \
							   if(d != WAIT_OBJECT_0 ) return;


#define _MUTEX_END_   ReleaseMutex(m_hMutex);

//初始化
CClog *CClog::s_log = NULL;

CClog::CClog(void):m_hFile(NULL),m_szFileName(NULL),m_szFormatBuff(NULL)
{
	m_szFileName = new char[400];
	m_szFormatBuff = new char [5120];
	m_hMutex = CreateMutex(NULL,FALSE,NULL);
}

CClog::~CClog(void)
{
	if(m_szFileName)
		delete []m_szFileName;
	if(m_hFile)
		fclose(m_hFile);
	if(m_szFormatBuff)
		delete []m_szFormatBuff;
	CloseHandle(m_hMutex);
}

bool CClog::InitClog( const char *szDstDir )
{
	//check dir
	int nDirFlag = access(szDstDir,F_OK | W_OK);
	if(-1 == nDirFlag)
	{
		int nMkDirFlag = mkdir(szDstDir);
		assert(-1 != nMkDirFlag);
		if(-1 == nMkDirFlag)
			return false;
	}
	//create file
	srand((unsigned int)time(NULL));
	int nRand = rand();
	time_t nNowTime = time(0);
	tm* nowTm = localtime(&nNowTime);
	char szBuff[90] = "\0";
	strftime(szBuff, sizeof(szBuff) - 1, "%Y_%m_%d__%H_%M_%S", nowTm);
	char szBuff2[30] = "\0";
	sprintf(szBuff2,"_%d.log",nRand%10000);
	
	strcat(szBuff,szBuff2);

	if(s_log) delete s_log;
	s_log = new CClog;
	int nLen = strlen(szDstDir);
	assert(nLen+strlen(szBuff)<399);
	strcpy(s_log->m_szFileName,szDstDir);
	if(s_log->m_szFileName[nLen-1] != '/' && s_log->m_szFileName[nLen-1] != '\\' )
	{
		s_log->m_szFileName[nLen] = '/';
		s_log->m_szFileName[nLen+1] = '\0';
	}
	strcat(s_log->m_szFileName,szBuff);


	s_log->m_hFile = fopen(s_log->m_szFileName,"a");
	assert(s_log);
	if(!s_log->m_hFile)
		return false;
	fputs("###Powered by Clog###",s_log->m_hFile);
	return true;

}

bool CClog::CloseClog()
{

	if(s_log)
	{
		delete s_log;
		s_log = NULL;
	}
	return true;
}



void CClog::WriteLog(const char *szInfo) const
{
	_MUTEX_START_

	assert(szInfo);
	if(m_hFile)
	{
		time_t nNowTime = time(0);
		tm* nowTm = localtime(&nNowTime);
		char szBuff[90] = "\0";
		strftime(szBuff, sizeof(szBuff) - 1, "\n%Y-%m-%d %H:%M:%S  ", nowTm);
		fputs(szBuff,m_hFile);
		fputs(szInfo,m_hFile);
	}

	_MUTEX_END_
}

void CClog::WriteLogFormat(const char *szFormat,...) const
{
	//线程安全   
	//申请占用互斥量
	_MUTEX_START_

	va_list aptr;
	va_start(aptr, szFormat);
	//保证不溢出
	vsnprintf(m_szFormatBuff, 5119,szFormat, aptr);
	va_end(aptr);

	if(m_hFile)
	{
		time_t nNowTime = time(0);
		tm* nowTm = localtime(&nNowTime);
		char szBuff[90] = "\0";
		strftime(szBuff, sizeof(szBuff) - 1, "\n%Y-%m-%d %H:%M:%S  ", nowTm);
		fputs(szBuff,m_hFile);
		fputs(m_szFormatBuff,m_hFile);
	}

	_MUTEX_END_
}

const CClog &CClog::Instance()
{
	assert(s_log);
	return *s_log;
}

GIthub地址:

https://github.com/1002130915/CClog

你可能感兴趣的:(c++,开源)