日志系统我认为越小越好,完成记录后再用其它工具来查看比较好。 以下是一个简单的例子,实现了:把日志记录到xml文件中,把xml转换成html excel 来查看。包括。logFile.h logFile.cpp LogViewer.h LogViewer.cpp类,还有一个logManager主类:
LogFile.h在这个类中定义了对接口的宏,只要用这些宏就可以了
#pragma once

#include <vector>
#include <fstream>
#include <string>
#include <map>
#include <stdarg.h>
#include <stdio.h>


//#include <Windows.h>
#define Log_Init logfile.init//Log_Init ("const log file name"); //call when main function start
#define Log_TF(var_1) TrackF obj____unique_name(var_1)//Log_TF ("const function name "); //or operator namespace //call in every function first line to track the stack
#define Log_TFTOP Log_TF("CONVERTS")
#define Log_Message logfile.writeMessage//logfile.drawMessage//OutputDebugString// Log_Message( priority,string message); //call in any function
#define Log_Update logfile.updata//Log_Update() //call before convert a image
#define Log_End logfile.term //Log_End() //call when the main function end
#define Log_XML_TO_EXCEL logfile.change_xml_to_excel //Log_XML_TO_EXCEL( "xmlfileName","excelfileName")
#define Log_XML_TO_HTML logfile.change_xml_to_html //Log_XML_TO_HTML("xmlfileName","htmlfileName");
// "stack" typedef
#define endl ' '

typedef enum _PRIORITY_OP //for priority

...{
MES_ERROR,
MES_WARNING,
MES_PARAMETER, // your can write parameter 's value
MES_INPUT_IMAGE, //for input name and output name ,
MES_OUTPUT_IMAGE, //for output name
MES_DESCRIPTION //write some other message
}PRIORITY_OP ;
#ifdef UNICODE
typedef std::wstring String;
#else
typedef std::string String;
#endif

typedef std::vector<const String> CharPtrVec;
const int INDENT =4;
const int MAX_DEBUG_LINE_LEN=1024;
class TrackF

...{
public:
TrackF(const String name);
~TrackF(void);
};
class LogFile

...{


//~LogFile(void);
public:
LogFile(void);
void init(const String logfilename);
void drawMessage(PRIORITY_OP type,String message);
void writeMessage(PRIORITY_OP type,const char* format, ...);
void writeInstruction(char* instruction, ...);
void writeStartNode(String functionName);//just write node
void writeEndNode(String functionName);//just write node
void pushStack(const String name);
void popStack();
void term(void);
void updata(void);
//call after term to close the file
bool change_xml_to_excel(String xmlfilename,String excelFileName);
bool change_xml_to_html(String xmlfilename,String excelfilename);

private:
void drawTable(void);//just draw a table space
void drawSubTable(void);
void addTableCount(void); //just add the count
void reduceTableCount(void); //just reduce the count

bool isInit(void)...{return m_initialized;}


private:

//FILE* m_file;
unsigned int tableCount;
std::fstream m_file;
CharPtrVec m_callStack; //function stack
bool m_loggedEvent;
unsigned int m_previousStackLevel;
unsigned int m_updateCount; //a convert a update
bool m_initialized; //the log be initialized?
};
//extern LogFile logfile;

extern LogFile logfile;
LogFile.cpp:
#include "StdAfx.h"
#include ".logfile.h"
#include <assert.h>
#include "LogViewer.h"



LogFile logfile;
TrackF::TrackF(const String name)

...{
logfile.pushStack(name);
}
TrackF::~TrackF()

...{
logfile.popStack();
}
LogFile::LogFile(void)

...{
tableCount=0;
// m_file=0;
m_updateCount = 0;
m_loggedEvent = false;
m_initialized = false;
m_previousStackLevel = 0;
m_callStack.reserve(32); //分配空间
}

//LogFile::~LogFile(void)
//{
//}
void LogFile::init(const String logfilename)

...{
if(isInit())
return;
m_file.open(logfilename.c_str(),std::ios_base::out);// i just want to creat a logfile,or replace the logfile
m_initialized=true;
//<?xml version="1.0"?>
writeInstruction("xml version="1.0"");
}
void LogFile::drawTable()

...{
for(int i=0;i<tableCount;i++)

...{
m_file<<" ";
}
}
void LogFile::drawSubTable()//for message

...{
drawTable();
for(unsigned int i=0;i<INDENT;i++)
m_file<<" ";
}
void LogFile::drawMessage(PRIORITY_OP type,String message)

...{
//drawSubTable();
drawTable();
switch(type)

...{
case MES_INPUT_IMAGE:
m_file<<"<IN_IMAGE>"<<message<<"</IN_IMAGE>"<<' ';
break;
case MES_OUTPUT_IMAGE:
m_file<<"<OUT_IMAGE>"<<message<<"</OUT_IMAGE>"<<' ';
break;
case MES_PARAMETER:
m_file<<"<Message priority="PARAMETER">"<<message<<"</Message>"<<' ';
break;
case MES_ERROR:
m_file<<"<Message priority="ERROR">"<<message<<"</Message>"<<' ';
break;
case MES_WARNING:
m_file<<"<Message priority="WARNING">"<<message<<"</Message>"<<' ';
break;
case MES_DESCRIPTION:
m_file<<"<Message priority="DESCRIPTION">"<<message<<"</Message>"<<' ';
break;
}
m_file.flush();
}
void LogFile::writeInstruction(char* instruction, ...)

