青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

那誰的技術博客

感興趣領域:高性能服務器編程,存儲,算法,Linux內核
隨筆 - 210, 文章 - 0, 評論 - 1183, 引用 - 0
數據加載中……

服務器公共庫開發--log系統

實現了簡易的log打印,有以下的特點:
1) 支持向標準輸出或者文件打印log
2) 向文件打印log時限制log文件的大小, 同時, 如果在文件大小超出范圍的時候, 可以選擇下一個文件進行打印.在這里, 文件大小和文件的數量都是可以配置的.
3) 支持分級別打印, 目前分的級別有DEBUG,ERROR,WARN,INFO這幾種, 在打印時, 也可以通過宏來開啟DEBUG,WARN的log.
4) 在向文件打印log時, 支持多線程, 同樣的, 這個也是可以配置的.

分為三個文件,log.h是對外的接口, 提供對文件打印log和對標準輸出打印log的簡易封裝, 具體使用哪種方式, 可以通過宏進行配置;logger.h和logger.cpp是對文件進行打印的類封裝, 是一個單件類, 因此繼承自前面提過的singleton類.

log.h:

/********************************************************************
    created:    2008/08/02
    filename:   log.h    
    author:        Lichuang
                
    purpose:    log模塊的對外接口, 可以根據宏將log打印到文件或者標準
                輸出
********************************************************************
*/

#ifndef __LOG_H__
#define __LOG_H__

#ifdef __USE_LOG_FILE__

#include 
"logger.h"

#define LOG(runlevel, file, lineno, args)   \
        
do                                  \
        {                                   \
            CLogger::GetInstance()
->Log(    \
                    runlevel, file,         \
                    lineno, args);          \
        } 
while (0)

#define RUN_MSG_LOG()        LOG(INFO, __FILE__, __LINE__, __VA_ARGS__);
#define ERROR_MSG_LOG()      LOG(ERROR, __FILE__, __LINE__, __VA_ARGS__);

#ifdef LOG_DEBUG_MSG
    
#define DEBUG_MSG_LOG()  LOG(DEBUG, __FILE__, __LINE__, __VA_ARGS__);
#else
    
#define DEBUG_MSG_LOG(
#endif

#ifdef LOG_WARN_MSG
    
#define WARN_MSG_LOG()   LOG(WARN, __FILE__, __LINE__, __VA_ARGS__);
#else
    
#define WARN_MSG_LOG(
#endif

#else

#include 
<stdio.h>
#include 
<stdlib.h>
#include 
<time.h>
#include 
<stdarg.h>
#include 
<sys/time.h>

#define LOG(runlevel, file, lineno, args)   \
        
do{ \
                
struct timeval now;\
                gettimeofday(
&now,0); \
                
struct tm *ptm=localtime(&(now.tv_sec)); \
                fprintf(runlevel, 
"[%d:%d] [%s:%d]",ptm->tm_hour,ptm->tm_min, file,lineno); \
                fprintf(runlevel, args); \
                fprintf(runlevel, 
"\n"); \
        }
while(0)

#define RUN_MSG_LOG()        LOG(stdout, __FILE__, __LINE__, __VA_ARGS__);
#define ERROR_MSG_LOG()      LOG(stderr, __FILE__, __LINE__, __VA_ARGS__);

#ifdef LOG_DEBUG_MSG
    
#define DEBUG_MSG_LOG()  LOG(stdout, __FILE__, __LINE__, __VA_ARGS__);
#else
    
#define DEBUG_MSG_LOG(
#endif

#ifdef LOG_WARN_MSG
    
#define WARN_MSG_LOG()   LOG(stdout, __FILE__, __LINE__, __VA_ARGS__);
#else
    
#define WARN_MSG_LOG(
#endif

#endif

#endif /* __LOG_H__ */


logger.h
/********************************************************************
    created:    2008/08/02
    filename:   logger.h    
    author:        Lichuang
                
    purpose:    實現簡易的log打印
********************************************************************
*/

#ifndef __LOGGER_H__
#define __LOGGER_H__

#include 
"defines.h"
#include 
"singleton.h"
#include 
"threadmutex.h"
#include 
<string>

using namespace std;

struct LogInfo
{
    
int nFileNum;
    
string strFileSuffix;
    
string strFileName;
};

enum 
{
    DEBUG 
= 0,
    WARN,
    ERROR,
    INFO,
    NUM_OF_LOG_LEVEL
};

class CLogger
    : 
