Refine! Refine! Refine!

来源:互联网 发布:新浪理财师抓计划数据 编辑:程序博客网 时间:2024/06/03 16:00

不会调试就不会写代码,不会Refine就不可能写出好代码!

Refine之前:

#ifndef RTMP_LOG_H#define RTMP_LOG_H#include <iostream>#include <string>#include <stdarg.h>using namespace std;#include <smt_public.hpp>#include <smt_log.hpp>#define ccrtmp_memset(str, n) memset(str, n, sizeof(str))namespace log{    typedef struct _LogFileStruct    {        string strLogFilePrefix;        string strLogFileEndfix;        _LogFileStruct()        {            strLogFilePrefix = "master";            strLogFileEndfix = "log";        }        void operator = (const _LogFileStruct& logFileStruct2)        {            strLogFilePrefix = logFileStruct2.strLogFilePrefix;            strLogFileEndfix = logFileStruct2.strLogFileEndfix;        }    }LogFileStruct;    typedef struct _RtmpLogFile    {        string strLogDir;        string strFileName;        int nRollFileSize;        int nFileKeepNum;        bool bIsUseConsole; // use stdout or stderr        bool bIsUseLogType;  // use log file        LogFileStruct logFileStruct;        _RtmpLogFile()        {            strLogDir = "/var/log/";            strFileName = "master.00.log";            nRollFileSize = 50 * 1024 * 1024; // cut log file when file is 50M            nFileKeepNum = 15;            bIsUseConsole = false;            bIsUseLogType = true;        }        void operator = (const _RtmpLogFile& rtmpLogFile2)        {            strLogDir = rtmpLogFile2.strLogDir;            strFileName = rtmpLogFile2.strFileName;            nRollFileSize = rtmpLogFile2.nRollFileSize;            nFileKeepNum = rtmpLogFile2.nFileKeepNum;            bIsUseConsole = rtmpLogFile2.bIsUseConsole;            bIsUseLogType = rtmpLogFile2.bIsUseLogType;            logFileStruct = rtmpLogFile2.logFileStruct;        }        // TODO: add check valid. eg. "//" in logDir    }RtmpLogFile;    class CRtmpLog : public ILog    {    private:        bool initialized;    public:        CRtmpLog();        virtual ~CRtmpLog();    public:        virtual int Initialize(int log_to, std::string filename, int level);        int Debug(const char* fmt, ...);        int Trace(const char* fmt, ...);        int Warn(const char* fmt, ...);        int Error(const char* fmt, ...);        int Fatal(const char* fmt, ...);    private:        /**         * 1. set dir which be saved for log files         * 2. set file name for log file         * 3. set file size for rolling         * 4. set time of keep for log files         * 5. set using console true or false to output to stdout         * 6. set using log file true or false to output to files         * LogLevel default is LogLevel::Trace         * return 0 if set success         **/        int  LogFilePropertySet(RtmpLogFile& rtmpLogFile, unsigned long LogLevel = LogLevel::Trace);        void LogSetLevels(int Loglevel);    private:        /*        *  // parse file name and get prefix of log file, endfix of log file.        *  // seccuss : return 0; failed : return -1        */        int LogNamePasre();        int logformat(bool bIsError, const char* pLogLevlInfo, const char* fmt, va_list args);        // file log function         void LogFileLock();        void LogFileUnLock();    private:        RtmpLogFile m_rtmpLogFile;        int m_LogLevel;        FILE  *m_fdLog;    };}#endif

