如何在查询事件日志时创建 EventBookmark
How to create an EventBookmark when querying the event log
我有一个 EventLogReader 对象,事件日志中的查询如下所示:
string query = "*[System[(Level=2) and TimeCreated[@SystemTime>='%LastRun%']]]")
该代码基本上使用 reader 来查询自上次 reader 为 运行 以来与搜索查询匹配的所有事件。
为此,我宁愿使用 EventBookmark。毕竟,这就是它的用途!但是我找不到任何工作代码。
我现有的代码 运行,部分是这样的:
// This line replaces the %LastRun% code with the date
var myQuery = myEventLogQuery.Query.Replace("%LastRun%", myEventLogQuery.LastRun.ToString("o"));
var query = new EventLogQuery(myEventLogQuery.Log, myEventLogQuery.PathType, myQuery);
// Now set the LastRun date. I want to avoid this...
myEventLogQuery.LastRun = DateTime.UtcNow;
// ... by making this next line smarter.
var reader = new EventLogReader(query);
// var reader = new EventLogReader(query, ??? new EventBookmark());
EventRecord eventRecord;
while ((eventRecord = reader.ReadEvent()) != null)
{
EventRecords.Add(new EventRecordItem(eventRecord));
}
我应该可以使用第一个(或最后一个)EventRecord 的EventBookmark 属性 来限制下一次查询,但我想最初将EventBookmark 设置为基本上是日志中的最高记录。
当应用程序 运行 最初时,我不需要它告诉我过去的所有事件日志条目,我只关心应用程序启动后发生的事件。
好的,我继续尝试了很多,并设法为此制定了一个很好的系统。由于没有真正涵盖这个主题,我在这里发布我的答案。希望有用!
第一个挑战是创建初始 EventBookmark。你不能只实例化一个。您需要从现有的 EventRecord 派生一个。为此,我查询了日志中的最后一项,并将我的 EventBookmark 基于该项。
using System.Diagnostics.Eventing.Reader;
public class MyEventLogQuery
{
public string Log { get; set; }
public PathType PathType { get; set; }
public string Query { get; set; }
public EventBookmark Bookmark { get; set; }
public MyEventLogQuery(string log = "Application", PathType pathType = PathType.LogName, string query = "*[System[(Level=2)]]")
{
Log = log;
PathType = pathType;
Query = query;
Bookmark = GetBookmark(log, pathType); // Query is not important here
}
// This method returns the bookmark of the most recent event
// log EventRecord or null if the log is empty
private static EventBookmark GetBookmark(string log, PathType pathType)
{
var elq = new EventLogQuery(log, pathType) {ReverseDirection = true};
var reader = new EventLogReader(elq);
var record = reader.ReadEvent();
if (record != null)
return record.Bookmark;
return null;
}
}
下一步是在随后查询事件日志时使用书签(或缺少书签)。
using System.Diagnostics.Eventing.Reader;
public class EventLogTracker()
{
public List<MyEventLogQuery> Queries { get; set; }
// ... snipped some stuff
public int Run()
{
var count = 0;
foreach (var myQuery in Queries)
{
var query = new EventLogQuery(myQuery.Log, myQuery.PathType, myQuery.Query);
// This is the important bit. Must take account that the
// log may have been empty, so bookmark could be null
var reader = myQuery.Bookmark != null ? new EventLogReader(query, myQuery.Bookmark) : new EventLogReader(query);
EventRecord eventRecord;
while ((eventRecord = reader.ReadEvent()) != null)
{
// Do stuff
// ...
// Then update the bookmark
myQuery.Bookmark = eventRecord.Bookmark;
count++;
}
}
return count;
}
瞧,您的代码使用 EventBookmark 仅向您提供应用程序启动后发生的事件。
我有一个 EventLogReader 对象,事件日志中的查询如下所示:
string query = "*[System[(Level=2) and TimeCreated[@SystemTime>='%LastRun%']]]")
该代码基本上使用 reader 来查询自上次 reader 为 运行 以来与搜索查询匹配的所有事件。
为此,我宁愿使用 EventBookmark。毕竟,这就是它的用途!但是我找不到任何工作代码。
我现有的代码 运行,部分是这样的:
// This line replaces the %LastRun% code with the date
var myQuery = myEventLogQuery.Query.Replace("%LastRun%", myEventLogQuery.LastRun.ToString("o"));
var query = new EventLogQuery(myEventLogQuery.Log, myEventLogQuery.PathType, myQuery);
// Now set the LastRun date. I want to avoid this...
myEventLogQuery.LastRun = DateTime.UtcNow;
// ... by making this next line smarter.
var reader = new EventLogReader(query);
// var reader = new EventLogReader(query, ??? new EventBookmark());
EventRecord eventRecord;
while ((eventRecord = reader.ReadEvent()) != null)
{
EventRecords.Add(new EventRecordItem(eventRecord));
}
我应该可以使用第一个(或最后一个)EventRecord 的EventBookmark 属性 来限制下一次查询,但我想最初将EventBookmark 设置为基本上是日志中的最高记录。
当应用程序 运行 最初时,我不需要它告诉我过去的所有事件日志条目,我只关心应用程序启动后发生的事件。
好的,我继续尝试了很多,并设法为此制定了一个很好的系统。由于没有真正涵盖这个主题,我在这里发布我的答案。希望有用!
第一个挑战是创建初始 EventBookmark。你不能只实例化一个。您需要从现有的 EventRecord 派生一个。为此,我查询了日志中的最后一项,并将我的 EventBookmark 基于该项。
using System.Diagnostics.Eventing.Reader;
public class MyEventLogQuery
{
public string Log { get; set; }
public PathType PathType { get; set; }
public string Query { get; set; }
public EventBookmark Bookmark { get; set; }
public MyEventLogQuery(string log = "Application", PathType pathType = PathType.LogName, string query = "*[System[(Level=2)]]")
{
Log = log;
PathType = pathType;
Query = query;
Bookmark = GetBookmark(log, pathType); // Query is not important here
}
// This method returns the bookmark of the most recent event
// log EventRecord or null if the log is empty
private static EventBookmark GetBookmark(string log, PathType pathType)
{
var elq = new EventLogQuery(log, pathType) {ReverseDirection = true};
var reader = new EventLogReader(elq);
var record = reader.ReadEvent();
if (record != null)
return record.Bookmark;
return null;
}
}
下一步是在随后查询事件日志时使用书签(或缺少书签)。
using System.Diagnostics.Eventing.Reader;
public class EventLogTracker()
{
public List<MyEventLogQuery> Queries { get; set; }
// ... snipped some stuff
public int Run()
{
var count = 0;
foreach (var myQuery in Queries)
{
var query = new EventLogQuery(myQuery.Log, myQuery.PathType, myQuery.Query);
// This is the important bit. Must take account that the
// log may have been empty, so bookmark could be null
var reader = myQuery.Bookmark != null ? new EventLogReader(query, myQuery.Bookmark) : new EventLogReader(query);
EventRecord eventRecord;
while ((eventRecord = reader.ReadEvent()) != null)
{
// Do stuff
// ...
// Then update the bookmark
myQuery.Bookmark = eventRecord.Bookmark;
count++;
}
}
return count;
}
瞧,您的代码使用 EventBookmark 仅向您提供应用程序启动后发生的事件。