保存log时,根据不同级别采用不同颜色区分,文件保存为Html或者输出到控制台

来源:互联网 发布:婚恋网络的女嫌疑人图 编辑:程序博客网 时间:2024/05/22 05:08

为了保持可扩展性,将控制台颜色设置和保存文件颜色设置分别用两个头文件。
此外,因为log可能需要在整个工程的不同类中输出信息,因此将文件输出类中设计为静态数据成员,方便调用。
很简单,直接看代码吧。

#ifndef COUT_TO_FILE_H
#define COUT_TO_FILE_H

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

class CoutToFile
{
public:
    typedef enum { NONE= 0, DEBUG = 1, ERROR = 2,  FATAL= 3} LogLevels;
    static bool isCoutToFile;
    static ofstream ofObj;
    static streambuf* coutBuf;
    static streambuf* fileBuf;
    static void SaveLog(string info, LogLevels level);
};

#endif

设置输出到控制台的颜色,默认颜色是白色,可以根据需求cout时选择响应的颜色。
该段代码参考引用自:
http://wenku.baidu.com/view/6593f5631ed9ad51f01df2ae.html

#ifndef CONSOLE_COLORS_H
#define CONSOLE_COLORS_H
#include <iostream>
#include <windows.h>
using namespace std;
inline std::ostream& blue(std::ostream &s)
{
    HANDLE hStdout=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hStdout,FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_INTENSITY);
    return s;
}

inline std::ostream& red(std::ostream &s)
{
    HANDLE hStdout=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hStdout,FOREGROUND_RED|FOREGROUND_INTENSITY);
    return s;
}

inline std::ostream& green(std::ostream &s)
{
    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hStdout,FOREGROUND_GREEN|FOREGROUND_INTENSITY);
    return s;
}

inline std::ostream& yellow(std::ostream &s)
{
    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hStdout,FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY);
    return s;
}

inline std::ostream& white(std::ostream &s)
{
    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hStdout, FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
    return s;
}


#endif



#include "CoutToFile.h"
#include "ConsoleColor.h"

const string RED_BEGIN_TAG = "<span style=\"color: red;\">";
const string BLACK_BEGIN_TAG = "<span style=\"color: black;\">";
const string END_TAG = "</span>";
const string BR_TAG = "<br/>";

ofstream CoutToFile::ofObj;
streambuf* CoutToFile::coutBuf = cout.rdbuf();
streambuf* CoutToFile::fileBuf = CoutToFile::ofObj.rdbuf();
bool CoutToFile::isCoutToFile = false;

void CoutToFile::SaveLog(string info, LogLevels level)
{
    if(isCoutToFile)
    {
        if(level==3 /*FATAL*/ || level==2 /*ERROR*/)
        {
            cout<<RED_BEGIN_TAG<<endl;
        }
        else
        {
            cout<<BLACK_BEGIN_TAG<<endl;
        }

        cout<<info<<BR_TAG<<endl;

        cout<<END_TAG<<endl;
    }
    else
    {
        if( level== 2/*FATAL*/ || level==3 /*ERROR*/)
        {
            cout<<red<<info<<white<<endl;
        }
        else
        {
            cout<<white<<info<<endl;
        }
    }
}

注释:if语句中的enum类型比较,还有一点还有问题。采用整形比较没有问题,但是采用注释中的类型比较,就会进到错误的逻辑。目前还没有搞清楚。有清楚的同学请留言啊。



#include <iostream>
#include <fstream>
#include "CoutToFile.h"

using namespace std;

void SettingCout(string logSavePath, bool isSaveToFile)
{
    CoutToFile::isCoutToFile = isSaveToFile;

    if(CoutToFile::isCoutToFile)
    {
        CoutToFile::ofObj.open(logSavePath.c_str() /*, std::ofstream::app*/);
        cout.rdbuf(CoutToFile::fileBuf);
    }
    else
    {
        cout.rdbuf(CoutToFile::coutBuf);
    }
}

void ResetCout()
{
    if(CoutToFile::isCoutToFile)
    {
        cout.rdbuf(CoutToFile::coutBuf);
        CoutToFile::ofObj.close();
    }
}

int main(int argc, char* argv[])
{
    bool isCoutLogToFile = false;
    
    string logSavePath = "d:/Log.html";
    SettingCout(logSavePath, isCoutLogToFile);

    string name = "Name:Walle";
    string sex = "Sex: Male";
    string blog = "Blog:: http://blog.csdn.net/johnnyelf83";
    
    CoutToFile::SaveLog(name, CoutToFile::NONE);
    CoutToFile::SaveLog(sex, CoutToFile::NONE);
    CoutToFile::SaveLog(blog, CoutToFile::FATAL);
    
    ResetCout();

    system("PAUSE");
    return 0;
}




输出:
1. 设置输出到控制台:


2. 设置输出到html文件: