项目中需要分类日志功能,且日志由多个进程产生,所以写了这个类。
- #ifndef CAPPLOG_H_
- #define CAPPLOG_H_
- #include "Generic.h"
- enum LOG_TYPE
- {
- LOG_DEAGNOSTIC_MSG = 0x00000000,
- LOG_EVENT = 0x00000001,
- LOG_ACTIVITY = 0x00000002,
- LOG_ERROR = 0x00000004,
- };
- class CAppLog {
- public:
- CAppLog();
- virtual ~CAppLog();
- static void appendDeagnosticMsg( const char * lpszFmt, ...);
- static void appendEvent( const char * lpszFmt, ...);
- static void appendActivity( const char * lpszFmt, ...);
- static void appendError( const char * lpszFmt, ...);
- private:
- static sem_t * s_pLogFileSem;
- static void append(LOG_TYPE emType, const char * lpszText);
- };
- #endif /* CAPPLOG_H_ */
以下是它的实现
- /*
- * CAppLog.cpp
- *
- * Created on: Jan 1, 2009
- * Author: root
- */
- #include "CAppLog.h"
- #include "CSystemHelper.h"
- #define LOG_SEM_NAME "LogFileSem"
- sem_t * CAppLog::s_pLogFileSem = NULL;
- CAppLog g_oAppLog;
- CAppLog::CAppLog() {
- if( s_pLogFileSem == NULL )
- {
- s_pLogFileSem = sem_open( LOG_SEM_NAME, O_CREAT, 0666, 1);
- }
- }
- CAppLog::~CAppLog() {
- if( s_pLogFileSem != NULL )
- {
- sem_close(s_pLogFileSem);
- s_pLogFileSem = NULL;
- }
- }
- void CAppLog::append(LOG_TYPE emType, const char * lpszText)
- {
- char szBuffer[10240] = {0};
- int nRet = readlink("/proc/self/exe", szBuffer, sizeof(szBuffer));
- if( nRet <= 0 || nRet >= PATH_MAX )
- return;
- string strTemp(szBuffer);
- string strDir = strTemp.substr(0, strTemp.rfind( '/') + 1);
- string strExe = strTemp.substr(strTemp.rfind( '/') + 1);
- time_t ulNow = {0};
- time(&ulNow);
- tm * pNow = localtime(&ulNow);
- memset( szBuffer, 0, sizeof(szBuffer));
- sprintf( szBuffer, "%sLog/%04d/%04d-%02d/"
- , strDir.c_str()
- , 1900 + pNow->tm_year
- , 1900 + pNow->tm_year
- , 1 + pNow->tm_mon
- );
- CSystemHelper::createDirectory(szBuffer);
- sprintf( szBuffer, "%sLog/%04d/%04d-%02d/%04d-%02d-%02d.log"
- , strDir.c_str()
- , 1900 + pNow->tm_year
- , 1900 + pNow->tm_year
- , 1 + pNow->tm_mon
- , 1900 + pNow->tm_year
- , 1 + pNow->tm_mon
- , pNow->tm_mday
- );
- sem_wait(s_pLogFileSem);
- {
- ofstream stream( szBuffer,ios::out | ios::app);
- if( stream )
- {
- char szFormated[20480] = {0};
- sprintf( szFormated, "/r/n%02d[%02d:%02d:%02d PID=%05d TID=%05ld EXE=%-15s] %s"
- , emType
- , pNow->tm_hour
- , pNow->tm_min
- , pNow->tm_sec
- , getpid()
- , (long)syscall(SYS_gettid)
- , strExe.c_str()
- , lpszText
- );
- stream << szFormated;
- stream.flush();
- stream.close();
- }
- }
- sem_post(s_pLogFileSem);
- }
- void CAppLog::appendDeagnosticMsg( const char * lpszFmt, ...)
- {
- va_list arg;
- va_start(arg, lpszFmt);
- char szBuffer[10240] = {0};
- vsprintf( szBuffer, lpszFmt, arg);
- va_end(arg);
- CAppLog::append( LOG_DEAGNOSTIC_MSG, szBuffer);
- }
- void CAppLog::appendEvent( const char * lpszFmt, ...)
- {
- va_list arg;
- va_start(arg, lpszFmt);
- char szBuffer[10240] = {0};
- vsprintf( szBuffer, lpszFmt, arg);
- va_end(arg);
- CAppLog::append( LOG_EVENT, szBuffer);
- }
- void CAppLog::appendActivity( const char * lpszFmt, ...)
- {
- va_list arg;
- va_start(arg, lpszFmt);
- char szBuffer[10240] = {0};
- vsprintf( szBuffer, lpszFmt, arg);
- va_end(arg);
- CAppLog::append( LOG_ACTIVITY, szBuffer);
- }
- void CAppLog::appendError( const char * lpszFmt, ...)
- {
- va_list arg;
- va_start(arg, lpszFmt);
- char szBuffer[10240] = {0};
- vsprintf( szBuffer, lpszFmt, arg);
- va_end(arg);
- CAppLog::append( LOG_ERROR, szBuffer);
- }
使用起来很简单,将类加入到工程,然后在需要的地方包含此类的头文件,然后直接调用静态方法。这里用到了一个辅助类的函数 CSystemHelper::createDirectory,它的实现如下:
- void CSystemHelper::createDirectory(const char * lpszDir)
- {
- string strDir(lpszDir);
- int nIndex = 0;
- while(nIndex != string::npos)
- {
- int nFind = strDir.find( "/", nIndex+1);
- string strTemp = strDir.substr( 0, nFind+1);
- DIR *dir = opendir(strTemp.c_str());
- if( dir != NULL )
- closedir(dir);
- else
- mkdir( strTemp.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
- nIndex = nFind;
- }
- }
本文介绍了一个用于多进程环境中分类记录日志的C++类CAppLog。该类能够根据不同的日志类型(诊断消息、事件、活动、错误)记录日志,并通过信号量同步确保日志写入的线程安全。
1万+

被折叠的 条评论
为什么被折叠?



