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

2 篇文章 0 订阅

前言

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

介绍

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

环境

基于Windows平台

使用案例Demo

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

#include "stdafx.h"
#include <stdlib.h>
#include "Clog.h"
#include <Windows.h>

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 <Windows.h>

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 <stdlib.h>
#include <stdio.h>
#include <io.h>
#include <time.h>
#include <assert.h>
#include <memory>
#include <direct.h>
#include <stdarg.h>

#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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

宇龍_

若帮助到你,希望能给予鼓励!

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

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

打赏作者

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

抵扣说明:

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

余额充值