从完整的事件日志中读取时重复出现神秘的 IndexOutOfRange 异常

A mystery IndexOutOfRange Exception recurring when reading from a full EventLog

我正在维护一个应用程序,该应用程序使用 Windows 应用程序事件日志 'scan' 来查找来自另一个应用程序的错误。

我需要找到自指定时间以来出现的第一个条目。因此,到目前为止,我所做的是从最新的事件日志条目 (Entries.Count-1) 循环返回,直到在指定时间 之前找到一个条目。下一个条目必须是自指定时间以来的第一个条目,因此我从该条目向前循环直到最后一个条目 (Entries.Count-1)。

不过。我一直收到 IndexOutOfRange Exceptions,我发现很难解决或理解。

另外,我意识到我对事件日志的一些假设很可能是错误的——我正在努力寻找相关文档来纠正自己。

IndexOutOfRange Exception 仅在事件日志已满时发生。此外,log retention policy setting 设置为 'Overwrite events as needed.'


代码

// This method is called every time a log is written to the Application Event Log
private void parseApplicationLogEntries()
{ 
    // Assumes the first log since the specified time is the most recent one
    int firstLog = log.Entries.Count-1;

    // Loops through the logs from the last one until the first,
    // stopping if it finds one before the specified time. 
    // The next entry must be the first one since the specified
    // time, so set the firstLog to its index and then break. 
    for (int entry = log.Entries.Count - 1; entry > 0; entry--)
    {
        DateTime logEntryTimeWritten = log.Entries[entry].TimeWritten;

        if (logEntryTimeWritten < specifiedTime)
        {
             firstLog = entry + 1;
             break;
        }
    }

    //
    for (int entry = firstLog; entry <= log.Entries.Count - 1; entry++)
    {
        string logSource = log.Entries[entry].Source; 

        if (logSource == sourceIAmLookingFor)
        {
            // Do some stuff
            // It's found, so break
        }
    }
}

所以。这里有很多可疑的假设,并且没有异常处理显然应该有一些。

  1. 这假设事件日志索引按时间从最旧到最新的条目排序。 (例如 Entries[0] 是最早的条目,Entries[Entries.Count-1] 是最新的条目)

  2. 没有异常处理来捕获 IndexOutOfRange 异常。


目前正在努力寻找解决方案


老实说,我完全不知所措。我可以想到一些 'half-fixes'(例如,使事件日志的最大大小变大,并坚持一个什么都不做的异常处理程序)——但我真正想要的是理解为什么会发生这种情况并修复它 正确。由于索引应该始终在 0Entries.Count-1 之间,所以我不知道。

有什么想法吗?

无需以这种方式访问​​ EventLog 即可查看最新条目。

与其在每次写入新的 Entry 时调用方法遍历 EventLog,不如直接使用每次写入 Entry 时触发的事件处理程序。

private void eventLog_Application_EntryWritten(object sender, EntryWrittenEventArgs e)
{
    // Process e.Entry    
}