从完整的EventLog读取时会出现一个神秘的IndexOutOfRange异常

时间:2015-04-03 10:05:55

标签: c# event-log

我正在维护一个应用程序,该应用程序使用Windows应用程序事件日志来“扫描”来自其他应用程序的错误。

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

然而。我不断得到IndexOutOfRange Exceptions我发现很难解决或理解。

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

IndexOutOfRange Exception仅在EventLog已满时发生。此外,log retention policy setting设置为“根据需要覆盖事件。”


代码

// 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异常。


  3. 目前为解决方案而努力

    • 在MSDN和其他地方研究了EventLog

    • 编写一个程序,使用条目填充事件日志,以尝试复制发生异常的条件。 (我不能在开发环境下重复出现问题,即使它在实时环境中频繁出现。)


    老实说,我完全失败了。我可以想到一些“半修复”(例如,使事件日志的最大大小变大,并坚持使用Exception处理程序,它什么都不做) - 但我真正想要的是理解为什么会发生这种情况并修复它适当。由于索引应始终位于0Entries.Count-1之间,因此我没有任何线索。

    有什么想法吗?

1 个答案:

答案 0 :(得分:0)

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

每次编写新的EventLog时,不是调用方法迭代Entry,而是使用事件处理程序更直接地访问Entry更简单(更安全)每次写入Entry时触发。

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