主要增加了变参格式字符串的日志输出、静态函数日志输出以及日志等级;
/*
* 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以前的版本: