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.");
}