Как создать EventBookmark при запросе журнала событий

У меня есть объект 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));
}

Я должен иметь возможность использовать свойство EventBookmark первой (или последней) EventRecord, чтобы ограничить следующий запрос, но я хочу, чтобы изначально EventBookmark был в основном самой высокой записью в журнале.

Когда приложение запускается изначально, мне не нужно, чтобы оно сообщало мне обо всех прошлых записях журнала событий, мне нужны только те, которые произошли после запуска приложения.


person dylanT    schedule 20.07.2015    source источник


Ответы (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 для отображения только тех событий, которые произошли с момента запуска приложения.

person dylanT    schedule 21.07.2015