/// <summary> /// Aggregate Data and return UnitInfo List /// </summary> public DataAggregatorResult AggregateData(FahLog fahLog, QueueData queueData, UnitInfoLogData unitInfo) { if (Logger.IsDebugEnabled) { foreach (var s in fahLog.Where(x => x.LineType == LogLineType.Error)) { Logger.DebugFormat(Constants.ClientNameFormat, ClientName, String.Format("Failed to parse log line: {0}", s)); } } var currentClientRun = GetCurrentClientRun(fahLog); if (currentClientRun == null) { return null; } var result = new DataAggregatorResult(); result.StartTime = currentClientRun.Data.StartTime; result.Arguments = currentClientRun.Data.Arguments; result.ClientVersion = currentClientRun.Data.ClientVersion; result.UserID = currentClientRun.Data.UserID; result.MachineID = currentClientRun.Data.MachineID; result.Status = currentClientRun.SlotRuns[0].Data.Status; // Decision Time: If Queue Read fails parse from logs only if (queueData != null) { GenerateUnitInfoDataFromQueue(result, queueData, fahLog, unitInfo); result.Queue = BuildClientQueue(queueData); result.CurrentUnitIndex = result.Queue.CurrentIndex; } else { Logger.WarnFormat(Constants.ClientNameFormat, ClientName, "Queue unavailable or failed read. Parsing logs without queue."); GenerateUnitInfoDataFromLogs(result, fahLog, unitInfo); // default Unit Index if only parsing logs result.CurrentUnitIndex = 1; } if (result.UnitInfos == null || result.UnitInfos[result.CurrentUnitIndex] == null || result.UnitInfos[result.CurrentUnitIndex].LogLines == null) { result.CurrentLogLines = currentClientRun.ToList(); } else { result.CurrentLogLines = result.UnitInfos[result.CurrentUnitIndex].LogLines; } return result; }
//private const int QueueEntryLength = 712; /// <summary> /// Read queue.dat file /// </summary> /// <param name="filePath">Path to queue.dat file</param> /// <exception cref="System.ArgumentException">Throws if fileName is null or empty.</exception> /// <exception cref="System.IO.IOException">Throw on queue.dat read failure.</exception> /// <exception cref="System.NotSupportedException">Throws if queue.dat version is not supported. Supported versions are between 500 and 699.</exception> public static QueueData ReadQueue(string filePath) { if (String.IsNullOrEmpty(filePath)) throw new ArgumentException("Argument 'filePath' cannot be a null or empty string."); Data q = FromBinaryReaderBlock(filePath); // at this point we know we've read a file of expected length // and no exceptions were thrown in the process var qData = new QueueData(q); // If version is less than 5.xx, don't trust this data // this class is not setup to handle legacy clients // If version is greater than 6.xx, don't trust this data // this class has not been tested with clients beyond 6.xx if (qData.Version < 500 || qData.Version > 699) { throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture, "The version ({0}) of this queue.dat file is not supported.", qData.Version)); } return qData; }
private UnitInfo[] GenerateUnitInfoDataFromQueue(QueueData q) { Debug.Assert(q != null); var parsedUnits = new UnitInfo[10]; _unitLogLines = new IList<LogLine>[10]; for (int queueIndex = 0; queueIndex < parsedUnits.Length; queueIndex++) { // Get the Log Lines for this queue position from the reader _unitLogLines[queueIndex] = _logInterpreterLegacy.GetLogLinesForQueueIndex(queueIndex); // Get the FAH Log Data from the Log Lines FahLogUnitData fahLogUnitData = LogReader.GetFahLogDataFromLogLines(_unitLogLines[queueIndex]); UnitInfoLogData unitInfoLogData = null; // On the Current Queue Index if (queueIndex == q.CurrentIndex) { // Get the UnitInfo Log Data unitInfoLogData = GetUnitInfoLogData(); } parsedUnits[queueIndex] = BuildUnitInfo(q.GetQueueEntry((uint)queueIndex), fahLogUnitData, unitInfoLogData); if (parsedUnits[queueIndex] == null) { if (queueIndex == q.CurrentIndex) { string message = String.Format(CultureInfo.CurrentCulture, "Could not verify log section for current queue entry {0}. Trying to parse with most recent log section.", queueIndex); _logger.Warn(Constants.ClientNameFormat, ClientName, message); _unitLogLines[queueIndex] = _logInterpreterLegacy.CurrentWorkUnitLogLines; // If got no Work Unit Log Lines based on Current Work Unit Log Lines // then take the entire Current Client Run Log Lines - likely the run // was short and never contained any Work Unit Data. if (_unitLogLines[queueIndex] == null) { _unitLogLines[queueIndex] = _logInterpreterLegacy.CurrentClientRunLogLines; } fahLogUnitData = LogReader.GetFahLogDataFromLogLines(_unitLogLines[queueIndex]); if (_currentClientRun.Status.Equals(SlotStatus.GettingWorkPacket)) { // Use either the current Work Unit log lines or current Client Run log lines // as decided upon above... don't clear it here and show the user nothing - 10/9/10 //_unitLogLines[queueIndex] = null; fahLogUnitData = new FahLogUnitData(); unitInfoLogData = new UnitInfoLogData(); } parsedUnits[queueIndex] = BuildUnitInfo(q.GetQueueEntry((uint)queueIndex), fahLogUnitData, unitInfoLogData, true); } else { // Just skip this unit and continue string message = String.Format(CultureInfo.CurrentCulture, "Could not find or verify log section for queue entry {0} (this is not a problem).", queueIndex); _logger.Debug(Constants.ClientNameFormat, ClientName, message); } } } return parsedUnits; }
private static ClientQueue BuildClientQueue(QueueData q) { Debug.Assert(q != null); var cq = Mapper.Map<QueueData, ClientQueue>(q); for (int i = 0; i < 10; i++) { cq.Add(i, Mapper.Map<QueueEntry, ClientQueueEntry>(q.GetQueueEntry((uint)i))); } return cq; }
private void GenerateUnitInfoDataFromQueue(DataAggregatorResult result, QueueData q, FahLog fahLog, UnitInfoLogData unitInfo) { Debug.Assert(q != null); result.UnitInfos = new Dictionary<int, UnitInfo>(10); for (int i = 0; i < 10; i++) { result.UnitInfos[i] = null; } var clientRun = GetCurrentClientRun(fahLog); for (int queueIndex = 0; queueIndex < result.UnitInfos.Count; queueIndex++) { var unitRun = GetUnitRunForQueueIndex(fahLog, queueIndex); UnitInfoLogData unitInfoLogData = null; // On the Current Queue Index if (queueIndex == q.CurrentIndex) { // Get the UnitInfo Log Data unitInfoLogData = unitInfo; } var queueEntry = q.GetQueueEntry((uint)queueIndex); result.UnitInfos[queueIndex] = BuildUnitInfo(queueEntry, clientRun, unitRun, unitInfoLogData); if (result.UnitInfos[queueIndex] == null) { if (queueIndex == q.CurrentIndex) { string message = String.Format(CultureInfo.CurrentCulture, "Could not verify log section for current queue index {0} {1}.", queueIndex, queueEntry.ToProjectInfo()); Logger.WarnFormat(Constants.ClientNameFormat, ClientName, message); unitRun = GetCurrentUnitRun(fahLog); var slotRun = GetCurrentSlotRun(fahLog); if (slotRun != null && slotRun.Data.Status == SlotStatus.GettingWorkPacket) { unitRun = null; unitInfoLogData = new UnitInfoLogData(); } result.UnitInfos[queueIndex] = BuildUnitInfo(queueEntry, clientRun, unitRun, unitInfoLogData, true); } else if (Logger.IsDebugEnabled) { // Write debug info and skip this unit var projectInfo = queueEntry.ToProjectInfo(); if (!projectInfo.ProjectIsUnknown()) { string message = String.Format(CultureInfo.CurrentCulture, "Could not find log section for queue index {0} {1}.", queueIndex, queueEntry.ToProjectInfo()); Logger.DebugFormat(Constants.ClientNameFormat, ClientName, message); } } } } }
/// <summary> /// Primary Constructor /// </summary> /// <param name="entry">Entry Structure</param> /// <param name="index">Entry Index</param> /// <param name="qData">The QueueData object that is creating this QueueEntry</param> internal QueueEntry(Entry entry, UInt32 index, QueueData qData) { _entry = entry; _index = index; _qData = qData; }