public CSingleton<CLogger>
{
public:

public:
    
int Init(const string& strLogPath, const string& strFileName);
    
int Log(int nLogLevel, const char* pFileName, int nLine, const char *szFormat, );

private:
    DECLARE_SINGLETON_CLASS(CLogger)
    CLogger();
    
virtual ~CLogger();

    
int GetFileName(int nLogLevel);
    
int CheckFileSize(const string& strFileName);
    
void GenerateFileName(string& strFileName, int nFileNum, int nLogLevel);

private:
    
string m_strLogPath;
    
string m_strFileName;
    LogInfo m_szLogInfo[NUM_OF_LOG_LEVEL];
    CThreadMutex m_tThreadMutex;
};

#endif /* __LOGGER_H__ */

logger.cpp
/********************************************************************
    created:    2008/08/02
    filename:   logger.h    
    author:        Lichuang
                
    purpose:    實現簡易的log打印
********************************************************************
*/

#include 
"logger.h"
#include 
<sys/stat.h>

static const char* g_szLogSuffix[] = 
{
    
".debug",
    
".warn",
    
".error",
    
".info",
    NULL
};

CLogger::CLogger()
{
}

CLogger::
~CLogger()
{
}

int CLogger::Init(const string& strLogPath, const string& strFileName)
{
    m_strLogPath 
= strLogPath;
    m_strFileName 
= strFileName;

    
for (int i = DEBUG; i < NUM_OF_LOG_LEVEL; ++i)
    {
        m_szLogInfo[i].strFileSuffix 
= g_szLogSuffix[i];
        
if (0 > GetFileName(i))
            
return -1;
    }

    
return 0;
}

int CLogger::GetFileName(int nLogLevel)
{
    
int i;
    
string strFileName;
    
for (i = 0; i < MAX_FILE_NUM; ++i)
    {
        GenerateFileName(strFileName, i, nLogLevel);
        
if (!CheckFileSize(strFileName))
        {
            
break;
        }
    }

    
if (MAX_FILE_NUM == i)
    {
        
return -1;
    }

    m_szLogInfo[nLogLevel].nFileNum 
= i;
    m_szLogInfo[nLogLevel].strFileName 
= strFileName;

    
return 0;
}

int CLogger::CheckFileSize(const string& strFileName)
{
    
struct stat tStat;
    
int nRet = ::stat(strFileName.c_str(), &tStat);
    
if (0 == nRet && tStat.st_size > MAX_FILE_SIZE)
    {
        
return -1;
    }
    
else
    {
        
return 0;
    }
}

void CLogger::GenerateFileName(string& strFileName, int nFileNum, int nLogLevel)
{
    
char szFileNum[10];
    ::snprintf(szFileNum, 
sizeof(szFileNum), "_%02d", nFileNum);
    strFileName 
= m_strLogPath + m_strFileName + m_szLogInfo[nLogLevel].strFileSuffix + szFileNum;
}

