Error tracking during execution! I believe everyone has its own set of methods! ! ! But all use file files, I use XML & XSL this time, you can generate report formats, and easily generate reports! ! !
I will refer to the idea of writing XML configuration files in Emilio Guijarro Cameros! ! ! Combined with XML interface ixmldomdocument, ixmldomnode, ixmldomelement, and MFC, a CXMLLOGFILE class is written, only two public methods are exposed.
Void log (LPCTSTSTR S, ...); BOOL CLARALL ()
Log is adding a log, CLEARALL is clear all logs !!! When you need to view the daily value, you only need to open the corresponding XML file log.xml, you can see a log form, for this, I specialize in a XSL style. Document (XML style XSL file must be in the same directory in the XML file)!
The following is the source code, you need IE5.5 or above! ! ! If compiling errors! Please download Microsoft's latest XML SDK! ! ! !
// xmllogfile.h: interface for the cxmllogfile class.////
#if! defined (AFX_XMLLOGFILE_H__EA8ACC84_7139_49F6_9B8A_F69D9CF5C385__included _) # define afX_XMLLOGFILE_H__EA8ACC84_7139_49F6_9B8A_F69D9CF5C385__included_
#iF _MSC_VER> 1000 # prgma overce # endif //_msc_ver> 1000 # include #include #include #include #include
// Author: by Force Eagle // Date Time: 2003-5-26 17: 08 // Reference: // CXMLPROFILE BY Emilio Guijarro Cameros
#pragma comment (lib, "msxml2.lib") class CXMLLogfile: public CObject {CString m_strFileName; IXMLDOMDocument * m_pXMLDoc; IXMLDOMNode * GetChildNode (LPCTSTR lpszParent, LPCTSTR lpszChild, BOOL bCreate = TRUE); IXMLDOMNode * GetFirstLevelNode (LPCTSTR lpszNodeName, BOOL bCreate = TRUE);
// Unix TimeStamp: Seconds from 1970-01-01 00:00:00 (UTC) INLINE DOUBLE TIMESTAMP (VOID) {_timeb TS; _FTIME (& TS); return (int) ts.time (ts.millitm / 1000.0) ;}; Protected: void appendnode (ixmldomnode * pxmlitem, lpctstr lpsznodeename, lpctstr lpszvalue); Void appenditem (lpctstr lpszfilename); LPCTSTSTR LPSZCOMMENT
Void flush ();
Bool Createlogfile (lpctstr lpszlogfilname); Void Dumpcomerror (_COM_ERROR & E);
Void init ();
Public: cxmllogfile (lpctstr lpszfilename = null); Virtual ~ cxmllogfile (); void log (lpctstrlpszfilname, lpctstr s, ...); BOOL CLARALL ();
#ENDIF / /! Defined (AFX_XMLLOGFILE_H__EA8ACC84_7139_49F6_9B8A_F69D9CF5C385__included_)
// xmllogfile.cpp: importation of the cxmllogfile class.////
#include "stdafx.h" #include "xmllogfile.h"
#ifdef _debug # undef this_filestatic char this_file [] = __ file __; # Define new debug_new # Endif
/ / / Condition / destruction /// * static tchar * szlogorig = {_t ("
/ N ""
/ N "" /NXXXX/N1053925276.381/N "" 2003-05-26 / N13: 01: 16.861 / n / n ")}; // * / static wchar * wszlogorig = {l"
/ N
/N/NXXXX/N1053925276.381/N2003-05-26/N13:01:16.861/N "}
CXMLLogfile :: CXMLLogfile (LPCTSTR lpszFileName) {VARIANT_BOOL bResult; IXMLDOMElement * pRootNode; HRESULT hr; if (NULL == lpszFileName) {CString strHlpPath, strAppName; strHlpPath = AfxGetApp () -> m_pszHelpFilePath; strAppName = AfxGetAppName (); strHlpPath = strHlpPath .Left (strHlppath.getLength () - 4 - strapname.getlength ()); m_strfilename = strHlppath _t ("log.xml");} else {m_strfilename = lpszfilename;}
hr = CoInitialize (NULL); LoadLog: if (SUCCEEDED (hr)) {hr = CoCreateInstance (CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void **) & m_pXMLDoc); if (SUCCEEDED (hr)) {m_pXMLDoc-> load ( Colevariant (m_strfilename), & bresult);}}
// get the root node m_pxmldoc-> get_documentelement (& prootnode);
IF (prootnode == null) // Non-Non-node {m_pxmldoc-> release (); m_pxmldoc = null; // Re-create XML daily file createLogfile (m_strfilename); goto loadLog; // Re-load} else {init );}} Cxmllogfile :: ~ cxmldoc-> save (Colevariant (m_strfilename)); m_pxmldoc-> release ();} / ** function name: init () * Description: Initializing the engineering information of XML log files * Parameters: * None * Return: No * / void cxmllogfile :: init () {ixmldomnode * PAPPNAMENODE, * PTIMESTAMP, * PDATE, * PTIME ;; tchar * sztemp = new tchar [max_path]; HRESULT HR;
CTIME TIMECUR; timecur = ctime :: getcurrenttime (); cstring strdate, start; strdate = timecur.format (_t ("% y-% m-% d")); start = timecur.format (_t ("% x" ));
/ / Change the project name PAPPNAMENODE = GetFirstlevelNode (_t ("appname")); hr = PAPPNAMENODE-> PUT_TEXT (CCOMBSTR ()); PAPPNAMENODE-> Release (); // * // Timestamp ZeromeMore (Sztemp, MAX_PATH); double timestamp = timeStamp (); _stprintf (szTemp, _T ( ".% 3f"), timestamp); pTimestamp = GetFirstLevelNode (_T ( "timestamp")); hr = pTimestamp-> put_text (CComBSTR (szTemp)) PtimeStamp-> Release (); // * / / Date Pdate = getFirstlevelNode (_T ("Date")); hr = pdate-> put_text (ccombstr (strdate)); pdate-> release ();
// Time PTIME = getFirstlevelNode (_t ("time")); hr = ptime-> put_text (ccombstr (strtime)); ptime-> release ();
Delete sztemp; flush ();} / ** function name: Dumpcomerror (_COM_ERROR & E) * Description: Output COM Error message * Parameters: * IN _COM_ERROR & E COM error message object * Return: None * / void cxmllogfile :: dumpcomerror (_Error) & e) {_BSTR_T BSTRSOURCE (E.Source ()); _2tription (); trace ("error / n"); trace ("/ tcode =% 08LX / N", E.ERROR ()) Trace ("/ Tcode Meaning =% S / N", E.ErrorMessage ()); Trace ("/ Tsource =% S / N", (LPCSTR) bstrsource; trace ("/ tdescription =% s / n" , (LPCSTR) bstrDescription);} / ** function name: CreateLogFile (LPCTSTR lpszLogFilName) * Description: create original XML log files * parameters: * iN LPCTSTR lpszLogFileName file name * returns: true success * / bool CXMLLogfile :: CreateLogFile ( LPCTSTR LPSZLOGFILNAME) {ixmldomdocument * pxmldoc = null; bstr bstr = null; Variant_Bool Status; HRESULT HR;
Try {hr = cocreateInstance (CLSID_DOMDocument, Null, Clsctx_inproc_server, IID_IXMLDOMDocument, (Void **) & PXMLDOC);
IF (Failed (HR)) _COM_ISSUE_ERROR (HR);
BSTR = :: sysallocstring (wszlogorig); assert (null! = bstr); hr = pxmldoc-> loadingXML (BSTR, & status); :: sysfreestring (bstr);
IF (Failed (HR)) _COM_ISSUE_ERROR (HR);
IF (status! = variant_true) {return false;}
HR = pxmldoc-> save (Colevariant (lpszlogfilname)); if (failed (hr)) _COM_ISSUE_ERROR (HR);
PXMLDOC-> Release ();} catch (__Error & e) {dumpcomerror (e); return false;} Return true;} / ** function name: getFirstLEVELNODE (LPCTSTR LPSZNODENAME) * Description: Find the first layer node pointer according to the name , it is determined whether there is no parameter to create *: * IN LPCTSTR lpszNodeName node name * IN BOOL bCreate whether to create * returns: IXMLDOMNode * node pointer * / IXMLDOMNode * CXMLLogfile :: GetFirstLevelNode (LPCTSTR lpszNodeName, BOOL bCreate) {IXMLDOMElement * pRootNode = NULL, * element = NULL; IXMLDOMNode * pLogItem = NULL, * pResultNode = NULL; CComBSTR szName; bool bSecFound = false, bEntryFound = false; // wchar_t * szTemp = new wchar_t [255]; m_pXMLDoc-> get_documentElement (& pRootNode); for ( ProotNode-> Get_Firstchild (& PLOGITEM); PLOGITEM! = NULL; PLOGITEM-> GET_NEXTSIBLING (& PLOGITEM) {PLOGITEM-> GET_BASENAME (& SZNAME);
IF (szname == ccombstr (lpsznodename)) {PRESULTNODE = PLOGITEM; BREAK;}}
if (pLogItem == NULL && bCreate) {m_pXMLDoc-> createElement (CComBSTR (lpszNodeName), & element); pRootNode-> appendChild (element, & pLogItem); element-> Release (); pResultNode = pLogItem;}
ProotNode-> release;} / ** function name: getChildNode (LPCTSTR LPSZPARENT, LPCTSTSTSZCHILD) * Description: Find some sub-node pointers under the parent node, no decision whether to create a creation * parameter: * in LPCTSTR lpszParent parent name * IN LPCTSTR lpszChild child node name * IN BOOL bCreate whether to create * returns: IXMLDOMNode * child node pointer * / IXMLDOMNode * CXMLLogfile :: GetChildNode (LPCTSTR lpszParent, LPCTSTR lpszChild, BOOL bCreate) {IXMLDOMElement * pRootNode = NULL , * Element = null; ixmldomnode * plogItem = null, * plogdata = null, * PRESULTNODE = NULL; CCOMBSTR SZNAME;
m_pXMLDoc-> get_documentElement (& pRootNode); for (pRootNode-> get_firstChild (& pLogItem); pLogItem = NULL;! pLogItem-> get_nextSibling (& pLogItem)) {pLogItem-> get_baseName (& szName); if (szName == CComBSTR (lpszParent)) {For (PLOGITEM-> Get_FirstChild (& PLogData); PlogData! = NULL; PLOGDATA-> GET_NEXTSIBLING (& PLOGDATA)) {PLOGDATA-> Get_Basename (& Szname);
IF (szname == ccombstr (lpszchild) {pResultNode = PLOGDATA; BREAK;}}
if (pLogData == NULL && bCreate) {m_pXMLDoc-> createElement (CComBSTR (lpszChild), & element); pLogItem-> appendChild (element, & pLogData); element-> Release (); pResultNode = pLogData;} pLogItem-> Release ( Break;}}
if (pLogItem == NULL && bCreate) {m_pXMLDoc-> createElement (CComBSTR (lpszParent), & element); pRootNode-> appendChild (element, & pLogItem); element-> Release (); m_pXMLDoc-> createElement (CComBSTR (lpszChild), & element); Plogitem-> appendchild (element, & plogdata); element-> release (); PRESULTNODE-> Release ();
return pResultNode;} / ** Function Name: AppendNode (IXMLDOMNode * pXMLItem, LPCTSTR lpszNodeName, LPCTSTR lpszValue) * Note: adding a node in the XML, and assigned lpszValue * Parameters: * IN IXMLDOMNode * pXMLItem Add node pointer node * iN LPCTSTR lpszNodeName node name * iN LPCTSTR lpszComment added value * / void CXMLLogfile :: appendNode (IXMLDOMNode * pXMLItem, LPCTSTR lpszNodeName, LPCTSTR lpszValue) {IXMLDOMElement * element; IXMLDOMNode * pLogData;
M_pxmldoc-> CreateElement (CCOMBSTR (LPSZNODENAME), & ELEMENT); PXMLITEM-> Appendchild (Element, & PLogData); Element-> Release ();
pLogData-> put_text (CComBSTR (lpszValue)); pLogData-> Release ();} / ** Function Name: AppendItem (LPCTSTR lpszFileName, LPCTSTR lpszComment) * Note: * log add a parameter in the XML: * IN LPCTSTR lpszFileName file * IN LPCTSTR lpszComment information error message * / void CXMLLogfile :: AppendItem (LPCTSTR lpszFileName, LPCTSTR lpszComment) {IXMLDOMElement * pRootNode, * element; IXMLDOMNode * nLogItem; CComBSTR szName; HRESULT hr; CTime timeCur; timeCur = CTime :: GetCurrentTime () CString strdate, start; strdate = timecur.format (_t ("% y-% m-% d")); start = timecur.format (_t ("% x")); hr = m_pxmldoc-> get_documentelement (& ProotNode );
M_pxmldoc-> CreateElement (CCOMBSTR (_T ("LogItem"), & Element); ProotNode-> appendchild (element, & nlogitem); element-> release ();
Appendnode (NLogitem, _T ("Date"), strdate;
AppendNode (NLOGITEM, _T ("Time"), startime);
Appendnode (NLOGITEM, _T ("FileName"), LPSZFILENAME);
Appendnode (NLOGITEM, _T ("comment"), lpszcomment;
ProotNode-> Release ();} / ** function name: flush () * Description: Write the buffer data to disk Save XML file * Parameters: * No * / void cxmllogfile :: flush () {m_pxmldoc-> save (Colevariant);} / ** function name: log (lpctstr s, ...) * Description: Add a daily value record * Parameters: * LPCTSTR LPSZFILENAME File Information * LPCTSTR S Other Error Messages * Example : * Log (__ file __, "% ld line error !!", __ line __) * / void cxmllogfile :: log (lpctstrlpszfilname, lpctstr s, ...) {static tchar szbuff [1024]; va_list argptr; int CNT;
VA_Start (Argptr, S); CNT = _VStPrintf (SZBuff, S, Argptr); VA_END (ARGPTR); appenditem (lpszfilname, szbuff); flush ();} / ** function name: clearll () * Description: Clear daily value * parameters: * * None return value: successful true * / bool CXMLLogfile :: ClearAll () {IXMLDOMElement * pRootNode = NULL; IXMLDOMNode * pLogItem = NULL, * pLogData = NULL, * pOldNode = NULL, * pNextNode, * pPreviousNode; CComBSTR szName; HRESULT hr; m_pXMLDoc-> get_documentElement (& pRootNode); try {pRootNode-> get_lastChild (& pLogItem); do {pLogItem-> get_previousSibling (& pPreviousNode); pLogItem-> get_baseName (& szName); if (szName == CComBSTR (_T ( "logItem"))) {pLogItem-> get_firstChild (& pLogData); do {pLogData-> get_nextSibling (& pNextNode); pLogData-> get_baseName (& szName); hr = pLogItem-> removeChild (pLogData, & pOldNode); if (FAILED (hr ))) _COM_ISSUE_ERROR (HR); PoldNode-> Release (); PoldNode = NULL;
PLOGDATA = PNEXTNODE;
IF (FAILED (HR)) _COM_ISSUE_ERROR (HR); PLOGITEM = PPREVIOUSNODE;} while (PLOGITEM! = null); ProotNode-> Release ();} catch (_COM_ERROR & E) {prootnode-> release (); dumpcomerror (e) Return false;} flush (); return true;}