编程实例:
#include "Mutex.h"
#include "CTime.h"
#include <fcntl.h>
#include <iostream>
#include <stdarg.h>
#include <fstream>
#define LOGPATH "./common.log"
#define BUFSIZE 2048
class CLog
{
public:
static CLog* getInstance();
void Init(const char* path, int level);
void Error(char *pFmt, ...);
void Info(char *pFmt, ...);
void Debug(char *pFmt, ...);
void Warn(char *pFmt, ...);
void Log(int level, const char * loginfo);
private:
CLog(){}
static CLog *m_log;
CLog(const CLog& clog);
CLog& operator=(const CLog& clog);
Mutex m_mutex;
int m_logLevel;
const char* m_logPath;
enum { LOG_ERROR = 0, LOG_INFO, LOG_WARN, LOG_DEBUG};
};
CLog* CLog::m_log = NULL;
CLog* CLog::getInstance()
{
if(m_log == NULL)
{
m_log = new CLog();
}
return m_log;
}
void CLog::Init(const char* path, int level)
{
m_logPath = path;
m_logLevel = level;
}
void CLog::Log(int level, const char * loginfo)
{
const char *infos[4] = {"ERROR: ", "INFO: ", "WARN : ", "DEBUG: "};
m_mutex.Lock();
CTime time;
std::ofstream fout(m_logPath, std::ios::app|std::ios::ate);
if(fout)
{
fout<<"["<<time<<"]"<<infos[level]<<loginfo<<std::endl;
if(fout.tellp() > 2*1024*1024)
{
fout.close();
std::string logname = m_logPath + time.getTime(); //back the log file
rename(m_logPath, logname.c_str());
}
}
else
{
std::cout << time << infos[0] <<"open file failed \n"<<strerror(errno) << std::endl;
}
if(fout) fout.close();
m_mutex.UnLock();
}
void CLog::Error(char *pFmt, ...)
{
va_list valist;
char Buf[BUFSIZE]={'\0'};
va_start(valist, pFmt);
vsnprintf(Buf, sizeof(Buf)-1, pFmt, valist);
va_end(valist);
Log(LOG_ERROR, Buf);
}
void CLog::Info(char *pFmt, ...)
{
va_list valist;
char Buf[BUFSIZE]={'\0'};
va_start(valist, pFmt);
vsnprintf(Buf, sizeof(Buf)-1, pFmt, valist);
va_end(valist);
Log(LOG_INFO, Buf);
}
void CLog::Debug(char *pFmt, ...)
{
va_list valist;
char Buf[BUFSIZE]={'\0'};
va_start(valist, pFmt);
vsnprintf(Buf, sizeof(Buf)-1, pFmt, valist);
va_end(valist);
Log(LOG_DEBUG, Buf);
}
void CLog::Warn(char *pFmt, ...)
{
va_list valist;
char Buf[BUFSIZE]={'\0'};
va_start(valist, pFmt);
vsnprintf(Buf, sizeof(Buf)-1, pFmt, valist);
va_end(valist);
Log(LOG_WARN, Buf);
}
Mutext.h
#include <cstdlib>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <cstdio>
#include <string.h>
class Mutex
{
public:
Mutex();
virtual ~Mutex();
void Lock();
void UnLock();
private:
friend class CondVar;
pthread_mutex_t m_mutex;
Mutex(const Mutex&);
void operator=(const Mutex&);
};
class CondVar
{
public:
explicit CondVar(Mutex* mu);
virtual ~CondVar();
void Wait();
void Signal();
void SignalAll();
private:
pthread_cond_t m_cond;
Mutex *m_mu;
};
class CASLock
{
public:
CASLock(void* lock);
virtual ~CASLock();
void Lock();
void UnLock();
bool TryLock();
private:
void* m_lock;
};
static void MutexErr(const char* err, int res)
{
if(res != 0)
{
fprintf(stderr, "pthread %s: %s\n", err, strerror(res));
return;
}
}
Mutex::Mutex()
{
MutexErr("init mutex", pthread_mutex_init(&m_mutex, NULL));
}
Mutex::~Mutex()
{
MutexErr("destroy mutex", pthread_mutex_destroy(&m_mutex));
}
void Mutex::Lock()
{
MutexErr("lock mutex", pthread_mutex_lock(&m_mutex));
}
void Mutex::UnLock()
{
MutexErr("unlock mutex", pthread_mutex_unlock(&m_mutex));
}
CondVar::CondVar(Mutex* mu):m_mu(mu)
{
MutexErr("init cond", pthread_cond_init(&m_cond, NULL));
}
CondVar::~CondVar()
{
MutexErr("destroy cond", pthread_cond_destroy(&m_cond));
}
void CondVar::Wait()
{
MutexErr("wait cond", pthread_cond_wait(&m_cond, &m_mu->m_mutex));
}
void CondVar::Signal()
{
MutexErr("signal cond", pthread_cond_signal(&m_cond));
}
void CondVar::SignalAll()
{
MutexErr("broadcast cond", pthread_cond_broadcast(&m_cond));
}
CASLock::CASLock(void* lock):m_lock(lock){}
CASLock::~CASLock(){}
void CASLock::Lock()
{
while(!__sync_bool_compare_and_swap((int*)m_lock, 0, 1))
{
sched_yield();
}
}
void CASLock::UnLock()
{
*((int*)m_lock) = 0;
}
bool CASLock::TryLock()
{
if(__sync_bool_compare_and_swap((int*)m_lock, 0, 1))
return 0;
else
return -1;
}
CTime.h
#include <iostream>
#include <cstring>
#include <ctime>
#include <sys/time.h>
#include <cstdio>
class CTime
{
public:
CTime();
CTime(std::string tim);
virtual ~CTime();
std::string getTime();
std::string getShortTime();
friend std::ostream& operator<<(std::ostream& os, CTime& tim);
void Start();
void Stop();
void Reset();
void costTime();
private:
std::string m_time; //reserve the time
void timeToStr(char* buf);
struct timeval t1, t2;
bool b;
};
void CTime::timeToStr(char *buf)
{
time_t ti = time(NULL);
strftime(buf, 30, "%Y-%m-%d %H:%M:%S", localtime(&ti));
}
CTime::CTime()
{
char buf[30]={'\0'};
timeToStr(buf);
m_time = std::string(buf);
}
CTime::CTime(std::string tim)
{
if(tim.size() == 0)
{
char buf[30];
timeToStr(buf);
m_time = buf;
}
else
{
m_time = tim;
}
}
CTime::~CTime()
{}
std::string CTime::getTime()
{
return m_time;
}
std::string CTime::getShortTime()
{
if(m_time.size())
{
return m_time.substr(0, m_time.find_first_of(' '));
}
else
{
char buf[30];
timeToStr(buf);
return std::string(buf);
}
}
void CTime::Start()
{
b = false;
gettimeofday(&t1, NULL);
}
void CTime::Stop()
{
gettimeofday(&t2, NULL);
}
void CTime::Reset()
{
}
void CTime::costTime()
{
int usec = 0, sec =0;
if(t2.tv_usec > t1.tv_usec)
{
usec = t2.tv_usec - t1.tv_usec;
}
else
{
b = true;
usec = t2.tv_usec + 1000000 - t1.tv_usec;
}
if(b)
{
sec = t2.tv_sec -1 -t1.tv_sec;
}
else
{
sec = t2.tv_sec - t1.tv_sec;
}
printf("cost the time:%.05fms\n", (double)(sec*1000000+usec)/1000);
}
std::ostream& operator<<(std::ostream& os, CTime& tim)
{
os <<tim.m_time;
return os;
}
TestLog.cpp
#include "CLog.h"
CLog *cLog = CLog::getInstance();
int main(int argc, char *argv[])
{
cLog->Init("./common.log", 0);
cLog->Info("test the program");
cLog->Error("err\n");
return 0;
}
编译:
g++ -o testLog TestLog.cpp CLog.h Mutex.h CTime.h