2009년 10월 25일 일요일

응용프로그램의 이벤트 로그 깔끔하게 저장하기

윈도즈의 서비스 프로그램에서 서비스 프로그램의 상태를 표시하는 방법으로 이벤트 로깅이 애용됩지요.

HANDLE hEventSource = RegisterEventSource(NULL, GetEventSource());

ReportEvent(hEventSource, EVENTLOG_INFORMATION_TYPE, 0, GS_INFO_GENERAL, NULL, 2, 0, lpszStrings, NULL);
DeregisterEventSource(hEventSource);

그런데, 이렇게만 호출한 후 이벤트 표시기를 통해 이벤트를 보면 지저분한 메시지들이 실제 메시지 앞에 표시됩니다.

The description for Event ID ( 258 ) in Source ( gsService ) cannot be found. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer. You may be able to use the /AUXSOURCE= flag to retrieve this description; see Help and Support for details. The following information is part of the event: GS Service Report: , Java Process started: Process Handle=0x7c, Process Id=3504.

RegisterEventSource에 사용한 이벤트명이 이벤트 소스로 등록되어 있지 않아서 생기는 문제인데, 이문제를 해결하기 위한 절차가 절차를 알아봅시다.

 

1. 메시지 파일의 생성

; // ***** GSMsg.mc *****
; // This is the header section.

SeverityNames=(Success=0x0:STATUS_SEVERITY_SUCCESS
    Informational=0x1:STATUS_SEVERITY_INFORMATIONAL
    Warning=0x2:STATUS_SEVERITY_WARNING
    Error=0x3:STATUS_SEVERITY_ERROR
    )

FacilityNames=(System=0x0:FACILITY_SYSTEM
    Runtime=0x2:FACILITY_RUNTIME
    Stubs=0x3:FACILITY_STUBS
    Io=0x4:FACILITY_IO_ERROR_CODE
)

LanguageNames=(English=0x409:MSG00409)
;LanguageNames=(Korean=0x412:MSG00412)

; // The following are message definitions.
MessageIdTypedef=DWORD

MessageId=0x101
Severity=Error
Facility=Runtime
SymbolicName=GS_ERROR_GENERAL
Language=English
General Error: %1 %2

.

 

MessageId=0x102
Severity=Informational
Facility=Runtime
SymbolicName=GS_INFO_GENERAL
Language=English
Information: %1 %2
.

2. 메시지 파일을 메시지 컴파일러(mc)로 컴파일

mc -h $(InputDir) -r $(InputDir) $(InputPath)

-h dir: 헤더파일 출력폴더 지정
-r dir: 리소스파일 출력폴더 지정

-u: 메시지 파일이 유니코드 파일

-U: 출력 .bin파일을 유니코드 파일로 지정

이렇게 하면 GSMsg.h, GSMsg.rc, 그리고 MSG00409.bin (MSG00412.bin) 파일이 생성됩니다. 생성된 파일은 일반 헤더와 리소스처럼 VC 프로젝트에 추가해 컴파일 해줍니다. 그러면 생성된 EXE나 DLL에 메시지 정보가 포함됩니다.

 

3. 메시지 소스를 레지스트리에 등록

   메시지를 실행파일에 포함했으면, 이제 그 정보를 이벤트표시기에 그 정보를 알려줘야 하는데, 윈도즈의 레지스트리가 이용됩니다.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\EventSourceName

EventMessageFile(REG_EXPAND_SZ): C:\Program Files\gsservice\GSService.exe

TypesSupported(REG_DWORD): 7 (EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE)

좀 번거롭나요? 그래도 완성도를 높이려면 좀 수고를 해야겠죠. 그러면 이벤트 메시지가 깔끔해집니다.

Information: GS Service Report:  Java Process started: Process Handle=0x7c, Process Id=3504

자바 프로그램을 윈도즈 서비스로 만들기에 첨부된 소스의 프로젝트 파일에는 메시지컴파일과 리소스컴파일과정이 포함되어 있습니다.