zoukankan      html  css  js  c++  java
  • C++ 实现一个日志类

    转载:https://blog.csdn.net/baidu_41743195/article/details/107359665

    我们可能遇到发包后,在客户机器上出现各种未知错误,如果没有日志打印,对于问题解决是很困难的,因此常规的解决办法就是打印日志。

    在此用C++ 实现一个简单的日志类,使用cout输出调试信息,同时把日志写到文件中,实现了一个Logger类,主要考虑实现以下功能:

    • 日志等级: 参考python的logger类,我设置了四个日志等级, 从低到高依次为debug, info, warning, error,这样的话我想输出一条debug信息就可以这样写logger.debug("something..."), (关于日志等级是什么意思可以参考一下python的logger类,简单来说就是当日志等级大于等于设置的初始等级时才会记录日志)
    • 输出目标: 我设置了三种输出目标: 仅输出到终端、仅输出到文件、既输出到终端又输出到文件

    为了方便的设置日志等级,可以用一个枚举类表示四种日志等级,同理用一个枚举类表示三种输出目标

    enum log_level{debug, info, warning, error};// 日志等级
    enum log_target{file, terminal, file_and_terminal};// 日志输出目标

    Logger.h

    #ifndef _LOGGER_H_
    #define _LOGGER_H_
    
    #include <iostream>
    #include <fstream>
    #include <time.h>
    
    #pragma warning (disable:4996)
    
    class Logger
    {
    public:
        enum log_level { debug, info, warning, error };// 日志等级
        enum log_target { file, terminal, file_and_terminal };// 日志输出目标
    public:
        Logger();
        Logger(log_target target, log_level level, const std::string& path);
        ~Logger();
        
        void DEBUG(const std::string& text);
        void INFO(const std::string& text);
        void WARNING(const std::string& text);
        void ERRORS(const std::string& text);
    
    private:
        std::ofstream m_outfile;    // 将日志输出到文件的流对象
        log_target m_target;        // 日志输出目标
        std::string m_path;              // 日志文件路径
        log_level m_level;          // 日志等级
        void output(const std::string &text, log_level act_level);            // 输出行为
    };
    
    #endif//_LOGGER_H_

    Logger.cpp

    #include "Logger.h"
    #include <string>
    
    std::string currTime()
    {
        // 获取当前时间,并规范表示
        char tmp[64];
        time_t ptime;
        time(&ptime);  // time_t time (time_t* timer);
        strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S", localtime(&ptime));
        return tmp;
    }
    
    Logger::Logger()
    {
        // 默认构造函数
        m_target = terminal;
        m_level = debug;
        std::cout << /*"[WELCOME] " << __FILE__ << " " <<*/ currTime() << " : " << "=== Start logging ===" << std::endl;
    }
    
    
    Logger::Logger(log_target target, log_level level, const std::string& path)
    {
        m_target = target;
        m_path = path;
        m_level = level;
    
        std::string strContent =   currTime() + " : " + "=== Start logging ===
    ";
        if (target != terminal) {
            m_outfile.open(path, std::ios::out | std::ios::app);   // 打开输出文件
            m_outfile << strContent;
        }
        if (target != file) 
        {
            // 如果日志对象不是仅文件
            std::cout << strContent;
        }
    }
    
    Logger::~Logger()
    {
        std::string  strContent =  currTime() + " : " + "=== End logging ===
    ";
        if (m_outfile.is_open())
        {
            m_outfile << strContent;
        }
        m_outfile.flush();
        m_outfile.close();
    }
    
    void Logger::DEBUG(const std::string& text)
    {
        output(text, debug);
    }
    
    void Logger::INFO(const std::string& text)
    {
        output(text, info);
    }
    
    void Logger::WARNING(const std::string& text)
    {
        output(text, warning);
    }
    
    void Logger::ERRORS(const std::string& text)
    {
        output(text, error);
    }
    
    void Logger::output(const std::string &text, log_level act_level)
    {
        std::string prefix;
        if (act_level == debug) prefix = "[DEBUG] ";
        else if (act_level == info) prefix = "[INFO] ";
        else if (act_level == warning) prefix = "[WARNING] ";
        else if (act_level == error) prefix = "[ERROR] ";
        //else prefix = "";
        //prefix += __FILE__;
        //prefix += " ";
        std::string outputContent = prefix + currTime() + " : " + text + "
    ";
        if (m_level <= act_level && m_target != file) 
        {
            // 当前等级设定的等级才会显示在终端,且不能是只文件模式
            std::cout << outputContent;
        }
        if (m_target != terminal)
            m_outfile << outputContent;
    
        m_outfile.flush();//刷新缓冲区
    }

    测试

    #include "Logger.h"
    
    void test() {
        Logger logger(Logger::file_and_terminal, Logger::debug, "Log.log");
        logger.DEBUG("Debug info");
        logger.INFO("This is variable");
        logger.WARNING("This function or variable may be unsafe");
        logger.ERRORS("Memory leak");
    }
    
    int main()
    {
        test();
        getchar();
        return 0;
    }

     

  • 相关阅读:
    洛谷 P2053 :[SCOI2007]修车(拆点+最小费用流)
    LightOJ
    spark简单入门
    crontab 应用
    HttpClient的使用
    build.sbt的定义格式
    Scalatra
    SBT 构建scala eclipse开发
    mysql 存在更新,不存在插入
    Flash Vector例子
  • 原文地址:https://www.cnblogs.com/chechen/p/13893924.html
Copyright © 2011-2022 走看看