#include <smt_stdinc.hpp>#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <time.h>#include <inttypes.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <stdarg.h>#include <sys/file.h>//#include <iostream>//#include <string>#include <smt_log_simple_log.hpp>using namespace log;#include <smt_error_code.hpp>using namespace core;typedef struct stat     stbuf;CRtmpLog::CRtmpLog(){    m_fdLog  = NULL;    m_LogLevel = LogLevel::Trace;    initialized = false;}CRtmpLog::~CRtmpLog(){    if(m_fdLog != NULL)    {        fclose(m_fdLog);        m_fdLog = NULL;    }}int CRtmpLog::Initialize(int log_to, std::string filename, int level){    RtmpLogFile log_file;    log_file.bIsUseConsole = (log_to == LogTank::Console);    log_file.bIsUseLogType = !log_file.bIsUseConsole;    log_file.strFileName = filename;    initialized = true;    return LogFilePropertySet(log_file, level);}/** * 1. set dir which be saved for log files * 2. set file name for log file * 3. set file size for rolling * 4. set time of keep for log files * LogLevel default is LogLevel::Trace * return 0 if set success **/int CRtmpLog::LogFilePropertySet(RtmpLogFile& rtmpLogFile, unsigned long LogLevel){    if(m_fdLog != NULL)    {        fclose(m_fdLog);        m_fdLog = NULL;    }    //printf("Console : %s \n", (rtmpLogFile.bIsUseConsole) ? "true" : "false");    //printf("LogType : %s \n", (rtmpLogFile.bIsUseLogType) ? "true" : "false");    //if( m_rtmpLogFile.bIsUseConsole == false && m_rtmpLogFile.bIsUseLogType == false)    if( rtmpLogFile.bIsUseConsole == rtmpLogFile.bIsUseLogType)    {        fprintf(stderr, "Both bIsUseConsole and bIsUseLogType could not set to the same value.\n");        return -1;    }    m_rtmpLogFile = rtmpLogFile;    m_LogLevel = LogLevel;    // TODO : trim "/" of string's end    // TODO : check log file size    if(m_rtmpLogFile.bIsUseLogType)    {        if (LogNamePasre() != 0)        {            fprintf(stderr, "log file name in configration is error.\n");            return -1;        }        string strFileNameWithPath = m_rtmpLogFile.strLogDir + "/" + m_rtmpLogFile.strFileName;        if( (m_fdLog = fopen(strFileNameWithPath.c_str(), "a+b")) == NULL)        {            fprintf(stderr, "open file failed, errno is %d - %s\n", errno, strerror(errno));            return -1;        }    }    return 0;}void CRtmpLog::LogFileLock(){    if(m_fdLog != NULL)    {        flock(fileno(m_fdLog), LOCK_EX);    }}void CRtmpLog::LogFileUnLock(){    if(m_fdLog != NULL)    {        flock(fileno(m_fdLog), LOCK_UN);    }}void CRtmpLog::LogSetLevels(int Loglevel){    m_LogLevel = Loglevel;}/**  // parse file name and get prefix of log file, endfix of log file.*  // seccuss : return 0; failed : return -1*/int CRtmpLog::LogNamePasre(){    string strPareseTmp = m_rtmpLogFile.strFileName;    string strPareseTmp2 = m_rtmpLogFile.strFileName;    unsigned long long unNumPos = strPareseTmp.find(".00.");    //size_type unNumPos = strPareseTmp.find(".00.");    if( unNumPos != string::npos)    {        strPareseTmp.erase(unNumPos);        m_rtmpLogFile.logFileStruct.strLogFilePrefix = strPareseTmp;        strPareseTmp2.erase(0, unNumPos + strlen(".00."));        m_rtmpLogFile.logFileStruct.strLogFileEndfix = strPareseTmp2;        fprintf(stdout, "m_logFilePrefix : %s, m_logFileEndFix : %s.\n",                 m_rtmpLogFile.logFileStruct.strLogFilePrefix.c_str(),                 m_rtmpLogFile.logFileStruct.strLogFileEndfix.c_str());        return 0;    }    // log name invalid.    return -1;    }/**string CRtmpLog::FileNumAddOne(string &strFileName, string strFindNum){    string strFTmp = strFileName;    unsigned int lPointPos = strFTmp.find(strFindNum);    if( lPointPos != string::npos )    {                unsigned int rPointPos = strFTmp.rfind(".log");    }}**/int CRtmpLog::Debug(const char* fmt, ...){    if(!initialized){        return ErrorCode::SystemLogUnInitialized;    }        int nStrLenth = 0;    if(m_LogLevel > LogLevel::Debug)    {        return 0;    }    va_list arg_list;    va_start(arg_list, fmt);    nStrLenth = logformat(false, "debug", fmt, arg_list);    va_end(arg_list);    return ErrorCode::Success;}int CRtmpLog::Trace(const char* fmt, ...){    if(!initialized){        return ErrorCode::SystemLogUnInitialized;    }        int nStrLenth = 0;    if(m_LogLevel > LogLevel::Trace)    {        return 0;    }    va_list arg_list;    va_start(arg_list, fmt);    nStrLenth = logformat(false, "trace", fmt, arg_list);    va_end(arg_list);    return ErrorCode::Success;}int CRtmpLog::Warn(const char* fmt, ...){    if(!initialized){        return ErrorCode::SystemLogUnInitialized;    }        int nStrLenth = 0;    if(m_LogLevel > LogLevel::Warn)    {        return 0;    }    va_list arg_list;    va_start(arg_list, fmt);    nStrLenth = logformat(false, "warning", fmt, arg_list);    va_end(arg_list);    return ErrorCode::Success;}int CRtmpLog::Error(const char* fmt, ...){    if(!initialized){        return ErrorCode::SystemLogUnInitialized;    }        int nStrLenth = 0;    va_list arg_list;    va_start(arg_list, fmt);    nStrLenth = logformat(true, "error", fmt, arg_list);    va_end(arg_list);    return ErrorCode::Success;}int CRtmpLog::Fatal(const char* fmt, ...){    if(!initialized){        return ErrorCode::SystemLogUnInitialized;    }        int nStrLenth = 0;    va_list arg_list;    va_start(arg_list, fmt);    nStrLenth = logformat(true, "fatal", fmt, arg_list);    va_end(arg_list);    return ErrorCode::Success;}/*** bIsError : true - need output error info, or set to false.* pLogLevlInfo : set print log level info**/int CRtmpLog::logformat(bool bIsError, const char* pLogLevlInfo, const char* fmt, va_list args){    int nStrLenth = 0;    char cTime[128];    memset(cTime, 0, sizeof(cTime));    struct tm *newtime;    time_t lt;    time(<);    newtime = localtime(<);    strftime(cTime, 128, "[%Y-%m-%d %H:%M:%S]", newtime);    FILE *fpTemp = NULL;    if(m_rtmpLogFile.bIsUseLogType)    {// print to log files        //flock(fileno(m_fdLog), LOCK_EX | LOCK_NB);        fpTemp = m_fdLog;    }    else    {// print to stdout        fpTemp = stdout;    }    fprintf(fpTemp, "%s %d [%s] ", cTime, getpid(), pLogLevlInfo);    nStrLenth = vfprintf(fpTemp, fmt, args);    if( bIsError)    {        fprintf(fpTemp, " | errno : %d (Hex : 0x%X) - %s", errno, errno, strerror(errno));    }    fprintf(fpTemp, "\n");    // unlock file    if(m_rtmpLogFile.bIsUseLogType)    {        fflush(m_fdLog);        LogFileUnLock();    }    return nStrLenth;}

