EventLog クラスって、これも存在は知ってましたが触ったことないクラスの一つです。
イベントログに関する色々な操作ができるんですねー。
EventLogTraceListener は結構おどろきでした。
Debug や Trace.Write の出力先をイベントログにする事もできちゃうなんて。
(おもろいけど、使う場面ってあるのかな...)
TraceListener クラス自体は抽象クラスのようですが、
そいつを継承した以下のクラス郡で リスナーが出来るみたいです。おもろー。
Microsoft.VisualBasic.Logging.FileLogTraceListener
System.Diagnostics.DefaultTraceListener
System.Diagnostics.TextWriterTraceListener
System.Web.WebPageTraceListener
■参考文献
カスタム イベント ログの作成と削除
EventLog クラス
OverflowAction 列挙体
TraceListener クラス
■実行画像
EventLog への書き込み
EventLog へ書き込まれた時の通知
EventLog からの読み出し
Public Class EventLogTest
Private Const APPLICATION_LOG As String = "Application"
Private Const APPLICATION_NAME As String = "MyTestApplication"
Private Const EVENT_ID As Integer = 1
Private Enum Action As Integer
イベントログの書き出し
Log消去・カスタムソースの消去
Applicationログの読み出し
イベントログの全読み出し
TraceListenerの利用
オーバーフロー時に関する設定など
End Enum
Private Sub EventLogTest_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
With Me.ComboBox1
.Items.Clear()
.DropDownStyle = ComboBoxStyle.DropDownList
.Items.Add(Action.イベントログの書き出し)
.Items.Add(Action.Log消去・カスタムソースの消去)
.Items.Add(Action.Applicationログの読み出し)
.Items.Add(Action.イベントログの全読み出し)
.Items.Add(Action.TraceListenerの利用)
.Items.Add(Action.オーバーフロー時に関する設定など)
.SelectedIndex = 0
End With
With Me.ListView1
.View = View.Details
.GridLines = True
.FullRowSelect = True
.Columns.Add("種類", 80, HorizontalAlignment.Left)
.Columns.Add("日付時刻", 80, HorizontalAlignment.Left)
.Columns.Add("ソース", 100, HorizontalAlignment.Left)
.Columns.Add("データ", 100, HorizontalAlignment.Left)
End With
With Me.EventLog1
.BeginInit()
.MachineName = System.Environment.MachineName ' Local 指定の場合 "." でも OK
.Source = APPLICATION_NAME
.Log = APPLICATION_LOG
.EndInit()
End With
' 何故か EventLog1 では EntryWritten が拾えなかった為、もう一個用意
With Me.EventLog2
.BeginInit()
.EnableRaisingEvents = True ' コレが無いと EntryWritten の通知が来ない
.SynchronizingObject = Me
.MachineName = System.Environment.MachineName
.Source = APPLICATION_NAME
.Log = APPLICATION_LOG
.EndInit()
End With
End Sub
Private Sub EventLog2_EntryWritten(ByVal sender As Object, ByVal e As System.Diagnostics.EntryWrittenEventArgs) Handles EventLog2.EntryWritten
MessageBox.Show("書き込みまれました" & ControlChars.NewLine & _
e.Entry.Source & ":" & e.Entry.EntryType.ToString())
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Select Case DirectCast(Me.ComboBox1.SelectedItem, Action)
Case Action.イベントログの書き出し
Me.WriteEventLog() : Exit Select
Case Action.Log消去・カスタムソースの消去
Me.DeleteLog() : Exit Select
Case Action.Applicationログの読み出し
Me.ReadApplicationLog() : Exit Select
Case Action.イベントログの全読み出し
Me.ReadAllEventLogs() : Exit Select
Case Action.TraceListenerの利用
Me.UseTraceListener() : Exit Select
Case Action.オーバーフロー時に関する設定など
Me.ModifyOverflowPolicy() : Exit Select
End Select
End Sub
' イベントログの書き出し
Private Sub WriteEventLog()
If Not System.Diagnostics.EventLog.SourceExists(APPLICATION_NAME, System.Environment.MachineName) Then
' 第二引数は Application、System、Security、または自分でつけた名前
Dim sourceData As System.Diagnostics.EventSourceCreationData = _
New System.Diagnostics.EventSourceCreationData(APPLICATION_NAME, APPLICATION_LOG)
System.Diagnostics.EventLog.CreateEventSource(sourceData)
End If
Dim data As Byte() = System.Text.Encoding.Default.GetBytes("これはテストのデータ")
Const CATEGORY_ID As Short = 1S
' Me.EventLog1.WriteEntry でもいいみたいだが、WriteEntry は共有メソッドなので
' 警告がでる。 Load の With 句に囲まれた所は Instance 経由じゃないとできない。へん。
Me.EventLog1.WriteEntry(APPLICATION_NAME, _
"これはてすとですよー", _
EventLogEntryType.Information, _
EVENT_ID, _
CATEGORY_ID, _
data)
Me.EventLog1.Close() ' これも Instance 経由。理由が解らない。
End Sub
' Log 消去
Private Sub DeleteLog()
Me.EventLog1.Clear()
Me.EventLog1.Close()
'' カスタムソース消去(CreateEventSource 時に EventSourceCreationData の第二引数にカスタムのを入れた時だけやりましょう)
'If System.Diagnostics.EventLog.SourceExists(APPLICATION_NAME, System.Environment.MachineName) Then
' Dim logName As String = _
' System.Diagnostics.EventLog.LogNameFromSourceName(APPLICATION_NAME, System.Environment.MachineName)
' System.Diagnostics.EventLog.DeleteEventSource(APPLICATION_NAME, System.Environment.MachineName)
' System.Diagnostics.EventLog.Delete(logName, System.Environment.MachineName)
'End If
MessageBox.Show("消去しました")
End Sub
' Application ログの読み出し
Private Sub ReadApplicationLog()
Me.ListView1.BeginUpdate()
Me.ListView1.Items.Clear()
Me.WriteEventLogEntriesToListView(Me.EventLog1)
Me.ListView1.EndUpdate()
End Sub
' イベントログの全読み出し
Private Sub ReadAllEventLogs()
Me.ListView1.BeginUpdate()
Me.ListView1.Items.Clear()
Dim events As System.Diagnostics.EventLog() = _
System.Diagnostics.EventLog.GetEventLogs(System.Environment.MachineName)
For Each evnt As EventLog In events
Me.ListView1.Items.Add(evnt.LogDisplayName)
Me.WriteEventLogEntriesToListView(evnt)
Next
Me.ListView1.EndUpdate()
End Sub
' EventLog から Entry を取り出して ListView に追加する
Private Sub WriteEventLogEntriesToListView(ByVal evnt As EventLog)
If evnt.Entries.Count = 0 Then
MessageBox.Show(evnt.LogDisplayName & " にはエントリがありません")
Return
End If
For Each ent As System.Diagnostics.EventLogEntry In evnt.Entries
Dim lstItem As ListViewItem = New ListViewItem
Dim forecolor As Color = Drawing.SystemColors.ControlText
If ent.EntryType _
= System.Diagnostics.EventLogEntryType.Warning Then
' Warning は文字色を黄に
forecolor = Color.Orange
End If
If ent.EntryType _
= System.Diagnostics.EventLogEntryType.Error OrElse _
ent.EntryType _
= System.Diagnostics.EventLogEntryType.FailureAudit Then
' Error・FailureAudit は文字色を赤に
forecolor = Color.Red
End If
lstItem.SubItems.Add(New ListViewItem.ListViewSubItem(lstItem, ent.EntryType.ToString(), forecolor, lstItem.BackColor, lstItem.Font))
lstItem.SubItems.Add(New ListViewItem.ListViewSubItem(lstItem, ent.TimeWritten.ToString("yy/MM/dd hh:mm:ss"), forecolor, lstItem.BackColor, lstItem.Font))
lstItem.SubItems.Add(New ListViewItem.ListViewSubItem(lstItem, ent.Source, forecolor, lstItem.BackColor, lstItem.Font))
lstItem.SubItems.Add(New ListViewItem.ListViewSubItem(lstItem, ent.Message & ControlChars.NewLine & System.Text.Encoding.Default.GetString(ent.Data), forecolor, lstItem.BackColor, lstItem.Font))
lstItem.SubItems.RemoveAt(0)
Me.ListView1.Items.Add(lstItem)
Next
End Sub
' EventLogTraceListener を使ってみる
Private Sub UseTraceListener()
System.Diagnostics.Trace.WriteLine("This is Test1")
Dim listener As System.Diagnostics.EventLogTraceListener = _
New System.Diagnostics.EventLogTraceListener(Me.EventLog1)
System.Diagnostics.Trace.Listeners.Clear()
System.Diagnostics.Trace.Listeners.Add(listener)
System.Diagnostics.Trace.WriteLine("This is Test2-1")
System.Diagnostics.Trace.TraceWarning("This is Test2-1") ' 警告のエントリが追加される
' 通常は System.Diagnostics.DefaultTraceListener がリスナーをしている
System.Diagnostics.Trace.Listeners.Clear()
System.Diagnostics.Trace.Listeners.Add(New System.Diagnostics.DefaultTraceListener())
System.Diagnostics.Trace.WriteLine("This is Test3")
End Sub
' オーバーフロー時に関する設定など
Private Sub ModifyOverflowPolicy()
Dim buff As System.IO.StringWriter = New System.IO.StringWriter
With buff
.WriteLine(Me.EventLog1.LogDisplayName & "ログの現在の設定:")
.WriteLine("ログの最大サイズ:" & Me.EventLog1.MaximumKilobytes.ToString() & "KB") ' 512
.WriteLine("最大サイズに達した場合の動作:" & Me.EventLog1.OverflowAction.ToString()) ' OverwriteOlder
.WriteLine("ログのエントリを保持する日数:" & Me.EventLog1.MinimumRetentionDays.ToString() & "日") '7
End With
Me.EventLog1.BeginInit()
' 最大サイズの変更
Me.EventLog1.MaximumKilobytes = 1024
' 最大サイズに達した場合の動作の変更 及び エントリを保持する日数(OverwriteOlder 以外は意味なしただし 1 以上 365 以下)
Me.EventLog1.ModifyOverflowPolicy(OverflowAction.OverwriteAsNeeded, 3)
Me.EventLog1.EndInit()
With buff
.WriteLine(StrDup(20, "="c))
.WriteLine(Me.EventLog1.LogDisplayName & "ログの新しいの設定:")
.WriteLine("ログの最大サイズ:" & Me.EventLog1.MaximumKilobytes.ToString() & "KB") ' 512
.WriteLine("最大サイズに達した場合の動作:" & Me.EventLog1.OverflowAction.ToString()) ' OverwriteOlder
.WriteLine("ログのエントリを保持する日数:" & Me.EventLog1.MinimumRetentionDays.ToString() & "日") '7
End With
MessageBox.Show(buff.ToString())
End Sub
End Class