// Created by Larry Leonard, Definitive Solutions, Inc. #ifndef MYATLLOGH_ #define MYATLLOGH_ #pragma once #include using namespace std; #ifdef _ATL_MIN_CRT #error C RunTime is required by this class! #endif ///////////////////////////////////////////////////////////////////////////// // Macros // This macro just makes for less typing. If you need finer control, you can // still call the methods manually, but usually you would use this. (Note the // clever use of a space to allow this macro to take variable arguments.) // // Example: DOMYLOG (SEV_AUDIT, "This is test <%d>: <%s>.", 328, "Zoë!"); #define DOMYLOG GenericAtl::TheLog.Header(__FILE__, __LINE__); \ GenericAtl::TheLog.Log // Load the format from the string table. // Call this like this: DOMYLOGST(API_FAILURE), "GetDlgItem()", nRC); #define DOMYLOGST(uiStringTableId) \ GenericAtl::TheLog.Header(__FILE__, __LINE__); \ string sFormatString; \ VERIFY(sFormatString.LoadString(uiStringTableId)); \ GenericAtl::TheLog.Log(sFormatString // These make for less typing. #define SEV_AUDIT MyAtlLog::Severity::Audit #define SEV_ERROR MyAtlLog::Severity::Error #define SEV_WARNS MyAtlLog::Severity::Warns #define SEV_DEBUG MyAtlLog::Severity::Debug #define SEV_NOLOG MyAtlLog::Severity::NoLog ///////////////////////////////////////////////////////////////////////////// // MyAtlLog class MyAtlLog { // Construction. public: MyAtlLog(); virtual ~MyAtlLog(); // Declared but not defined. private: MyAtlLog(const MyAtlLog& rhs); MyAtlLog& operator=(const MyAtlLog& rhs); // Public data. public: // The different levels of messages. enum Severity { NoLog = 0, // Disables logging. Audit = 1, // Informational - always logged. Error = 2, // Problem - logged if m_eLoggingLevel is Error or lower. Warns = 3, // Issue - logged if m_eLoggingLevel is Warning or lower. Debug = 4 // Informational - logged if m_eLoggingLevel is Debug. }; // Operations. public: // You MUST call both of these methods. HRESULT Initialize(); HRESULT Shutdown(); // You rarely need to use these utility methods. void SetLoggingLevel(Severity sev); string GetLastBuffer(); static string GetStringForSeverity(Severity sev); // You virtually never need to call these - used by the macros above. void Header(const string& sFile, DWORD nLine); void Log(Severity sev, const TCHAR* pszFormatString, ...); MyAtlLog& operator <<(int nVal); MyAtlLog& operator <<(long lVal); MyAtlLog& operator <<(unsigned int unVal); MyAtlLog& operator <<(unsigned long ulVal); MyAtlLog& operator <<(double dVal); MyAtlLog& operator <<(const TCHAR* psz); MyAtlLog& operator <<(TCHAR tch); // Implementation. protected: HRESULT InsertMsgToDOM(); HRESULT AppendMessageNodeToDOM(IXMLDOMElementPtr& pRootElement, const string& strSub); HRESULT SaveDOMToDisk(); // Data. protected: struct Msg { string strTimestamp; // YYYY-MM-DD HH:MM:SS.mmm DWORD dwProcessId; // This app's process number. DWORD dwThreadId; // Thread number. string strFile; // __FILE__ DWORD dwLine; // __LINE__ Severity sev; // Our enum. string strMsg; // The message. }; string m_strFileName; // Name of XML log file. Severity m_LoggingLevel; // Log msgs this level and higher. Msg m_Msg; // The current message being logged. string m_strLastBuffer; // Most recently logged message. IXMLDOMDocumentPtr* m_pspXMLDOMDocument; // The DOM document for the XML. }; #endif // MYATLLOGH_