zoukankan      html  css  js  c++  java
  • 一个简单的日志类的开发

    前段时间,由于工作需要,需开发一个新的日志类,要求将服务端所处理的有关同一个请求的所有日志全部记录在一个json中,以方便日志收集与查询、分析。像以前那样处理到某一步打印一条日志的方式便不再可行了。

    一个请求由于中间有好多处理过程,而且不尽相同,要求将这些处理产生的日志都打印在一起,最先想到的自然就是设计一个新的日志类,里边有一个buffer,在收到请求时创建一个该类的对象,然后所有的请求日志都通过该类写入buffer,而实际写入日志文件则是在该类的析构函数中进行,也就达到了一次性写入的目的。

      

    //请求日志记录类,每条请求添加一条日志记录的对象
    class RequestLogger
    {
    public:
        enum LogLevel
        {
            TRACE = 0,
            DEBUG,
            INFO,
            WARN,
            ERROR,
            NUM_LOG_LEVELS
        };
        
        ~RequestLogger()
        {
            Json::FastWriter writer;
            std::string &&s = writer.write(m_value);
            LoggerWriter::getLoggerWriter().write(s);
        }
    
        RequestLogger& operator <<(std::string s)
        {
            if(s.size() != 0)
                m_buf.append(s);
            return *this;
        }
        RequestLogger& operator <<(int i)
        {
            try
            {
                std::string tmp = boost::lexical_cast<std::string>(i);
                return *this << tmp;
            }catch(boost::bad_lexical_cast& e)
            {
                return *this;
            }
            
        }
    
        void addLog(LogLevel level, const char* filename, const int line)
        {
            Json::Value tmp;
            const char* slash = strrchr(filename, '/');
            if(!slash)
                slash = filename;
            else
                slash++;
            tmp["file"] = slash;
            tmp["line"] = line;
            struct timeval tv;
            gettimeofday(&tv, NULL);
            int64_t seconds = tv.tv_sec + 8*3600; //    UTC + 8.0
            char buf[32] = {0};
            struct tm tm_time;
            gmtime_r(&seconds,&tm_time);
            snprintf(buf, sizeof(buf), "%4d-%02d-%02d %02d:%02d:%02d.%06d",
                 tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday,
                 tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec,
                 tv.tv_usec);
            tmp["time"] = std::string(buf);
            tmp["content"] = m_buf;
            switch(level)
            {
                case TRACE:
                    tmp["level"] = "TRACE";
                    break;
                case DEBUG:
                    tmp["level"] = "DEBUG";
                    break;
                case INFO:
                    tmp["level"] = "INFO";
                    break;
                case WARN:
                    tmp["level"] = "WARN";
                    break;
                case ERROR:
                    tmp["level"] = "ERROR";
                    break;
            }
            m_value["processlog"].append(tmp);
            m_buf = "";
            
        }
        
    private:
        std::string m_buf;
        Json::Value m_value;
    };

    通过重载operator << 操作符,对日志写入进行了方便对日志进行写入,然后,再定义addLog函数,将buf中的内容转换到json变量中,最后在析构时调用LoggerWriter单例类去写入日志文件。为方便使用,定义以下宏来使用。

    #define REQUEST_TRACE(logger_ptr, logstream) ((*logger_ptr) << logstream).addLog(RequestLogger::LogLevel::TRACE, __FILE__, __LINE__);
    #define REQUEST_DEBUG(logger_ptr, logstream) ((*logger_ptr) << logstream).addLog(RequestLogger::LogLevel::DEBUG, __FILE__, __LINE__);
    #define REQUEST_INFO(logger_ptr, logstream) ((*logger_ptr) << logstream).addLog(RequestLogger::LogLevel::INFO, __FILE__, __LINE__);
    #define REQUEST_WARN(logger_ptr, logstream) ((*logger_ptr) << logstream).addLog(RequestLogger::LogLevel::WARN, __FILE__, __LINE__);
    #define REQUEST_ERROR(logger_ptr, logstream) ((*logger_ptr) << logstream).addLog(RequestLogger::LogLevel::ERROR, __FILE__, __LINE__);

    记录日志使用如下:

    std::shared_ptr<RequestLogger> ptr_logger(new RequestLogger());
    REQUEST_INFO(ptr_logger, "基本预处理后: " << tmp_query);

    还是蛮方便的。

  • 相关阅读:
    TortoiseSVN 命令 (命令行执行工具)(转)
    express blend下载
    js绝对地址图片转换成base64的方法
    js判断是否安装flash player及当前版本 和 检查flash版本是否需要升级
    js实现默认或者触发一个事件选中元素内容的方法
    js实现复制功能,将需要复制的内容放入剪切板上
    前端js上传文件插件
    javascript检测浏览器的缩放状态实现代码 是指浏览器网页内容的百分比缩放(按Ctrl和+号键或者-号键的缩放)
    html5 canvas 画图移动端出现锯齿毛边的解决方法
    jquery实现全选/反选功能
  • 原文地址:https://www.cnblogs.com/yutongqing/p/6667261.html
Copyright © 2011-2022 走看看