日志系统我认为越小越好,完成记录后再用其它工具来查看比较好。 以下是一个简单的例子,实现了:把日志记录到xml文件中,把xml转换成html excel 来查看。包括。logFile.h logFile.cpp LogViewer.h LogViewer.cpp类,还有一个logManager主类:
LogFile.h在这个类中定义了对接口的宏,只要用这些宏就可以了
#pragma
once
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#include
<
vector
>
#include
<
fstream
>
#include
<
string
>
#include
<
map
>
#include
<
stdarg.h
>
#include
<
stdio.h
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
//
#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 ' '
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
typedef
enum
_PRIORITY_OP
//
for priority
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
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
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
typedef std::vector
<
const
String
>
CharPtrVec;
const
int
INDENT
=
4
;
const
int
MAX_DEBUG_LINE_LEN
=
1024
;
class
TrackF
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public:
TrackF(const String name);
~TrackF(void);
}
;
class
LogFile
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//~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);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
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
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
bool isInit(void)...{return m_initialized;}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
private:
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//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
"
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
LogFile logfile;
TrackF::TrackF(
const
String name)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
logfile.pushStack(name);
}
TrackF::
~
TrackF()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
logfile.popStack();
}
LogFile::LogFile(
void
)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
tableCount=0;
// m_file=0;
m_updateCount = 0;
m_loggedEvent = false;
m_initialized = false;
m_previousStackLevel = 0;
m_callStack.reserve(32); //分配空间
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
//
LogFile::~LogFile(void)
//
{
//
}
void
LogFile::init(
const
String logfilename)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
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()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
for(int i=0;i<tableCount;i++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
m_file<<" ";
}
}
void
LogFile::drawSubTable()
//
for message
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
drawTable();
for(unsigned int i=0;i<INDENT;i++)
m_file<<" ";
}
void
LogFile::drawMessage(PRIORITY_OP type,String message)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
//drawSubTable();
drawTable();
switch(type)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
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, ...)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
if(!isInit())
return;
char buffer[MAX_DEBUG_LINE_LEN];
va_list args;
va_start(args, instruction);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
int buf = _vsnprintf(buffer, MAX_DEBUG_LINE_LEN, instruction, args);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
assert((buf >= 0) && (buf < MAX_DEBUG_LINE_LEN));
va_end(args);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
String str(buffer);
m_file<<"<?"<<str<<"?>"<<endl;
m_file.flush();
}
void
LogFile::writeStartNode(String functionName)
//
just write node
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
drawTable();
m_file<<"<"<<functionName<<">"<<endl;
}
void
LogFile::writeEndNode(String functionName)
//
just write node
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
drawTable();
m_file<<"</"<<functionName<<">"<<endl;
}
void
LogFile::pushStack(
const
String name)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
m_callStack.push_back(name);
writeStartNode(name);
addTableCount();
m_file.flush();
}
void
LogFile::popStack()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int index=m_callStack.size();
//if(index>0)
assert( index>0);
reduceTableCount();
writeEndNode(m_callStack[index-1]);
updata();
m_callStack.pop_back();
//updata();
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
LogFile::addTableCount(
void
)
//
just add the count
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
tableCount+=INDENT;
}
void
LogFile::reduceTableCount(
void
)
//
just reduce the count
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
tableCount-=INDENT;
}
bool
LogFile::change_xml_to_html(String xmlfilename,String htmlfilename)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
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)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
LogViewer logviewer(filename);
logviewer.m_To_Excel(filename2);
return true;
}
void
LogFile::term(
void
)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
m_file.flush();
m_file.close();
}
void
LogFile::updata(
void
)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
m_file.flush();
}
void
LogFile::writeMessage(PRIORITY_OP type,
const
char
*
format, ...)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
if(!isInit())
return;
char buffer[MAX_DEBUG_LINE_LEN];
va_list args;
va_start(args, format);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
int buf = _vsnprintf(buffer, MAX_DEBUG_LINE_LEN, format, args);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
assert((buf >= 0) && (buf < MAX_DEBUG_LINE_LEN));
va_end(args);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
String str(buffer);
drawMessage(type,str);
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
LogViewer.h:
#pragma
once
#include
<
vector
>
#include
<
string
>
#include
<
Windows.h
>
#include
<
fstream
>
#include
<
iostream
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#if
!defined(__MSXML3__)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#define
__MSXML3__
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#import
"
msxml3.dll
"
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#endif
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#ifdef UNICODE
typedef std::wstring String;
#else
typedef std::
string
String;
#endif
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
typedef
struct
_NodeItem
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
String mNodeName;
String mText;
std::vector<_NodeItem> mChildNodes;
std::vector<_NodeItem> mAttributes;
}
NodeItem;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
class
XMLLoader
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public:
XMLLoader(void);
public:
~XMLLoader(void);
public:
int loadFile(String fileName);
private:
int readNode(MSXML2::IXMLDOMNodePtr& element, NodeItem& node);
NodeItem& getRoot()
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
return mRoot;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
protected:
NodeItem mRoot;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
protected:
int resetTree(NodeItem& node);
}
;
//
const int AINDENENT=4;
class
LogViewer:XMLLoader
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
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="");
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/**////std::fstream m_file;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//返回一个指针链表,指向所有符合条件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);
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/**///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