in GVFS/GVFS/CommandLine/DiagnoseVerb.cs [34:180]
protected override void Execute(GVFSEnlistment enlistment)
{
string diagnosticsRoot = Path.Combine(enlistment.DotGVFSRoot, "diagnostics");
if (!Directory.Exists(diagnosticsRoot))
{
Directory.CreateDirectory(diagnosticsRoot);
}
string archiveFolderPath = Path.Combine(diagnosticsRoot, "gvfs_" + DateTime.Now.ToString("yyyyMMdd_HHmmss"));
Directory.CreateDirectory(archiveFolderPath);
using (FileStream diagnosticLogFile = new FileStream(Path.Combine(archiveFolderPath, "diagnostics.log"), FileMode.CreateNew))
using (this.diagnosticLogFileWriter = new StreamWriter(diagnosticLogFile))
{
this.WriteMessage("Collecting diagnostic info into temp folder " + archiveFolderPath);
this.WriteMessage(string.Empty);
this.WriteMessage("gvfs version " + ProcessHelper.GetCurrentProcessVersion());
GitVersion gitVersion = null;
string error = null;
if (!string.IsNullOrEmpty(enlistment.GitBinPath) && GitProcess.TryGetVersion(enlistment.GitBinPath, out gitVersion, out error))
{
this.WriteMessage("git version " + gitVersion.ToString());
}
else
{
this.WriteMessage("Could not determine git version. " + error);
}
this.WriteMessage(enlistment.GitBinPath);
this.WriteMessage(string.Empty);
this.WriteMessage("Enlistment root: " + enlistment.EnlistmentRoot);
this.WriteMessage("Cache Server: " + CacheServerResolver.GetCacheServerFromConfig(enlistment));
string localCacheRoot;
string gitObjectsRoot;
this.GetLocalCachePaths(enlistment, out localCacheRoot, out gitObjectsRoot);
string actualLocalCacheRoot = !string.IsNullOrWhiteSpace(localCacheRoot) ? localCacheRoot : gitObjectsRoot;
this.WriteMessage("Local Cache: " + actualLocalCacheRoot);
this.WriteMessage(string.Empty);
this.PrintDiskSpaceInfo(actualLocalCacheRoot, this.EnlistmentRootPathParameter);
this.RecordVersionInformation();
this.ShowStatusWhileRunning(
() =>
this.RunAndRecordGVFSVerb<StatusVerb>(archiveFolderPath, "gvfs_status.txt") != ReturnCode.Success ||
this.RunAndRecordGVFSVerb<UnmountVerb>(archiveFolderPath, "gvfs_unmount.txt", verb => verb.SkipLock = true) == ReturnCode.Success,
"Unmounting",
suppressGvfsLogMessage: true);
this.ShowStatusWhileRunning(
() =>
{
// .gvfs
this.CopyAllFiles(enlistment.EnlistmentRoot, archiveFolderPath, GVFSPlatform.Instance.Constants.DotGVFSRoot, copySubFolders: false);
// driver
if (this.FlushKernelDriverLogs())
{
string kernelLogsFolderPath = GVFSPlatform.Instance.KernelDriver.LogsFolderPath;
// This copy sometimes fails because the OS has an exclusive lock on the etl files. The error is not actionable
// for the user so we don't write the error message to stdout, just to our own log file.
this.CopyAllFiles(Path.GetDirectoryName(kernelLogsFolderPath), archiveFolderPath, Path.GetFileName(kernelLogsFolderPath), copySubFolders: false, hideErrorsFromStdout: true);
}
// .git
this.CopyAllFiles(enlistment.WorkingDirectoryRoot, archiveFolderPath, GVFSConstants.DotGit.Root, copySubFolders: false);
this.CopyAllFiles(enlistment.WorkingDirectoryRoot, archiveFolderPath, GVFSConstants.DotGit.Hooks.Root, copySubFolders: false);
this.CopyAllFiles(enlistment.WorkingDirectoryRoot, archiveFolderPath, GVFSConstants.DotGit.Info.Root, copySubFolders: false);
this.CopyAllFiles(enlistment.WorkingDirectoryRoot, archiveFolderPath, GVFSConstants.DotGit.Logs.Root, copySubFolders: true);
this.CopyAllFiles(enlistment.WorkingDirectoryRoot, archiveFolderPath, GVFSConstants.DotGit.Refs.Root, copySubFolders: true);
this.CopyAllFiles(enlistment.WorkingDirectoryRoot, archiveFolderPath, GVFSConstants.DotGit.Objects.Info.Root, copySubFolders: false);
this.LogDirectoryEnumeration(enlistment.WorkingDirectoryRoot, Path.Combine(archiveFolderPath, GVFSConstants.DotGit.Objects.Root), GVFSConstants.DotGit.Objects.Pack.Root, "packs-local.txt");
this.LogLooseObjectCount(enlistment.WorkingDirectoryRoot, Path.Combine(archiveFolderPath, GVFSConstants.DotGit.Objects.Root), GVFSConstants.DotGit.Objects.Root, "objects-local.txt");
// databases
this.CopyAllFiles(enlistment.DotGVFSRoot, Path.Combine(archiveFolderPath, GVFSPlatform.Instance.Constants.DotGVFSRoot), GVFSConstants.DotGVFS.Databases.Name, copySubFolders: false);
// local cache
this.CopyLocalCacheData(archiveFolderPath, localCacheRoot, gitObjectsRoot);
// corrupt objects
this.CopyAllFiles(enlistment.DotGVFSRoot, Path.Combine(archiveFolderPath, GVFSPlatform.Instance.Constants.DotGVFSRoot), GVFSConstants.DotGVFS.CorruptObjectsName, copySubFolders: false);
// service
this.CopyAllFiles(
GVFSPlatform.Instance.GetCommonAppDataRootForGVFS(),
archiveFolderPath,
this.ServiceName,
copySubFolders: true);
this.CopyAllFiles(
GVFSPlatform.Instance.GetSecureDataRootForGVFS(),
archiveFolderPath,
this.ServiceName,
copySubFolders: true);
// service ui
this.CopyAllFiles(
GVFSPlatform.Instance.GetCommonAppDataRootForGVFS(),
archiveFolderPath,
GVFSConstants.Service.UIName,
copySubFolders: true);
if (GVFSPlatform.Instance.UnderConstruction.SupportsGVFSConfig)
{
this.CopyFile(GVFSPlatform.Instance.GetSecureDataRootForGVFS(), archiveFolderPath, LocalGVFSConfig.FileName);
}
if (!GVFSPlatform.Instance.TryCopyPanicLogs(archiveFolderPath, out string errorMessage))
{
this.WriteMessage(errorMessage);
}
return true;
},
"Copying logs");
this.ShowStatusWhileRunning(
() => this.RunAndRecordGVFSVerb<MountVerb>(archiveFolderPath, "gvfs_mount.txt") == ReturnCode.Success,
"Mounting",
suppressGvfsLogMessage: true);
this.CopyAllFiles(enlistment.DotGVFSRoot, Path.Combine(archiveFolderPath, GVFSPlatform.Instance.Constants.DotGVFSRoot), "logs", copySubFolders: false);
}
string zipFilePath = archiveFolderPath + ".zip";
this.ShowStatusWhileRunning(
() =>
{
ZipFile.CreateFromDirectory(archiveFolderPath, zipFilePath);
this.fileSystem.DeleteDirectory(archiveFolderPath);
return true;
},
"Creating zip file",
suppressGvfsLogMessage: true);
this.Output.WriteLine();
this.Output.WriteLine("Diagnostics complete. All of the gathered info, as well as all of the output above, is captured in");
this.Output.WriteLine(zipFilePath);
}