Windows下的日誌機制

來源:互聯網
上載者:User

 

對於日誌,大部分人的想法應當和我起初的想法一致,只要寫個函數,在這個函數中開啟一個檔案,把需要記錄的事件資訊寫到這個檔案中。然後在需要記錄日誌的地方調用這個函數。

但此時需要考慮的問題有很多,包括檔案名稱的定義,是每次寫日誌都建立一個新檔案還是在一個檔案中寫所有的資訊。如果是同一個檔案如果控制多線程同時寫的問題;還有當記錄檔過大時,如果刪除以前的記錄。讀日誌的方式,包括檢索的功能;安全問題等等。所以不要小看了僅是協助工具功能的日誌機制,但不用擔心,windows已經為我們定義了很完善的日誌架構。

Windows vista引入的CLFS ( Common Log File System)機制,另外一個就是從NT3.5就支援的Event Logging機制,裡面的函數大多是以Elf(Event Log File)開頭的,簡稱為ELF。

Windows XP中定義了3類日誌,分別是應用程式記錄檔(Application),安全日誌(Security)和系統日誌(system),檔案名稱分別為AppEvent.Evt, SecEvent.Evt和SysEvent.Evt.這些檔案都用於儲存註冊表檔案和配置資訊的CONFIG目錄下%SystemRoot%\SYSTEM32\CONFIG\

Windows Vista增加了HardvareEvents和DFS Replication等日誌類別,並且為所有的記錄檔建立了一個單獨的目錄,即%SystemRoot%\SYSTEM32\winevt\Logs目錄,記錄檔的副檔名也由.EVT改為.EVTX。

日誌的配置資訊都是儲存在註冊表

HKEY_LOACAL_MACHINE\SYSTEM\CurrentControlSet\Sercices\Eventlog

 

下面看產生windows日誌的API及其執行過程:

1.  在註冊表中註冊事件來源。線介紹一下事件來源,事件來源都是註冊在註冊表HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Application\下的,如果需要自己註冊事件來源就可以在這個註冊表下添加一個新的鍵,再加兩個項就可以了。來看個例子,outlook的事件來源

它包含了三個鍵,EvetMessageFile用來指定這個事件來源的訊息檔案(message file)的位置和名稱。訊息檔案的作用可以使用模板來格式化日誌事件或其他訊息,與字串資源和對話方塊資源差不多。可以使用後面介紹的事件ID(Event ID)來尋找對應的顯示資訊,提供一種模板的支援。TypesSupported表示事件所支援的類型,包括EVENTLOG_ERROR_TYPE(0x0001), EVENTLOG_WARBUBG_TYPE(0x0002)等。Version表示事件來源的版本。訊息檔案可以是DLL,exe等有效地PE檔案,編寫訊息檔案的方法這裡就不介紹了,這裡可以寫應用程式本身的路徑。

2.  調用RegisterEventSource API來取得事件來源控制代碼,原型為:

HANDLE RegisterEventSource ( LPCTSTR lpUNCServerName, LPCTSTR lpSourceName)

其中lpUNCServerName表示機器名,如果是在本機操作,添NULL就可以了,lpSourceName為事件來源的名稱,填寫前面建立的鍵名就可以了。如果事件來源的名稱在註冊表中找不到,那麼系統會預設使用應用類日誌下的Application事件來源。

3.  使用ReportEvent API來添加日誌記錄。原型為:

BOOL ReportEvent ( HANLE hEventLog, WORD wType, WORD wCategory, DWORD dwEventID, PSID lpUserSid, DWORD wNumStrings, DWORD dwDataSize, LPCTSTR* lpStrings, LPVOID lpRawData);

第一參數為hEventLog是使用RegisterEventSource得到的事件來源控制代碼;第二個參數wType用來指定事件的類型,可以為如下的常量:EVENTLOG_SUCCESS,EVENTLOG_AUDIT_FAILURE等。第三個參數wCategory用來指定事件在事件來源中的類屬號,其分類規則是由應用程式自己定義的。第四個參數dwEventID用來指定事件的ID號,通過這個ID來定位訊息檔案中所對應的資訊。所以ID也是有應用程式自己定義的。第五個參數lpUserSid用來指定使用者的安全標識,可以設為NULL。第六個參數wNumStrings用來指定第八個參數lpStrings所指向的字串數組所包含的字串指標個數。第八個參數用在事件的Description欄位中顯示資訊,如所示:

第七個參數dwDataSize用來指定第九個參數lpRawData所指向的未經處理資料緩衝區的資料長度。這兩個參數一個設為0,另一個設為NULL就行了。

   這樣就可以寫入日子記錄了,來看一下代碼。

   首先是註冊事件來源的代碼:

BOOL AddEventSource(CString csName, DWORD dwCategoryCount)

{

         HKEY         hRegKey = NULL;

         DWORD   dwError = 0;

         TCHAR     szPath[ MAX_PATH ];

 

         _stprintf( szPath, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\%s"), csName );

 

         // Create the event source registry key

         dwError = RegCreateKey( HKEY_LOCAL_MACHINE, szPath, &hRegKey );

         if (dwError != 0)

         {

                   OutMsg("RegCreateKey failed for %d",GetLastError());

                   return E_FAIL;

         }

 

         // Name of the PE module that contains the message resource

         GetModuleFileName( NULL, szPath, MAX_PATH );

 

         // Register EventMessageFile

         dwError = RegSetValueEx( hRegKey, _T("EventMessageFile"), 0, REG_EXPAND_SZ, (PBYTE) szPath, (_tcslen( szPath) + 1) * sizeof TCHAR );

         if (dwError == 0)

         {

                   // Register supported event types

                   DWORD dwTypes = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE;

                   dwError = RegSetValueEx( hRegKey, _T("TypesSupported"), 0, REG_DWORD, (LPBYTE) &dwTypes, sizeof dwTypes );

 

                   // If we want to support event categories, we have also to register     the CategoryMessageFile.

                   // and set CategoryCount. Note that categories need to have the message ids 1 to CategoryCount!

 

                   if(dwError == 0 && dwCategoryCount > 0 )

                   {

                            dwError = RegSetValueEx( hRegKey, _T("CategoryMessageFile"), 0, REG_EXPAND_SZ, (PBYTE) szPath, (_tcslen( szPath) + 1) * sizeof TCHAR );

                            if (dwError == 0)

                                     dwError = RegSetValueEx( hRegKey, _T("CategoryCount"), 0, REG_DWORD, (PBYTE) &dwCategoryCount, sizeof dwCategoryCount );

                   }

         }

 

         RegCloseKey( hRegKey );

 

         return TRUE;

}

來至《軟體調試》

 

接下來是添加記錄的過程:

         LPCTSTR ppszArgs[]={"I make a trick!!!!!!!"};  // 要顯示的資訊

         HANDLE  hLog = ::RegisterEventSource( NULL, "MyEventSource"); //之前註冊的事件來源

 

         BOOL bRet = ReportEvent(hLog, EVENTLOG_INFORMATION_TYPE,

                   0, 1024, NULL, 1, 0, ppszArgs,         NULL);    // 顯示記錄

 

除了顯示日子記錄的功能,當然還有其他的API來實現更多的功能,其他的API如所示:

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.