C# 如何在查询事件日志时创建EventBookmark

C# 如何在查询事件日志时创建EventBookmark,c#,event-log,system.diagnostics,C#,Event Log,System.diagnostics,我有一个EventLogReader对象,事件日志中有一个查询,如下所示: string query = "*[System[(Level=2) and TimeCreated[@SystemTime>='%LastRun%']]]") // This line replaces the %LastRun% code with the date var myQuery = myEventLogQuery.Query.Replace("%LastRun%", myEventLogQuery

我有一个EventLogReader对象,事件日志中有一个查询,如下所示:

string query = "*[System[(Level=2) and TimeCreated[@SystemTime>='%LastRun%']]]")
// 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));
}
代码基本上使用读取器来查询自上次运行读取器以来与搜索查询匹配的所有事件

为此,我宁愿使用EventBookmark。毕竟,这就是它的目的!但是我很难找到任何工作代码

我现有的代码部分是这样运行的:

string query = "*[System[(Level=2) and TimeCreated[@SystemTime>='%LastRun%']]]")
// 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;
    }
使用System.Diagnostics.Eventing.Reader;
公共类EventLogTracker()
{
公共列表查询{get;set;}
//…剪了一些东西
公共int运行()
{
var计数=0;
foreach(查询中的var myQuery)
{
var query=neweventlogquery(myQuery.Log、myQuery.PathType、myQuery.query);
//这是重要的一点。必须考虑到
//日志可能为空,因此书签可能为空
var reader=myQuery.Bookmark!=null?新建EventLogReader(查询,myQuery.Bookmark):新建EventLogReader(查询);
事件记录事件记录;
而((eventRecord=reader.ReadEvent())!=null)
{
//做事
// ...
//然后更新书签
myQuery.Bookmark=eventRecord.Bookmark;
计数++;
}
}
返回计数;
}
瞧,您的代码使用EventBookmark只提供自应用程序启动以来发生的事件