/// <summary> /// Extracts all entries spanning given scan parameters. /// Extraction is performed on a separate thread. /// Returned entries are in descending timestamp order. /// </summary> /// <returns></returns> public ScanResult Scan() { logSearchParameters.AssertAreValid(); var filesManager = wurmLogFiles.GetForCharacter(new CharacterName(logSearchParameters.CharacterName)); LogFileInfo[] logFileInfos = filesManager.GetLogFiles(logSearchParameters.MinDate, logSearchParameters.MaxDate) .Where(info => info.LogType == logSearchParameters.LogType).ToArray(); cancellationManager.ThrowIfCancelled(); CharacterMonthlyLogHeuristics characterHeuristics = monthlyHeuristics.GetForCharacter(new CharacterName(logSearchParameters.CharacterName)); cancellationManager.ThrowIfCancelled(); var result = GetEntries(logFileInfos, characterHeuristics); switch (logSearchParameters.ScanResultOrdering) { case ScanResultOrdering.Ascending: return(new ScanResult(result.OrderBy(entry => entry.Timestamp).ToList())); case ScanResultOrdering.Descending: return(new ScanResult(result.OrderByDescending(entry => entry.Timestamp).ToList())); default: throw new Exception("Unsupported ScanResultOrdering value: " + logSearchParameters.ScanResultOrdering); } }
private List <LogEntry> GetEntries( IEnumerable <LogFileInfo> logFileInfos, CharacterMonthlyLogHeuristics heuristicsFileMap) { var parsingHelper = logFileParserFactory.Create(); List <LogEntry> result = new List <LogEntry>(); foreach (LogFileInfo logFileInfo in logFileInfos) { if (logFileInfo.LogFileDate.LogSavingType == LogSavingType.Monthly) { ParseMonthlyFile(heuristicsFileMap, logFileInfo, result, parsingHelper); } else if (logFileInfo.LogFileDate.LogSavingType == LogSavingType.Daily) { ParseDailyFile(logFileInfo, result, parsingHelper); } else { logger.Log( LogLevel.Warn, string.Format( "LogsScanner encountered and skipped file with unsupported saving type, type: {0}, file: {1}", logFileInfo.LogFileDate.LogSavingType, logFileInfo.FullPath), this, null); } cancellationManager.ThrowIfCancelled(); } return(result); }
private void ParseMonthlyFile( CharacterMonthlyLogHeuristics heuristicsFileMap, LogFileInfo logFileInfo, List <LogEntry> result, LogFileParser logFileParser) { var heuristics = heuristicsFileMap.GetFullHeuristicsForMonth(logFileInfo); var dayToSearchFrom = GetMinDayToSearchFrom(logSearchParameters.MinDate, logFileInfo.LogFileDate.DateTime); var dayToSearchTo = GetMaxDayToSearchUpTo(logSearchParameters.MaxDate, logFileInfo.LogFileDate.DateTime); List <LogEntry> entries = new List <LogEntry>(); LogFileStreamReader reader = null; try { for (int day = dayToSearchFrom; day <= dayToSearchTo; day++) { var thisDayHeuristics = heuristics.GetForDay(day); if (thisDayHeuristics.LinesLength == 0) { continue; } if (reader == null) { if (heuristics.HasValidFilePositions) { reader = streamReaderFactory.Create( logFileInfo.FullPath, thisDayHeuristics.StartPositionInBytes); } else { reader = streamReaderFactory.CreateWithLineCountFastForward( logFileInfo.FullPath, thisDayHeuristics.TotalLinesSinceBeginFile); } } var thisEntryDate = new DateTime( logFileInfo.LogFileDate.DateTime.Year, logFileInfo.LogFileDate.DateTime.Month, day, 0, 0, 0); int readLinesCount = 0; List <string> allLines = new List <string>(); string currentLine; while ((currentLine = reader.TryReadNextLine()) != null) { allLines.Add(currentLine); readLinesCount++; if (readLinesCount == thisDayHeuristics.LinesLength) { break; } } IList <LogEntry> parsedLines = logFileParser.ParseLinesForDay(allLines, thisEntryDate, logFileInfo); entries.AddRange(parsedLines); cancellationManager.ThrowIfCancelled(); } result.AddRange(entries); } finally { reader?.Dispose(); } }