Changes between Initial Version and Version 1 of Software/userlog


Ignore:
Timestamp:
04/07/11 11:24:26 (14 years ago)
Author:
sherbold
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Software/userlog

    v1 v1  
     1= MFC Usage Monitoring - usagelog.dll = 
     2 
     3[[TracNav(TOC)]] 
     4[[TOC(inline)]] 
     5 
     6== Requirements == 
     7 * Windows MFC 
     8 
     9== Description == 
     10 
     11This tool is implemented as a Dynamic Linked Library (DLL) called {{{usagelog.dll}}}. The interface of the DLL is kept extremly simple, it provides only two functions: one to start the logging and one to end it. The logging itself is done, by utilizing the ''message hooks''. Hooks are placed inside the message processing chain of a program. Using them, it is possible to inspect the internal messaging of a program without modifying the program itself. For the different kinds of message, different hooks are provided. Currently, two hooks seem to be sufficient: a {{{WH_GETMESSAGE}}} and a {{{WH_CALLWNDPROC}}} hook.  
     12 
     13To be able to replay logged actions, three general informations are needed: 
     14 1. The correct order of the events 
     15 1. A description of the event itself 
     16 1. The target of the event 
     17 
     18To identify the order of the event, the order of the logged messages is used. It is assumed that this logging order is correct and that therefore the events took also place in this order.  
     19 
     20To describe the events themselves is more difficult. The logger has the responsibility to log any information that might be needed for event identification or replaying of events. To this aim, the messages are filtered based on their ''type'', e.g., {{{WM_CREATE}}} and {{{WM_COMMAND}}}.  
     21 
     22The target of the event is identified using the HWND of the GUI object that the event has been addressed to.  
     23 
     24=== Architecture === 
     25 
     26The architecture of the logging mechanism is rather simple. It is a DLL written in C++. The interface provides currently only functions to start and stop the logging: 
     27{{{ 
     28#!cpp 
     29__declspec(dllexport) void __cdecl InitUsagelog(); 
     30__declspec(dllexport) void __cdecl ReleaseUsagelog(); 
     31}}} 
     32 
     33The message filter is defined in as a simple switch-statement and may only be modified at compile time.  
     34 
     35As data format for the logs a simple XML scheme is used, described by the following DTD: 
     36{{{ 
     37#!xml 
     38<!ELEMENT log (session*)> 
     39<!ELEMENT session (msg*)> 
     40<!ELEMENT msg (param*)> 
     41<!ELEMENT param EMPTY> 
     42<!ATTLIST msg 
     43  type  CDATA #REQUIRED> 
     44<!ATTLIST param 
     45  name  CDATA #REQUIRED 
     46  value CDATA #REQUIRED> 
     47}}} 
     48A ''log'' consists of several ''sessions'', i.e., program executions. Every session consists of the messages it recorded. A message consists of a ''type'' and of parameters. The of a message is describes by an integer that identifies the windows message that has been send, e.g., {{{WM_CREATE}}}, {{{WM_DESTROY}}} or {{{WM_LBUTTONCLICK}}}. The parameters are ''name'', ''value'' pairs, both stored as strings. Using the parameters, it is possible to store additional information to messages in a generic and flexible way. For example, in case a window is created additional information about the window, like its resource id. 
     49 
     50=== How to use === 
     51 
     52To enable the logging the {{{usagelog.dll}}} has to be loaded: 
     53{{{ 
     54#!cpp 
     55HINSTANCE hinstDll = NULL; // Handle of the Dll. Should be global, as it needs to be used to start/stop the logging and to unload the Dll. 
     56 
     57// Load the Dll and check for errors 
     58hinstDll = LoadLibrary(L"usagelog.dll"); 
     59if( hinstDll==NULL ) { 
     60        MessageBox(0, L"Loading of DLL failed", L"Failure", MB_OK); 
     61} 
     62}}} 
     63 
     64Then, to start the logging {{{InitUsagelog()}}} needs to be called: 
     65{{{ 
     66#!cpp 
     67void (__cdecl *InitUsagelogPtr)(void) = NULL; // Function pointer with the signature of InitUsagelog 
     68 
     69// Obtain a function pointer to InitUsagelog() from the Dll and check for errors 
     70InitUsagelogPtr = (void (*)(void)) GetProcAddress(hinstDll, "InitUsagelog"); 
     71if( InitUsagelogPtr==NULL ) { 
     72        MessageBox(0, L"Loading of InitFuncPtr failed", L"Failure", MB_OK); 
     73} 
     74// Start the logging 
     75if( InitUsagelogPtr!=NULL ) { 
     76        InitUsagelogPtr(); 
     77} 
     78}}} 
     79 
     80To stop the logging, {{{ReleaseUsagelog()}}} needs to be called: 
     81{{{ 
     82#!cpp 
     83void (*ReleaseUsagelogPtr)(void) = NULL; // Function pointer with the signature of ReleaseUsagelog() 
     84 
     85// Obtain a function pointer to InitUsagelog() from the Dll and check for errors 
     86ReleaseUsagelogPtr = (void (*)(void)) GetProcAddress(hinstDll, "ReleaseUsagelog"); 
     87if( ReleaseUsagelogPtr==NULL ) { 
     88        MessageBox(0, L"Loading of ReleaseFuncPtr failed", L"Failure", MB_OK); 
     89} 
     90}}} 
     91 
     92Finally, if no more logging is required, the Dll may be unloaded: 
     93{{{ 
     94#!cpp 
     95FreeLibrary(hinstDll); 
     96}}} 
     97 
     98=== Further Features === 
     99 * Unicode logging 
     100  * encoding depends in compiler, UTF-16LE with Visual Studio 2008 
     101 * Base64 encoding of log to support writing ASCII while using Unicode internally