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%的代码。
少即是快,少即是多。
- Refine! Refine! Refine!
- RDF Refine(Open Refine + RDF Refine)使用笔记
- javascript代码Refine实例
- python代码refine实例
- C++代码Refine实例
- php代码refine实例
- sql refine实例
- AS3代码Refine实例
- BASH代码Refine实例
- 一个refine/refactor的例子
- angularjs代码refine,还是老一套
- Open Refine能学到什么
- 论文精读 Learning to Refine Object Segments
- 为什么x264_intra_rd_refine 相对x264_intra_rd 来说是个refine
- How to Refine the Log Retention Settings in XenServer
- 为什么x264_intra_rd_refine 相对x264_intra_rd 来说是个refine
- 介绍两款大数据清洗工具——DataWrangler、Google Refine
- How to refine C++ in a general way?
- 字符串例子收集---StringBuffer
- AVL Operation
- MERGE
- ByteArray的API
- 跨平台网络通讯要注意的地方
- Refine! Refine! Refine!
- DOS命令之net use命令详细解释
- Android:GPS卫星定位
- android in practice_SQLiteManager
- MAVEN配置文件pom.xml
- mysql字符串索引优化
- 数据库同步维护工具 for WPF MvvM
- const在函数声明中的应用-zt
- C语言宏的高级应用