/// <summary> /// Return a single log record identified by the specific message timestamp. If no record is found a blank log record is returned. /// </summary> /// <param name="MessageTimestamp">Message timestamp to use when searching</param> /// <param name="TimestampEarlyOrLate">Earliest = Message immediately before timestamp, Latest = Message immediately after timestamp</param> /// <returns>A single log record</returns> public LogRecord GetRecordByTimestamp(DateTime MessageTimestamp, EarliestOrLatest TimestampEarlyOrLate = EarliestOrLatest.Earliest) { log.DebugFormat("MessageTimestamp - {0}", MessageTimestamp); return this.GetRecordByFileTime((ulong)MessageTimestamp.ToFileTime(), TimestampEarlyOrLate); }
/// <summary> /// Return a single log record identified by the specific message filetime. If no record is found a blank log record is returned. /// </summary> /// <param name="MessageFiletime">Message filetime to use when searching</param> /// <param name="TimestampEarlyOrLate">Earliest = Message immediately before timestamp, Latest = Message immediately after timestamp</param> /// <returns>A single log record</returns> public LogRecord GetRecordByFileTime(ulong MessageFiletime, EarliestOrLatest TimestampEarlyOrLate = EarliestOrLatest.Earliest) { log.DebugFormat("MessageFiletime - {0}", MessageFiletime); LogRecord returnValue = new LogRecord(); bool foundRecord = false; /* For optimization purposes first locate the log files that may contain a message with the specified filetime We say file(s) because there is currently an issue with how the log system writes files that may overlap timestamps in that case will find the first match and return that * * General premise of searching early or late is that early will get message immediately on or before target timestamp * and late will get message immediately on or after target timestamp */ foreach (string logFilePath in GetLogFilePathsForMessageFileTime(MessageFiletime)) { // Get a reference to the log file by opening it if (!OpenLogFile(logFilePath).Status) { throw new aaLogReaderException(string.Format("Error opening log file {0}", logFilePath)); } //Get the header which should be loaded into a global in memory now LogHeader localHeader = this.CurrentLogHeader; //Determine if we are closer to the beginning or end if ((MessageFiletime - localHeader.StartFileTime) <= (localHeader.EndFileTime - MessageFiletime)) { log.DebugFormat("Starting from beginning of file at filetime {0}", localHeader.StartFileTime); //Looks like we are closer to beginning to start at beginning and go next returnValue = GetFirstRecord(); // Start looping until we find the record we are looking for considering the Early or Late Timestamp parameters while (returnValue.ReturnCode.Status) { // If we have gone past our target timestamp then go back and get the last record if (returnValue.EventFileTime >= MessageFiletime) { if (TimestampEarlyOrLate == EarliestOrLatest.Earliest) { // Go back one record returnValue = GetPrevRecord(); // Make sure we got a good record then dump out of the while loop if (returnValue.ReturnCode.Status) { foundRecord = true; break; } } else { break; } } // Get the next record returnValue = GetNextRecord(); } } else { //Looks like we are closer to the end so start at end and go previous returnValue = GetLastRecord(); // Start looping until we find the record we are looking for considering the Early or Late Timestamp parameters while (returnValue.ReturnCode.Status) { // If we have gone past our target timestamp then go back and get the last record if (returnValue.EventFileTime <= MessageFiletime) { if (TimestampEarlyOrLate == EarliestOrLatest.Latest) { // Go back one record returnValue = GetNextRecord(); // Make sure we got a good record then dump out of the while loop if (returnValue.ReturnCode.Status) { foundRecord = true; break; } } else { break; } } // Get the previous record returnValue = GetPrevRecord(); } } // Check to see if we have found our record if (foundRecord) { // Dump out of the for loop break; } } return returnValue; }