...{
if(!isInit())
return;
char buffer[MAX_DEBUG_LINE_LEN];
va_list args;
va_start(args, instruction);

int buf = _vsnprintf(buffer, MAX_DEBUG_LINE_LEN, instruction, args);

assert((buf >= 0) && (buf < MAX_DEBUG_LINE_LEN));
va_end(args);

String str(buffer);
m_file<<"<?"<<str<<"?>"<<endl;
m_file.flush();
}
void LogFile::writeStartNode(String functionName)//just write node

...{
drawTable();
m_file<<"<"<<functionName<<">"<<endl;
}
void LogFile::writeEndNode(String functionName)//just write node

...{
drawTable();
m_file<<"</"<<functionName<<">"<<endl;
}
void LogFile::pushStack(const String name)

...{
m_callStack.push_back(name);
writeStartNode(name);
addTableCount();
m_file.flush();
}
void LogFile::popStack()

...{
int index=m_callStack.size();
//if(index>0)
assert( index>0);
reduceTableCount();
writeEndNode(m_callStack[index-1]);
updata();
m_callStack.pop_back();
//updata();
}


void LogFile::addTableCount(void) //just add the count

...{
tableCount+=INDENT;
}
void LogFile::reduceTableCount(void) //just reduce the count

...{
tableCount-=INDENT;
}
bool LogFile::change_xml_to_html(String xmlfilename,String htmlfilename)

...{
LogViewer logviewer(xmlfilename);
logviewer.m_To_Html(htmlfilename,"CONVERT");//logviewer.m_To_Html(htmlfilename,"CONVERT","","","","");
return true;
}
bool LogFile::change_xml_to_excel(String filename,String filename2)

...{
LogViewer logviewer(filename);
logviewer.m_To_Excel(filename2);
return true;
}
void LogFile::term(void)

...{
m_file.flush();
m_file.close();
}
void LogFile::updata(void)

...{
m_file.flush();
}
void LogFile::writeMessage(PRIORITY_OP type,const char* format, ...)

...{
if(!isInit())
return;
char buffer[MAX_DEBUG_LINE_LEN];
va_list args;
va_start(args, format);

int buf = _vsnprintf(buffer, MAX_DEBUG_LINE_LEN, format, args);

assert((buf >= 0) && (buf < MAX_DEBUG_LINE_LEN));
va_end(args);

String str(buffer);
drawMessage(type,str);
}



LogViewer.h:
#pragma once
#include <vector>
#include <string>
#include <Windows.h>
#include <fstream>
#include <iostream>


#if !defined(__MSXML3__)

#define __MSXML3__

#import "msxml3.dll"

#endif

#ifdef UNICODE
typedef std::wstring String;
#else
typedef std::string String;
#endif


typedef struct _NodeItem

...{
String mNodeName;
String mText;
std::vector<_NodeItem> mChildNodes;
std::vector<_NodeItem> mAttributes;
}NodeItem;


class XMLLoader

...{
public:
XMLLoader(void);
public:
~XMLLoader(void);
public:
int loadFile(String fileName);
private:
int readNode(MSXML2::IXMLDOMNodePtr& element, NodeItem& node);
NodeItem& getRoot()

...{
return mRoot;
}

protected:
NodeItem mRoot;

protected:
int resetTree(NodeItem& node);
};
//const int AINDENENT=4;
class LogViewer:XMLLoader

...{
public:
LogViewer(const String xmlFileName);
~LogViewer(void);
int indent;
bool m_To_Excel(String excelFileName);
bool m_To_Html(String htmlfileName,String LevelNodeName,String nodeName="",String nodetext="",String attributeName="",String attributeValue="");


/**////std::fstream m_file;

//返回一个指针链表,指向所有符合条件Node(在同一深度上的)的指针 LevelNodeName限定了返回Node的深度,以后是条件
void findNode(std::vector<NodeItem*> &resultNodes,NodeItem& node,String LevelNodeName,String nodeName,String nodetext,String attribute,String attributeValue);//这是过程不新创建内存
private:
void findNode(std::vector<NodeItem*> &resultNodes,NodeItem& node,String LevelNodeName);//
bool isNodeMatch(NodeItem &node,String nodeName,String text,String attribute,String attributeValue);
void isSubNodeMatch(NodeItem &INnode,bool &out,String nodeName,String text,String attribute,String attributeValue);
bool findMessage(NodeItem &node,String attributeName,String attributeValue,String &result);//return all the string to result
void parsingXML(NodeItem &node,std::fstream &m_file);
void drawATable(int count,std::fstream &m_file);
void writeExcelHead(std::fstream &m_file);
void writeExcelStyles(std::fstream &m_file);
void setExcelWidth(std::fstream &m_file);

/**///////////////////////////////////////////////////////////////////////////html
protected:
virtual void wirte_noe_html(NodeItem &node,std::fstream &file);
private:
String setFont(String face,String size,String color,String &str);
};

LogViewer.cpp