当前位置: 首页 > 工具软件 > cclog > 使用案例 >

c++ 日志类 CCLog(更新)

鱼志诚
2023-12-01

主要增加了变参格式字符串的日志输出、静态函数日志输出以及日志等级;


/*
 *  CCLog.h
 *  c++_common_codes
 *
 *  Created by xichen on 12-1-12.
 *  Copyright 2012 cc_team. All rights reserved.
 *	
 *	2012-3-3	add the log level , variable argument string output and 
 *				static log output func
*/
#ifndef CC_LOG_H
#define CC_LOG_H

#include "ccStringBase.h"
#include <cstdio>

typedef enum _LOG_TYPE
{
    LOG_TYPE_CONSOLE,
    LOG_TYPE_FILE,

    LOG_TYPE_MAX
}LOG_TYPE;

typedef enum _LOG_LEVEL
{
	LOG_LEVEL_SERIOUS_ERROR,		// serious error
	LOG_LEVEL_ERROR,				// error
	LOG_LEVEL_WARNING,				// warning
	LOG_LEVEL_INFO,					// info
	
	LOG_LEVEL_MAX
}LOG_LEVEL;

class CCLog
{
public:
    CCLog(const char * fileName = NULL, const char * mode = "wa+");    // by default, open file by "wa+" mode
    ~CCLog();

public:
    unsigned	write(const CCString & str, LOG_LEVEL logLevel = LOG_LEVEL_INFO);
    unsigned	writeLine( const CCString & str , LOG_LEVEL logLevel = LOG_LEVEL_INFO);	// it will write another '\n', comparing to write func above
	unsigned	write(LOG_LEVEL logLevel, const char *str, ...);
	unsigned	writeLine(LOG_LEVEL logLevel, const char *str, ...);
	
	unsigned	writeEndl(LOG_LEVEL logLevel = LOG_LEVEL_INFO);		// it will just write an '\n'
    void		clearAllData();	    // if a file is opened, all contents of the file will be cleared, the file will be opened a second time.

public:
	// the four static log funcs below are just for console output, alse the str will be output immediately
	static		void	logSE(const CCString & str);		// log as serious error
	static		void	logE(const CCString & str);		// log as error
	static		void	logW(const CCString & str);		// log as warning
	static		void	logI(const CCString & str);		// log as info
	
public:
    void	setWriteToConsole();
    void	setWriteToFile();

public:
    LOG_TYPE	getLogType() const { return _logType; }
    CCString	getLogFileName() const { return _fileName; }
	LOG_LEVEL	getLogLevel() const { return _logLevel; }
	void		setLogLevel(LOG_LEVEL newLevel)	{ _logLevel = newLevel; }

public:    
    void	clearConsole()	    
    {
#ifdef _WINDOWS					// windows
		system("cls");	
#elif defined(__APPLE__)		// mac
		system("clear");
#else
		system("clear");
#endif
    }

private:
    CCLog(const CCLog & log);
    CCLog & operator=(const CCLog & log);

private:
    FILE	*_file;
    FILE	*_backupFile;
    CCString	_fileName;
    LOG_TYPE	_logType;
	LOG_LEVEL	_logLevel;
};

#endif

/*
 *  CCLog.cpp
 *  c++_common_codes
 *
 *  Created by xichen on 12-1-12.
 *  Copyright 2012 cc_team. All rights reserved.
 *
*/
#include "ccLog.h"

CCLog::CCLog( const char * fileName /*= NULL*/, const char * mode /*= "wa+"*/ )
{
    if(fileName == NULL)
    {
		_file = _backupFile = NULL;
		_logType = LOG_TYPE_CONSOLE;
		_logLevel = LOG_LEVEL_INFO;
		return;
    }

    _logType = LOG_TYPE_FILE;
	_logLevel = LOG_LEVEL_INFO;
    _file = fopen(fileName, mode);
    _backupFile = _file;
    if(_file == NULL)
	{
		std::cerr << "Open file error" << std::endl;
		exit(-1);
	}
    else
		_fileName = CCString(fileName);
}

CCLog::~CCLog()
{
    if(_logType == LOG_TYPE_FILE)
    {
		if(_file != NULL)
		{
			fclose(_file);
			return;
		}
		if(_backupFile != NULL)
		{
			fclose(_backupFile);
		}
    }
}

unsigned CCLog::write( const CCString & str , LOG_LEVEL logLevel /* = LOG_LEVEL_INFO */)
{
	if(logLevel > _logLevel)
	{
		std::cerr << "CCLog Internal:logLevel is too big, nothing will logged" << std::endl;
		return 0;
	}
	
    if(_logType == LOG_TYPE_CONSOLE)
    {
		int ret = printf("%s", str.c_str());
		fflush(stdout);
		return ret;	
    }

    fseek(_file, 0, SEEK_END);
    return fwrite(str.c_str(), 1, str.length(),  _file);
}

unsigned CCLog::writeLine( const CCString & str , LOG_LEVEL logLevel /* = LOG_LEVEL_INFO */)
{
	CCString temp = str + "\n";
	return write(temp, logLevel);
}

unsigned	CCLog::write(LOG_LEVEL logLevel, const char *str, ...)
{
	if(logLevel > _logLevel)
	{
		std::cerr << "CCLog Internal:logLevel is too big, nothing will logged" << std::endl;
		return 0;
	}
	
	if(_logType == LOG_TYPE_CONSOLE)
	{
		va_list args;
		va_start (args, str);
		int ret = vfprintf (stdout, str, args);
		va_end (args);
		return ret;
	}
	
	fseek(_file, 0, SEEK_END);
	
	va_list args;
	va_start (args, str);
	int ret = vfprintf (_file, str, args);
	va_end (args);
	return ret;
}