Refine之后:

/*** This file is part of SmartServer.* Copyright(c) 2012 by ChinaCache.com * All rights reserved. ** Author*      - chengli.yang <chengli.yang>*/#ifndef smt_log_fast_log_hpp#define smt_log_fast_log_hpp#include <smt_public.hpp>#include <string>#include <smt_log.hpp>namespace log{    /**    * we use memory/disk cache and donot flush when write log.    */    class FastLog : public ILog    {    private:        // defined in LogTank.        int tank;        // defined in LogLevel.        int level;        // if tank specified the File, write to this file.        std::string filename;    private:        int fd;        // log_body to store the log message body.        char* log_body;        // log_header to store the log header.        char* log_header;    private:        CopyConstructor(FastLog);    public:            FastLog();        virtual ~FastLog();    public:        virtual int Initialize(int log_to, std::string filename, int level);    public:        virtual int Debug(const char* fmt, ...);        virtual int Trace(const char* fmt, ...);        virtual int Warn(const char* fmt, ...);        virtual int Error(const char* fmt, ...);        virtual int Fatal(const char* fmt, ...);    private:        inline int DoLog(const char* level_name, int log_size);        inline int WriteLog(char* str_log, int size);    };}#endif

#include <smt_stdinc.hpp>#include <unistd.h>#include <stdio.h>#include <assert.h>#include <string.h>#include <errno.h>#include <stdarg.h>#include <sys/time.h>#include <fcntl.h>#include <sys/stat.h>#include <sys/types.h>using namespace std;#include <smt_log_fast_log.hpp>using namespace log;#define LogBufferSize 4096FastLog::FastLog(){    tank = LogTank::Console;    level = LogLevel::Trace;    fd = -1;        log_body = SmtNewArr(char, LogBufferSize);    log_header = SmtNewArr(char, LogBufferSize);}FastLog::~FastLog(){    SmtFree(char, log_body, true);    SmtFree(char, log_header, true);        if(fd != -1){        close(fd);        fd = -1;    }}int FastLog::Initialize(int log_to, std::string filename, int level){    this->tank = log_to;    this->filename = filename;    this->level = level;        if(fd != -1){        close(fd);        fd = -1;    }        // if log to file, open the file.    if((tank & LogTank::File) == LogTank::File){        fd = open(filename.c_str(), O_RDWR | O_APPEND);                if(fd == -1 && errno == ENOENT){            fd = open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);        }                if(fd == -1){            return ErrorCode::SystemLogOpenError;        }    }        return ErrorCode::Success;}int FastLog::Debug(const char* fmt, ...){    if(level > LogLevel::Debug){        return ErrorCode::Success;    }        va_list ap;        va_start(ap, fmt);    int size = vsnprintf(log_body, LogBufferSize, fmt, ap);    va_end(ap);    return DoLog("debug", size);}int FastLog::Trace(const char* fmt, ...){    if(level > LogLevel::Trace){        return ErrorCode::Success;    }        va_list ap;        va_start(ap, fmt);    int size = vsnprintf(log_body, LogBufferSize, fmt, ap);    va_end(ap);    return DoLog("trace", size);}int FastLog::Warn(const char* fmt, ...){    if(level > LogLevel::Warn){        return ErrorCode::Success;    }        va_list ap;        va_start(ap, fmt);    int size = vsnprintf(log_body, LogBufferSize, fmt, ap);    va_end(ap);    return DoLog("warn", size);}int FastLog::Error(const char* fmt, ...){    if(level > LogLevel::Error){        return ErrorCode::Success;    }        va_list ap;        va_start(ap, fmt);    int size = vsnprintf(log_body, LogBufferSize, fmt, ap);    va_end(ap);    return DoLog("error", size);}int FastLog::Fatal(const char* fmt, ...){    va_list ap;        va_start(ap, fmt);    int size = vsnprintf(log_body, LogBufferSize, fmt, ap);    va_end(ap);    return DoLog("fatal", size);}int FastLog::DoLog(const char* level_name, int log_size){    int ret = ErrorCode::Success;        // check log format specified by size.    if(log_size == -1){        return ErrorCode::SystemLogFormatError;    }    // no content.    if(log_size == 0){        return ret;    }        // clock time    timeval tv;    if(gettimeofday(&tv, NULL) == -1){        return ErrorCode::SystemLogTimeError;    }    // to calendar time    struct tm* tm;    if((tm = localtime(&tv.tv_sec)) == NULL){        return ErrorCode::SystemLogTimeError;    }        // log header, the time/pid/level of log    int log_header_size = snprintf(log_header, LogBufferSize, "\n[%d-%02d-%02d %02d:%02d:%02d.%03d] %d [%s] ",         1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,         (int)(tv.tv_usec / 1000), getpid(), level_name);        // write log now    if((ret = WriteLog(log_header, log_header_size)) != ErrorCode::Success){        return ret;    }    // the last char is a newline char.    if((ret = WriteLog(log_body, log_size)) != ErrorCode::Success){        return ret;    }        return ret;}int FastLog::WriteLog(char* str_log, int size){    int ret = ErrorCode::Success;        if((tank & LogTank::Console) == LogTank::Console){        printf(str_log);    }        if((tank & LogTank::File) == LogTank::File && fd != -1){        write(fd, str_log, size);    }        return ret;}


因为很多功能,经过一段时间,已经和最初的样子不一样了,必须要Refine。

[winlin@dev6 log]$ ls *simple*|xargs wc -l  307 smt_log_simple_log.cpp  130 smt_log_simple_log.hpp  437 total[winlin@dev6 log]$ ls *fast*|xargs wc -l 183 smt_log_fast_log.cpp  56 smt_log_fast_log.hpp 239 total[winlin@dev6 log]$ 

此次Refine减少代码198行,减少45%的代码。

少即是快,少即是多。

原创粉丝点击