int CLogger::Log(int nLogLevel, const char* pFileName, int nLine, const char *szFormat, )
{
    va_list ap;
    FILE 
*pFile;
    
char szTime[32];
    time_t nCurrTime;
    
struct tm stCurrTime;

    THREAD_LOCK(m_tThreadMutex);

    
if (0 > CheckFileSize(m_szLogInfo[nLogLevel].strFileName))
    {
        m_szLogInfo[nLogLevel].nFileNum 
= (m_szLogInfo[nLogLevel].nFileNum + 1% MAX_FILE_NUM;
        GenerateFileName(m_szLogInfo[nLogLevel].strFileName, m_szLogInfo[nLogLevel].nFileNum, nLogLevel);
    }

    
if(NULL == (pFile = ::fopen(m_szLogInfo[nLogLevel].strFileName.c_str(), "a+")))
    {
        
return -1;
    }

    ::time(
&nCurrTime);
    ::localtime_r(
&nCurrTime, &stCurrTime);
    ::snprintf(szTime, 
sizeof(szTime), "%d%02d%02d %02d:%02d:%02d",
            stCurrTime.tm_year
+1900, stCurrTime.tm_mon+1, stCurrTime.tm_mday,
            stCurrTime.tm_hour, stCurrTime.tm_min, stCurrTime.tm_sec);
    ::fprintf(pFile, 
"[%s]:[%s][%d] ", szTime, pFileName, nLine);

    ::va_start(ap, szFormat);
    ::vfprintf(pFile, szFormat, ap);
    ::va_end(ap);

    ::fprintf(pFile, 
"\n");
    ::fclose(pFile);

    THREAD_UNLOCK(m_tThreadMutex);

    
return 0;
}


posted on 2008-08-05 11:37 那誰 閱讀(3018) 評論(10)  編輯 收藏 引用 所屬分類: 服務器設計Linux/Unix

評論

# re: 服務器公共庫開發--log系統  回復  更多評論   

log rotate 最好能加一些可配置的策略,
如允許多少log文件,文件大小超過多少rotate,用戶可定義什么時間rotate,用戶可定義log可以生存多少時間自動刪除。
log 還可以加入模塊名的參數,有的時候只想log某些模塊。
2008-08-05 13:18 | lotus

# re: 服務器公共庫開發--log系統  回復  更多評論   

試試Log4吧,Log不用自己寫
2008-08-05 13:36 | 亨德列克

# re: 服務器公共庫開發--log系統  回復  更多評論   

@lotus
這幾個配置基本都有了,除了那個用戶定義生存時間的策略我沒有做之外.另外,log模塊也沒有實現.

2008-08-05 14:27 |

# re: 服務器公共庫開發--log系統  回復  更多評論   

@亨德列克
log4cpp吧?感覺有點大....
2008-08-05 14:28 |

# re: 服務器公共庫開發--log系統  回復  更多評論   

試試log4cxx,最近出了新版本.
采用log4系列是個很好的選擇,不用擔心功能不夠用,有各種語言的綁定,大不是問題,都是設設INCLUDE路徑,LIB路徑直接用就行了.
2008-08-05 20:10 | tangxinfa

# re: 服務器公共庫開發--log系統  回復  更多評論   

所謂的 log4cxx ,完全是照抄 JAVA 的理念做的不倫不類的東西。
語言的不同核心應該是理念的不同。
C/C++ 語言最好的 log 應該是 syslog ,完全現成,完全滿足需要,完全可配置,也完全符合 KISS 標準。
記住,每個程序,只做自己改做的事情,并把事情做好。
2008-08-06 10:37 | tangfl

# re: 服務器公共庫開發--log系統  回復  更多評論   

syslog和log4xx都是封裝好的東西,如果要知其所以然,還得我們親手實踐。
各個公司可能會需要在自己的業務需求上開發自己的log基盤,所以樓主的實踐頗具價值。
2008-08-06 13:00 | 金哥

# re: 服務器公共庫開發--log系統  回復  更多評論   

每次寫log都去檢查size會不會有影響呢?
2008-08-26 11:10 | haha

# re: 服務器公共庫開發--log系統[未登錄]  回復  更多評論   

言之有理,以后會進行優化,用一個成員變量去存放文件的大小, 每次程序初始化的時候讀取文件大小到這個成員中, 每次打印log之后更新, 而不是每次去檢查文件大小.
2008-08-26 12:13 |

# re: 服務器公共庫開發--log系統  回復  更多評論   

if (0 > CheckFileSize(m_szLogInfo[nLogLevel].strFileName))
{
m_szLogInfo[nLogLevel].nFileNum = (m_szLogInfo[nLogLevel].nFileNum + 1) % MAX_FILE_NUM;
GenerateFileName(m_szLogInfo[nLogLevel].strFileName, m_szLogInfo[nLogLevel].nFileNum, nLogLevel);
}

這里有問題吧,如果(m_szLogInfo[nLogLevel].nFileNum + 1) % MAX_FILE_NUM;這個log文件是回到0,這個文件肯定是已經達到最大存儲了,這時候還寫?
2009-03-03 20:55 | capable
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            99国产精品久久| 亚洲男同1069视频| 亚洲福利视频在线| 一区二区三区四区国产| 欧美成年人视频网站| 日韩午夜电影| 欧美寡妇偷汉性猛交| 激情自拍一区| 久久er精品视频| 午夜在线精品偷拍| 欧美另类高清视频在线| 亚洲全部视频| 欧美激情网友自拍| 美日韩精品视频免费看| 在线视频观看日韩| 亚洲高清自拍| 久久国产夜色精品鲁鲁99| 国产精品尤物福利片在线观看| 亚洲一区二区三区国产| 一片黄亚洲嫩模| 亚洲全部视频| 噜噜噜91成人网| 一区二区免费在线观看| 亚洲欧美日韩国产成人| 日韩一区二区高清| 欧美日韩高清在线播放| 亚洲精品日韩一| 一区二区三区久久精品| 精品不卡一区二区三区| 国产精品www.| 牛夜精品久久久久久久99黑人| 国语自产精品视频在线看一大j8| 久久久无码精品亚洲日韩按摩| 久久久不卡网国产精品一区| 亚洲福利视频二区| 亚洲另类视频| 国产精品一级二级三级| 久久国产一区| 久久久伊人欧美| 99riav国产精品| 亚洲一二三区在线| 一区二区在线观看视频| 亚洲三级视频| 国产精品久久久久久久午夜片 | 欧美成熟视频| 亚洲在线中文字幕| 久久xxxx| 亚洲人人精品| 亚洲一级电影| 好吊色欧美一区二区三区视频| 国内精品久久久久影院优 | 欧美激情第1页| 欧美日韩精品在线视频| 欧美在线日韩在线| 男男成人高潮片免费网站| 一区二区三区高清在线| 亚洲欧美日韩第一区| 亚洲国产精品久久久久| 中文av一区二区| 亚洲国产精品传媒在线观看 | 亚洲午夜在线视频| 亚洲综合99| 亚洲高清网站| 亚洲在线一区二区三区| 亚洲国内自拍| 亚洲欧美日韩精品久久久| 91久久精品国产91性色 | 国产日韩欧美高清| 性亚洲最疯狂xxxx高清| 99re8这里有精品热视频免费| 欧美日韩免费高清一区色橹橹| 亚洲国产日韩欧美在线99| 亚洲精品资源| 国产精品国产| 久久综合给合久久狠狠狠97色69| 亚洲校园激情| 欧美日本韩国在线| 日韩一本二本av| 亚洲欧美中文另类| 看片网站欧美日韩| 一区在线免费| 欧美伊人久久久久久午夜久久久久 | av成人免费在线观看| 亚洲三级电影全部在线观看高清| 国产精品99久久久久久宅男| 久久久久久穴| 欧美一二区视频| 欧美日韩综合| 一本久道久久综合婷婷鲸鱼| 免费视频一区| 久久福利精品| 在线成人国产| 亚洲欧美日韩专区| 亚洲精品国精品久久99热| 亚洲综合欧美| 亚洲欧美文学| 国产精品a级| 99成人在线| 亚洲级视频在线观看免费1级| 欧美日韩国产三级| 久久久久久久一区二区| 你懂的国产精品| 欧美成人午夜激情| 精品盗摄一区二区三区| 久久成人18免费网站| 性欧美18~19sex高清播放| 欧美日韩精品一区二区三区四区| 亚洲精品一区在线观看| 亚洲国产成人av好男人在线观看| 开心色5月久久精品| 国产精品ⅴa在线观看h| 欧美激情视频在线免费观看 欧美视频免费一| 免费在线播放第一区高清av| 久久午夜精品一区二区| 亚洲欧洲一二三| 免费观看日韩| 亚洲一区二区视频在线| 欧美一区二区三区视频免费播放| 久久综合精品国产一区二区三区| 性欧美精品高清| 最新中文字幕亚洲| 亚洲综合首页| 欧美一区二区免费观在线| 国产综合网站| 91久久中文| 久久av一区二区三区| 伊人久久综合97精品| 亚洲天堂av在线免费| 欧美午夜精品理论片a级大开眼界 欧美午夜精品理论片a级按摩 | 免播放器亚洲一区| 欧美国产丝袜视频| 欧美精品久久久久久久久久| 久久精品国产欧美亚洲人人爽| 欧美第一黄网免费网站| 国产一区二区三区自拍| 亚洲黄色成人| 欧美全黄视频| 西西裸体人体做爰大胆久久久| 久久久99久久精品女同性 | 国产精品久久久久久久午夜 | 久久亚洲综合网| 欧美精品免费视频| 欧美成人资源网| 午夜激情久久久| 国产精品毛片一区二区三区| 午夜精品亚洲| 国外精品视频| 欧美一区二区三区视频在线观看 | 欧美一级视频免费在线观看| 亚洲欧洲日韩在线| 午夜精品视频网站| 亚洲性夜色噜噜噜7777| 国产精品狠色婷| 亚洲欧美电影在线观看| 亚洲一区二区三区激情| 美女日韩欧美| 亚洲精品久久久久久久久| 国产精品综合视频| 欧美在线视频免费播放| 免费在线看成人av| 鲁大师成人一区二区三区 | 亚洲国产毛片完整版| 欧美成人精品h版在线观看| 国内揄拍国内精品久久| 久久亚洲精选| 蜜臀99久久精品久久久久久软件| 欧美高清不卡| 欧美成人精品一区二区三区| 欧美sm视频| 久久精品人人做人人综合 | 久久亚洲精品一区二区| 妖精视频成人观看www| 欧美在线播放| 久久er精品视频| 欧美精品激情在线| 亚洲激情国产精品| 一区二区欧美日韩视频| 欧美片在线播放| 欧美一区二区三区四区在线观看 | 久久综合久久综合这里只有精品| 欧美日韩一区三区| 久久夜色精品亚洲噜噜国产mv | 亚洲人成7777| 午夜精品久久久久久| 亚洲激情一区| 伊大人香蕉综合8在线视| 国产精品你懂的在线| 欧美三日本三级少妇三99| 免费视频亚洲| 激情婷婷欧美| 中国亚洲黄色| 99re成人精品视频| 欧美成人一区二区三区在线观看| 午夜影院日韩| 欧美色欧美亚洲另类二区 | 国产精品国产馆在线真实露脸| 国产精品每日更新| 欧美电影免费观看高清| 香蕉尹人综合在线观看| 亚洲影院色无极综合|