unsigned	CCLog::writeLine(LOG_LEVEL logLevel, const char *str, ...)
{
	if(logLevel > _logLevel)
	{
		std::cerr << "CCLog Internal:logLevel is too big, nothing will logged" << std::endl;
		return 0;
	}
	
	if(_logType == LOG_TYPE_CONSOLE)
	{
		va_list args;
		va_start (args, str);
		int ret = vfprintf (stdout, str, args);
		va_end (args);
		int retEndl = printf("\n");
		return ret + retEndl;
	}
	
	fseek(_file, 0, SEEK_END);
	
	va_list args;
	va_start (args, str);
	int ret = vfprintf (_file, str, args);
	va_end (args);
	int retEndl = vfprintf(_file, "\n", args);
	return ret + retEndl;
}


unsigned CCLog::writeEndl(LOG_LEVEL logLevel /* = LOG_LEVEL_INFO */)
{
	if(logLevel > _logLevel)
	{
		std::cerr << "CCLog Internal:logLevel is too big, nothing will logged" << std::endl;
		return 0;
	}
    return write("\n");
}


void CCLog::clearAllData()
{
    if(_logType == LOG_TYPE_CONSOLE)
		return;

    if(_backupFile != NULL)
		_file = _backupFile;

    fclose(_file);
    _file = fopen(CCString(_fileName), "wt+");	    // clear all the data of file
    _backupFile = _file;
    if(_file == NULL)
		std::cerr << "clearAllData:Open file error" << std::endl;
}

void	CCLog::logSE(const CCString & str)		// log as serious error
{
	std::cerr << "Serious Error:" << str.c_str() << std::endl;
}

void	CCLog::logE(const CCString & str)		// log as error
{
	std::cerr << "Error:" << str.c_str() << std::endl;
}

void	CCLog::logW(const CCString & str)		// log as warning
{
	std::cerr << "Warning:" << str.c_str() << std::endl;
}

void	CCLog::logI(const CCString & str)		// log as info
{
	std::cerr << "Info:" << str.c_str() << std::endl;
}

void CCLog::setWriteToConsole()
{
    _logType = LOG_TYPE_CONSOLE;
}

void CCLog::setWriteToFile()
{
    _logType = LOG_TYPE_FILE;
}


测试代码:

void ccTestLog()
{
#if 1	    // CCLog		// ok
    CCLog * log = new CCLog(NULL);
    log->write("hello");
    log->write("\t1\n");
    log->write("\txichen\n");

    delete log;
#ifdef	_WINDOWS
    log = new CCLog("logtest.txt");
#else
	log = new CCLog("logtest.txt");
#endif
    log->write("ab\t\n1");
    delete log;
#ifdef	_WINDOWS
    log = new CCLog("logtest.txt");
#else
	log = new CCLog("logtest.txt");
#endif
    log->write("xiche\t123");
    log->clearAllData();
    log->write("after clear");
    log->setWriteToConsole();
    log->write("the console info");
    log->setWriteToFile();
    log->write("the file content");
    log->writeEndl();
    log->write("the next line\nhehe");
	
	log->setWriteToConsole();
	log->write(LOG_LEVEL_INFO, "hello %d", 100);
	log->writeLine(LOG_LEVEL_INFO, "hello %d", 100);
	log->writeLine(LOG_LEVEL_INFO, "hello %d", 100);
	
	log->setWriteToFile();
	log->write(LOG_LEVEL_INFO, "hello %d", 100);
	log->writeLine(LOG_LEVEL_INFO, "hello %d", 100);
	
    delete log;
	
	log = new CCLog(NULL);
	log->setLogLevel(LOG_LEVEL_ERROR);
	log->writeLine("serious error 1", LOG_LEVEL_SERIOUS_ERROR);
	log->writeLine("error 1", LOG_LEVEL_ERROR);
	log->writeLine("warning 1", LOG_LEVEL_WARNING);
	log->writeLine("info 1", LOG_LEVEL_INFO);
	
	log->setLogLevel(LOG_LEVEL_INFO);
	log->writeLine("serious error 1", LOG_LEVEL_SERIOUS_ERROR);
	log->writeLine("error 1", LOG_LEVEL_ERROR);
	log->writeLine("warning 1", LOG_LEVEL_WARNING);
	log->writeLine("info 1", LOG_LEVEL_INFO);
	
	log->setLogLevel(LOG_LEVEL_MAX);
	log->writeLine("serious error 1", LOG_LEVEL_SERIOUS_ERROR);
	log->writeLine("error 1", LOG_LEVEL_ERROR);
	log->writeLine("warning 1", LOG_LEVEL_WARNING);
	log->writeLine("info 1", LOG_LEVEL_INFO);
	
	log->clearConsole();
	
	delete	log;
	
	CCLog::logSE("error");
	CCLog::logE("error");
	CCLog::logW("error");
	CCLog::logI("error");
	
	
	
#endif
}

测试代码结果:

Serious Error:error

Error:error

Warning:error

Info:error



注:

1、CCLog以前的版本:

http://blog.csdn.net/cxsjabcabc/article/details/7294969

 类似资料: