/// <summary> /// Ensures that a log path is created, calls <see cref="o:DumpPipLiteAnalysisUtilities.DumpPip"/>, and updates /// the state of the analyzer if it runs into an error. /// </summary> /// <param name="pip">Pip to be dumped.</param> /// <param name="dynamicData"> Dynamic data to be dumped.</param> /// <param name="currentNumLogFiles">The current number of dump pip lite files that have been created.</param> private void DumpPip(Pip pip, ProcessExecutionMonitoringReportedEventData?dynamicData, int currentNumLogFiles) { var dumpPipResult = false; if (!m_logPathCreated) { // A log entry should have been generated already if this fails m_logPathCreated = DumpPipLiteAnalysisUtilities.CreateLoggingDirectory(m_logPath.ToString(m_pipExecutionContext.PathTable), m_loggingContext); } if (m_logPathCreated) { // A log entry should have been generated already if this fails dumpPipResult = DumpPipLiteAnalysisUtilities.DumpPip(pip, dynamicData, m_logPath.ToString(m_pipExecutionContext.PathTable), m_pipExecutionContext.PathTable, m_pipExecutionContext.StringTable, m_pipExecutionContext.SymbolTable, m_pipGraph, m_loggingContext); } if (!(m_logPathCreated && dumpPipResult)) { // This failure was already logged in DumpPipLiteAnalysisUtilies m_loggingErrorOccured = true; } if (currentNumLogFiles >= m_maxLogFiles) { // Log limit reached, log this once Logger.Log.RuntimeDumpPipLiteLogLimitReached(m_loggingContext, m_maxLogFiles); } }
/// <summary> /// Hooks into the log target for pip execution performance data which will be called /// when a pip fails. This will then dump relevant information on the failing pip /// to a JSON file specified under <see cref="m_logPath"/>. /// The maximum number of logs generated can be specified using the /// /DumpFailedPipsLogCount parameter. /// </summary> /// <remarks> /// If an error occurs while serializing/dumping the specified pip, /// then this analyzer will be disabled for the remainder of this build and /// a warning will be logged with more details. /// </remarks> public override void PipExecutionPerformance(PipExecutionPerformanceEventData data) { if (data.ExecutionPerformance.ExecutionLevel == PipExecutionLevel.Failed && !m_loggingErrorOccured) { var currentNumLogFiles = Interlocked.Increment(ref m_numLogFilesGenerated); if (currentNumLogFiles <= m_maxLogFiles) { var dumpPipResult = false; if (!m_logPathCreated) { // A log entry should have been generated already if this fails m_logPathCreated = DumpPipLiteAnalysisUtilities.CreateLoggingDirectory(m_logPath.ToString(m_pipExecutionContext.PathTable), m_loggingContext); } if (m_logPathCreated) { var pip = m_pipTable.HydratePip(data.PipId, PipQueryContext.DumpPipLiteAnalyzer); // A log entry should have been generated already if this fails dumpPipResult = DumpPipLiteAnalysisUtilities.DumpPip(pip, m_logPath.ToString(m_pipExecutionContext.PathTable), m_pipExecutionContext.PathTable, m_pipExecutionContext.StringTable, m_pipExecutionContext.SymbolTable, m_pipGraph); } if (!(m_logPathCreated && dumpPipResult)) { // This failure was already logged in DumpPipLiteAnalysisUtilies m_loggingErrorOccured = true; } if (currentNumLogFiles >= m_maxLogFiles) { // Log limit reached, log this once Logger.Log.RuntimeDumpPipLiteLogLimitReached(m_loggingContext, m_maxLogFiles); } } } }