public async Task UploadDiagnosticLogsAsync()

in src/Agent.Worker/DiagnosticLogManager.cs [40:251]


        public async Task UploadDiagnosticLogsAsync(IExecutionContext executionContext,
                                         Pipelines.AgentJobRequestMessage message,
                                         DateTime jobStartTimeUtc)
        {
            ArgUtil.NotNull(executionContext, nameof(executionContext));
            ArgUtil.NotNull(message, nameof(message));

            executionContext.Debug("Starting diagnostic file upload.");

            // Setup folders
            // \_layout\_work\_temp\[jobname-support]
            executionContext.Debug("Setting up diagnostic log folders.");
            string tempDirectory = HostContext.GetDirectory(WellKnownDirectory.Temp);
            ArgUtil.Directory(tempDirectory, nameof(tempDirectory));

            string supportRootFolder = Path.Combine(tempDirectory, message.JobName + "-support");
            Directory.CreateDirectory(supportRootFolder);

            // \_layout\_work\_temp\[jobname-support]\files
            executionContext.Debug("Creating diagnostic log files folder.");
            string supportFilesFolder = Path.Combine(supportRootFolder, "files");
            Directory.CreateDirectory(supportFilesFolder);

            // Create the environment file
            // \_layout\_work\_temp\[jobname-support]\files\environment.txt
            var configurationStore = HostContext.GetService<IConfigurationStore>();
            AgentSettings settings = configurationStore.GetSettings();
            int agentId = settings.AgentId;
            string agentName = settings.AgentName;
            int poolId = settings.PoolId;

            executionContext.Debug("Creating diagnostic log environment file.");
            string environmentFile = Path.Combine(supportFilesFolder, "environment.txt");
            string content = await GetEnvironmentContent(agentId, agentName, message.Steps);
            File.WriteAllText(environmentFile, content);

            // Create the capabilities file
            var capabilitiesManager = HostContext.GetService<ICapabilitiesManager>();
            Dictionary<string, string> capabilities = await capabilitiesManager.GetCapabilitiesAsync(configurationStore.GetSettings(), default(CancellationToken));
            executionContext.Debug("Creating capabilities file.");
            string capabilitiesFile = Path.Combine(supportFilesFolder, "capabilities.txt");
            string capabilitiesContent = GetCapabilitiesContent(capabilities);
            File.WriteAllText(capabilitiesFile, capabilitiesContent);

            // Copy worker diag log files
            List<string> workerDiagLogFiles = GetWorkerDiagLogFiles(HostContext.GetDirectory(WellKnownDirectory.Diag), jobStartTimeUtc);
            executionContext.Debug($"Copying {workerDiagLogFiles.Count()} worker diag logs.");

            foreach (string workerLogFile in workerDiagLogFiles)
            {
                ArgUtil.File(workerLogFile, nameof(workerLogFile));

                string destination = Path.Combine(supportFilesFolder, Path.GetFileName(workerLogFile));
                File.Copy(workerLogFile, destination);
            }

            // Copy agent diag log files
            List<string> agentDiagLogFiles = GetAgentDiagLogFiles(HostContext.GetDirectory(WellKnownDirectory.Diag), jobStartTimeUtc);
            executionContext.Debug($"Copying {agentDiagLogFiles.Count()} agent diag logs.");

            foreach (string agentLogFile in agentDiagLogFiles)
            {
                ArgUtil.File(agentLogFile, nameof(agentLogFile));

                string destination = Path.Combine(supportFilesFolder, Path.GetFileName(agentLogFile));
                File.Copy(agentLogFile, destination);
            }

            // Read and add to logs waagent.conf settings on Linux
            if (PlatformUtil.RunningOnLinux)
            {
                executionContext.Debug("Dumping of waagent.conf file");
                string waagentDumpFile = Path.Combine(supportFilesFolder, "waagentConf.txt");

                string configFileName = "waagent.conf";
                try
                {
                    string filePath = Directory.GetFiles("/etc", configFileName).FirstOrDefault();
                    if (!string.IsNullOrWhiteSpace(filePath))
                    {
                        string waagentContent = File.ReadAllText(filePath);

                        File.AppendAllText(waagentDumpFile, "waagent.conf settings");
                        File.AppendAllText(waagentDumpFile, Environment.NewLine);
                        File.AppendAllText(waagentDumpFile, waagentContent);

                        executionContext.Debug("Dumping waagent.conf file is completed.");
                    }
                    else
                    {
                        executionContext.Debug("waagent.conf file wasn't found. Dumping was not done.");
                    }
                }
                catch (Exception ex)
                {
                    string warningMessage = $"Dumping of waagent.conf was not completed successfully. Error message: {ex.Message}";
                    executionContext.Warning(warningMessage);
                }
            }

            // Copy cloud-init log files from linux machines
            if (PlatformUtil.RunningOnLinux)
            {
                executionContext.Debug("Dumping cloud-init logs.");

                string logsFilePath = $"{HostContext.GetDirectory(WellKnownDirectory.Diag)}/cloudinit-{jobStartTimeUtc.ToString("yyyyMMdd-HHmmss")}-logs.tar.gz";
                string resultLogs = await DumpCloudInitLogs(logsFilePath);
                executionContext.Debug(resultLogs);

                if (File.Exists(logsFilePath))
                {
                    string destination = Path.Combine(supportFilesFolder, Path.GetFileName(logsFilePath));
                    File.Copy(logsFilePath, destination);
                    executionContext.Debug("Cloud-init logs added to the diagnostics archive.");
                }
                else
                {
                    executionContext.Debug("Cloud-init logs were not found.");
                }

                executionContext.Debug("Dumping cloud-init logs is ended.");
            }

            // Copy event logs for windows machines
            if (PlatformUtil.RunningOnWindows)
            {
                executionContext.Debug("Dumping event viewer logs for current job.");

                try
                {
                    string eventLogsFile = $"{HostContext.GetDirectory(WellKnownDirectory.Diag)}/EventViewer-{ jobStartTimeUtc.ToString("yyyyMMdd-HHmmss") }.log";
                    await DumpCurrentJobEventLogs(executionContext, eventLogsFile, jobStartTimeUtc);

                    string destination = Path.Combine(supportFilesFolder, Path.GetFileName(eventLogsFile));
                    File.Copy(eventLogsFile, destination);
                }
                catch (Exception ex)
                {
                    executionContext.Debug("Failed to dump event viewer logs. Skipping.");
                    executionContext.Debug($"Error message: {ex}");
                }
            }

            if (PlatformUtil.RunningOnLinux && !PlatformUtil.RunningOnRHEL6) {
                executionContext.Debug("Dumping info about invalid MD5 sums of installed packages.");

                try
                {
                    string packageVerificationResults = await GetPackageVerificationResult();
                    IEnumerable<string> brokenPackagesInfo = packageVerificationResults
                        .Split("\n")
                        .Where((line) => !String.IsNullOrEmpty(line) && !line.EndsWith("OK"));

                    string brokenPackagesLogsPath = $"{HostContext.GetDirectory(WellKnownDirectory.Diag)}/BrokenPackages-{ jobStartTimeUtc.ToString("yyyyMMdd-HHmmss") }.log";
                    File.AppendAllLines(brokenPackagesLogsPath, brokenPackagesInfo);

                    string destination = Path.Combine(supportFilesFolder, Path.GetFileName(brokenPackagesLogsPath));
                    File.Copy(brokenPackagesLogsPath, destination);
                }
                catch (Exception ex)
                {
                    executionContext.Debug("Failed to dump broken packages logs. Skipping.");
                    executionContext.Debug($"Error message: {ex}");
                }
            } else {
                executionContext.Debug("The platform is not based on Debian - skipping debsums check.");
            }

            try
            {
                executionContext.Debug("Starting dumping Agent Azure VM extension logs.");
                bool logsSuccessfullyDumped = DumpAgentExtensionLogs(executionContext, supportFilesFolder, jobStartTimeUtc);
                if (logsSuccessfullyDumped)
                {
                    executionContext.Debug("Agent Azure VM extension logs successfully dumped.");
                }
                else
                {
                    executionContext.Debug("Agent Azure VM extension logs not found. Skipping.");
                }
            }
            catch (Exception ex)
            {
                executionContext.Debug("Failed to dump Agent Azure VM extension logs. Skipping.");
                executionContext.Debug($"Error message: {ex}");
            }

            executionContext.Debug("Zipping diagnostic files.");

            string buildNumber = executionContext.Variables.Build_Number ?? "UnknownBuildNumber";
            string buildName = $"Build {buildNumber}";
            string phaseName = executionContext.Variables.System_PhaseDisplayName ?? "UnknownPhaseName";

            // zip the files
            string diagnosticsZipFileName = $"{buildName}-{phaseName}.zip";
            string diagnosticsZipFilePath = Path.Combine(supportRootFolder, diagnosticsZipFileName);
            ZipFile.CreateFromDirectory(supportFilesFolder, diagnosticsZipFilePath);

            // upload the json metadata file
            executionContext.Debug("Uploading diagnostic metadata file.");
            string metadataFileName = $"diagnostics-{buildName}-{phaseName}.json";
            string metadataFilePath = Path.Combine(supportFilesFolder, metadataFileName);
            string phaseResult = GetTaskResultAsString(executionContext.Result);

            IOUtil.SaveObject(new DiagnosticLogMetadata(agentName, agentId, poolId, phaseName, diagnosticsZipFileName, phaseResult), metadataFilePath);

            executionContext.QueueAttachFile(type: CoreAttachmentType.DiagnosticLog, name: metadataFileName, filePath: metadataFilePath);

            executionContext.QueueAttachFile(type: CoreAttachmentType.DiagnosticLog, name: diagnosticsZipFileName, filePath: diagnosticsZipFilePath);

            executionContext.Debug("Diagnostic file upload complete.");
        }