【问题标题】:How to create an EventBookmark when querying the event log查询事件日志时如何创建EventBookmark
【发布时间】:2015-10-09 03:55:24
【问题描述】:

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

string query = "*[System[(Level=2) and TimeCreated[@SystemTime>='%LastRun%']]]")

代码基本上使用阅读器来查询自上次运行阅读器以来与搜索查询匹配的所有事件。

我宁愿为此目的使用 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 设置为基本上是日志中的最高记录。

当应用程序最初运行时,我不需要它告诉我过去的所有事件日志条目,我只关心应用程序启动后发生的那些。

【问题讨论】:

    标签: c# event-log system.diagnostics


    【解决方案1】:

    好的,我继续进行了很多实验,并设法为此制定了一个好的系统。由于没有真正涵盖此主题,因此我将在此处发布我的答案。希望有用!

    第一个挑战是创建初始 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 只为您提供自应用程序启动以来发生的事件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-08
      • 2015-04-18
      • 1970-01-01
      • 1970-01-01
      • 2019-05-11
      • 1970-01-01
      • 2012-09-08
      相关资源
      最近更新 更多