/// <summary> /// Unified API for querying user chassis audit logs - both timestamp and maxEntries used as input /// </summary> /// <param name="filterStartTime"></param> /// <param name="filterEndTime"></param> /// <param name="maxEntries"></param> /// <returns>Returns list of user log when success else returns null.</returns> public static List <LogEntry> GetFilteredLogEntries(DateTime filterStartTime, DateTime filterEndTime, int maxEntries) { if (Tracer.GetCurrentUserLogFilePath() == null) { return(null); } try { List <LogEntry> timestampFilteredEntries = new List <LogEntry>(); // Parse the log entries from each user log file // Note that these files could simultaneously be modified (switch primary, delete content etc) foreach (string filepath in Tracer.GetAllUserLogFilePaths()) { if (!File.Exists(filepath)) { Tracer.WriteInfo("UserLogXmllinqHelper.GetFilteredLogEntries(): Skipping file ({0}) since it does not exist."); continue; } using (FileStream fileStream = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (BufferedStream bstream = new BufferedStream(fileStream)) using (StreamReader reader = new StreamReader(bstream)) { int index = 0; const int count = 2048; // Reading 2K characters at a time to alleviate memory pressure // Splitting file with arbitrary chunks size may result in chopped 'partial' XML data which is saved in this variable // This data will be merged with the subsequent (consecutive) XML data string prevEntry = null; while (!reader.EndOfStream) { char[] localbuffer = new char[count]; reader.Read(localbuffer, index, count); string myData = new string(localbuffer); myData = prevEntry + myData; string[] subStrings = System.Text.RegularExpressions.Regex.Split(myData, @"ApplicationData>"); if (subStrings.Length < 1) { break; } prevEntry = subStrings[subStrings.Length - 1]; for (int i = 0; i < subStrings.Length - 1; i++) { string str = subStrings[i]; if (str.Length > 2 && str.Trim().EndsWith("</")) { string currentEntry = (str.Remove(str.Length - 2)); string[] tokens = currentEntry.Trim().Split(new char[] { ',' }); LogEntry timestampFilteredEntry = new LogEntry(); if (DateTime.TryParse(tokens[0], out timestampFilteredEntry.eventTime)) { timestampFilteredEntry.eventTime = DateTime.ParseExact(tokens[0], "yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture); timestampFilteredEntry.eventDescription = currentEntry.Replace(tokens[0] + ",", ""); // Add this entry to the list only when the timestamp falls withing the parameter input range if (timestampFilteredEntry.eventTime >= filterStartTime && timestampFilteredEntry.eventTime <= filterEndTime) { timestampFilteredEntries.Add(timestampFilteredEntry); } } else { Tracer.WriteWarning("GetFilteredLogEntries(): Reading Chassis user log - ignoring entry '({0})' due to unparse-able date ", tokens[0]); // Skipping the entry since date is not parse-able } } } prevEntry = subStrings[subStrings.Length - 1]; } } } timestampFilteredEntries.Reverse(); return(timestampFilteredEntries.Take(maxEntries).ToList()); } catch (Exception e) { Tracer.WriteError("GetFilteredLogEntries(): Reading Chassis user log exception " + e.Message); return(null); } }