2005年08月16日

Windowsのイベントログを書き込む方法

Windowsで24時間365日稼動を保証する
ミッションクリティカルな
アプリケーションを作成する場合などに、
アプリケーションで発生する警告や致命的エラーを、
管理者がすばやく検出し対処できる様に、
適切なソリューションを提供する必要があります。

Windowsのサービスやアプリケーションが出力する
システムエラー、セキュリティ警告、アプリケーションエラーなどは、
主にイベントログに出力される仕組みが出来ています。
しかし、随時発生するイベントを、
「イベントビューア」で確認していては、
管理者の負荷はとても高く、
現実的な運用管理とほど遠いものとなります。

世の中には、Windowsのイベントログにフィルタリングを行い、
必要な情報を管理者へメールで通知するツールや、
Windows XP/Windows Server 2003から
提供された「eventtriggers」コマンドを利用し、
必要なイベントを必要なタイミングで抽出し、
任意のスクリプトを実行できる
便利な運用管理ツール類が存在します。
フィルタリングし通知するツールは別途紹介するとして、

今回は、アプリケーションで、
Windowsイベントログの利用を検討されているあなたに、
WindowsAPI関数の「ReportEvent」を
利用した具体的なソリューションを、
Delphiのサンプルプログラムで紹介します。

サンプルプログラム実行前に
以下の手順を実行してください。


@
EventLog.mcファイルをコンパイルしEventLog.rcを作成する。
MC.EXE EventLog.mc
A
EventLog.rcファイルをコンパイルしEventLog.resを作成する。
BRCC32.EXE -32 EventLog.rc
B
EventLog.resファイルをEventLogTesterUnit.pasに登録する。
{$R EventLog.RES}
C
レジストリにEventLogTesterのエントリを作成する。
・HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\
 Services\EventLog\Applicationキー配下に
 「EventLogTester」キーを作成する。
・HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\
 Services\EventLog\Application\EventLogTesterキー配下に
 名前=EventMessageFile,種類=REG_SZ,
 データ=<EventLogTester.exeのフルパス>を作成する。
・HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\
 Services\EventLog\Application\EventLogTesterキー配下に
 名前=TypesSupported,種類=REG_DWORD,
 データ=0x00000007を作成する。

全ソースは【続きを読む】をクリック!

使用例
procedure TForm1.btnReportEventClick(Sender: TObject);
const
 // イベント識別子
 EVENTID_INFOMATION = $400003E9;
 EVENTID_WARNING = $800003EA;
 EVENTID_ERROR = $C00003EB;
var
 lHdl: THandle;
 lMsg: String;
 lType,
 lEventID: Integer;
begin
 // イベントログのハンドルを取得する
 lHdl := RegisterEventSource(Nil, PChar('EventLogTester'));
 // ログに書込むイベントの種類を決定する
 case rgEventType.ItemIndex of
 0: // Information
  begin
   lType := EVENTLOG_INFORMATION_TYPE;
   lEventID := EVENTID_INFOMATION;
  end;
 1: // Warning
  begin
   lType := EVENTLOG_WARNING_TYPE;
   lEventID := EVENTID_WARNING;
  end;
 2: // Error
  begin
   lType := EVENTLOG_ERROR_TYPE;
   lEventID := EVENTID_ERROR;
  end;
 end;
 // メッセージをイベントログへ書込む
 lMsg := Format('%s', [edtEventMessage.Text]);
 ReportEvent(
  // イベントログのハンドル,
  // ログに書込むイベントの種類,
  // イベントの分類,
  // イベント識別子,
  // ユーザーセキュリティ識別子(省略可能),
  // メッセージにマージする文字列の数,
  // バイナリデータのサイズ(バイト数),
  // メッセージにマージする文字列の配列,
  // バイナリデータのアドレス

  lHdl,
  lType,
  StrToIntDef(edtEventCategory.Text,0),
  lEventID,
  Nil,
  1,
  0,
  @lMsg,
  Nil
 );
 // イベントログのハンドルを閉じる
 DeregisterEventSource(lHdl);
end;


【画面イメージ】

EventLogTester.gif

関連書籍


Copyright guy@かしらもんじ でぇ〜

注意:
 下記ソースファイルは、本ページの管理者である「guy」が個人的に作成しました。
 このソースは作者に断り無く、個人がコピー、改造することは許可しますが、
 いかなる場合であっても、商用目的に使用することを固く禁じます。
 あと、ホームページでの公開の都合上、各ソースの先頭に全角スペースが入ってます。
 あなたがDelphiでコンパイルする前に、この全角スペースを半角スペースに変換してくださいね。

Project File: EventLogTester.dpr
program EventLogTester;

uses
 Forms,
 EventLogTesterUnit in 'EventLogTesterUnit.pas' {Form1};

{$R *.res}

begin
 Application.Initialize;
 Application.CreateForm(TForm1, Form1);
 Application.Run;
end.


Form File: EventLogTesterUnit.dfm
object Form1: TForm1
 Left = 192
 Top = 114
 BorderIcons = [biSystemMenu, biMinimize]
 BorderStyle = bsSingle
 Caption = 'EventLog Tester'
 ClientHeight = 110
 ClientWidth = 272
 Color = clBtnFace
 Font.Charset = SHIFTJIS_CHARSET
 Font.Color = clWindowText
 Font.Height = -12
 Font.Name = #65325#65331' '#65328#12468#12471#12483#12463
 Font.Style = []
 OldCreateOrder = False
 PixelsPerInch = 96
 TextHeight = 12
 object lblEventMessage: TLabel
  Left = 120
  Top = 44
  Width = 90
  Height = 12
  AutoSize = False
  Caption = 'EventMessage:'
 end
 object lblEventCategory: TLabel
  Left = 120
  Top = 6
  Width = 90
  Height = 12
  AutoSize = False
  Caption = 'EventCategory:'
 end
 object btnReportEvent: TButton
  Left = 96
  Top = 84
  Width = 80
  Height = 22
  Caption = 'ReportEvent !'
  TabOrder = 3
  OnClick = btnReportEventClick
 end
 object edtEventMessage: TEdit
  Left = 118
  Top = 58
  Width = 150
  Height = 20
  TabOrder = 2
  Text = 'Event Log Test Message !'
 end
 object rgEventType: TRadioGroup
  Left = 6
  Top = 6
  Width = 107
  Height = 71
  Caption = 'EventType'
  ItemIndex = 0
  Items.Strings = (
   'Information'
   'Warning'
   'Error')
  TabOrder = 0
 end
 object edtEventCategory: TEdit
  Left = 118
  Top = 20
  Width = 150
  Height = 20
  TabOrder = 1
  Text = '1000'
 end
end


Source File: EventLogTesterUnit.pas
unit EventLogTesterUnit;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, ExtCtrls;

type
 TForm1 = class(TForm)
  rgEventType: TRadioGroup;
  lblEventCategory: TLabel;
  edtEventCategory: TEdit;
  lblEventMessage: TLabel;
  edtEventMessage: TEdit;
  btnReportEvent: TButton;
  procedure btnReportEventClick(Sender: TObject);
 private
 public
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}
{$R EventLog.RES}

//------------------------------------------------------------------------------
procedure TForm1.btnReportEventClick(Sender: TObject);
const
 // イベント識別子
 EVENTID_INFOMATION = $400003E9;
 EVENTID_WARNING = $800003EA;
 EVENTID_ERROR = $C00003EB;
var
 lHdl: THandle;
 lMsg: String;
 lType,
 lEventID: Integer;
begin
 // イベントログのハンドルを取得する
 lHdl := RegisterEventSource(Nil, PChar('EventLogTester'));
 // ログに書込むイベントの種類を決定する
 case rgEventType.ItemIndex of
 0: // Information
  begin
   lType := EVENTLOG_INFORMATION_TYPE;
   lEventID := EVENTID_INFOMATION;
  end;
 1: // Warning
  begin
   lType := EVENTLOG_WARNING_TYPE;
   lEventID := EVENTID_WARNING;
  end;
 2: // Error
  begin
   lType := EVENTLOG_ERROR_TYPE;
   lEventID := EVENTID_ERROR;
  end;
 end;
 // メッセージをイベントログへ書込む
 lMsg := Format('%s', [edtEventMessage.Text]);
 ReportEvent(
  // イベントログのハンドル,
  // ログに書込むイベントの種類,
  // イベントの分類,
  // イベント識別子,
  // ユーザーセキュリティ識別子(省略可能),
  // メッセージにマージする文字列の数,
  // バイナリデータのサイズ(バイト数),
  // メッセージにマージする文字列の配列,
  // バイナリデータのアドレス
  lHdl,
  lType,
  StrToIntDef(edtEventCategory.Text,0),
  lEventID,
  Nil,
  1,
  0,
  @lMsg,
  Nil
 );
 // イベントログのハンドルを閉じる
 DeregisterEventSource(lHdl);
end;

end.


MC File: EventLog.mc
;---------------------------------------------------------------------
MessageIdTypedef = DWORD
;---------------------------------------------------------------------
SeverityNames = (
 Success   = 0x0:EVENTLOG_SEVERITY_SUCCESS
 Information = 0x1:EVENTLOG_SEVERITY_INFORMATION
 Warning   = 0x2:EVENTLOG_SEVERITY_WARNING
 Error    = 0x3:EVENTLOG_SEVERITY_ERROR
)
;---------------------------------------------------------------------
LanguageNames = (
 English   = 0x0409:EVENTLOG_LANGUAGE_ENGLISH
 Japanese  = 0x0411:EVENTLOG_LANGUAGE_JAPANESE
)
;---------------------------------------------------------------------
MessageId=1001
Severity=Information
Facility=Application
SymbolicName=EVENTID_INFOMATION
Language=Japanese
%1
.
;---------------------------------------------------------------------
MessageId=1002
Severity=Warning
Facility=Application
SymbolicName=EVENTID_WARNING
Language=Japanese
%1
.
;---------------------------------------------------------------------
MessageId=1003
Severity=Error
Facility=Application
SymbolicName=EVENTID_ERROR
Language=Japanese
%1
.

posted by guy at 21:21 | 運用管理編
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。