public AppModelDetectionResult Get() { AppModelDetector detector = new AppModelDetector(); var version = detector.Detect(new DirectoryInfo(Path.Combine(Environment.GetEnvironmentVariable("HOME_EXPANDED"), "site", "wwwroot"))); return(version); }
static void Main(string[] args) { int processId = 0; string daasOutputFilePath = args[0]; bool Is64bit = false; bool collectRawStacks = args.Contains("collectRawStacks") ? true : false; bool cpuStacksOnly = args.Contains("cpuStacksOnly") ? true : false; if (cpuStacksOnly) { collectRawStacks = false; } Logger.Init("", daasOutputFilePath, "ClrProfilingCollector", true); ClrProfilingCollectorStats stats = new ClrProfilingCollectorStats { StatsType = "ClrProfilingCollector" }; bool failedToIdentifyProcessToTrace = false; var childProcesses = new List <int>(); var childProcessNames = new List <string>(); try { AppModelDetector detector = new AppModelDetector(); var webconfigPath = new DirectoryInfo(Path.Combine(Environment.GetEnvironmentVariable("HOME_EXPANDED"), "site", "wwwroot")); if (webconfigPath.Exists) { var version = detector.Detect(webconfigPath); if (!string.IsNullOrWhiteSpace(version.CoreProcessName)) { Logger.LogDiagnoserVerboseEvent($".Net Core detected - need to trace {version.CoreProcessName} as well"); childProcessNames.Add(version.CoreProcessName); } } } catch (Exception ex) { Logger.LogDiagnoserErrorEvent("Failed while reading configuration to check for .net core processes", ex); } foreach (var process in Process.GetProcesses()) { if (process.ProcessName == "w3wp" && processId == 0) { try { var envVar = DaaS.Utilities.GetEnvironmentVariablesCore(process.Handle); if (!DaaS.Utilities.GetIsScmSite(envVar)) { processId = process.Id; stats.ProcessId = processId; stats.InstanceName = Environment.MachineName; stats.SiteName = Logger.SiteName; stats.ActivityId = Logger.ActivityId; if (DaaS.Utilities.GetProcessBitness(process.Handle) == 64) { Is64bit = true; } } } catch (Exception ex) { Logger.LogDiagnoserErrorEvent("Finding right process failed", ex); failedToIdentifyProcessToTrace = true; } } else if (!string.IsNullOrWhiteSpace(process.ProcessName) && childProcessNames.Contains(process.ProcessName.ToLower())) { if (!childProcesses.Contains(process.Id) && process.Id != 0) { stats.DotNetCoreProcess = process.ProcessName; Logger.LogDiagnoserVerboseEvent($"Added {process.Id} for {process.ProcessName} to the list of child processes to trace"); childProcesses.Add(process.Id); } } } if (processId == 0) { if (failedToIdentifyProcessToTrace == true) { Logger.TraceFatal("Failed to identify the process to trace. Please check the diaglog file for more information."); } else { Logger.TraceFatal("w3wp.exe for the Web App is not running. Before collecting a profiler trace, make sure that the worker process is started by making a request."); } return; } Logger.LogDiagnoserVerboseEvent($"Process to Trace is {processId.ToString()} on instance { Environment.MachineName } "); var sleepDuration = ProfileManager.GetIisProfilingDuration().TotalSeconds; stats.TraceDurationInSeconds = sleepDuration; var startProfilingTime = DateTime.Now; Logger.LogStatus("Starting profiler session"); var result = ProfileManager.StartProfile(processId, !cpuStacksOnly, childProcesses.ToArray()); if (result.StatusCode != System.Net.HttpStatusCode.OK) { Logger.TraceFatal($"Failed to profile process {processId.ToString()}. Profiling call failed with {result.StatusCode }", false); Logger.LogDiagnoserErrorEvent($"Failed to start profiling for the process", $"Profiling call failed with {result.StatusCode } and message {result.Message}"); return; } else { Logger.LogDiagnoserEvent($"CLRProfilingSession Started with duration {sleepDuration}s"); } var timeToStartProfile = DateTime.Now.Subtract(startProfilingTime).TotalSeconds; stats.TimeToStartTraceInSeconds = timeToStartProfile; Logger.LogInfo(string.Format("Started sleeping for {0} seconds", sleepDuration)); Logger.LogStatus($"Profiler session started. Profiler will stop automatically after {sleepDuration} seconds. At this point, please reproduce the problem or browse to your WebApp to ensure that requests get captured in the trace"); while (sleepDuration != 0) { Thread.Sleep(10 * 1000); sleepDuration = sleepDuration - 10; Logger.LogInfo(string.Format("{0} seconds remaining", sleepDuration)); } var stopProfilingTime = DateTime.Now; Logger.LogStatus("Stopping profiler session"); bool stopRetried = false; stopProfilingLabel: try { result = ProfileManager.StopProfile(processId); if (result.StatusCode != System.Net.HttpStatusCode.OK) { if (!stopRetried) { stopRetried = true; Logger.LogDiagnoserErrorEvent($"Failed to stop profiling for the process, going to retry once", $"Profiling call failed with {result.StatusCode } and message {result.Message}"); Thread.Sleep(5000); goto stopProfilingLabel; } else { Logger.LogDiagnoserErrorEvent($"Failed to stop profiling for the process", $"Profiling call failed with {result.StatusCode } and message {result.Message}"); Logger.TraceFatal($"Failed to stop profiling for process { processId.ToString() }. Profiling call failed with { result.StatusCode }", false); return; } } } catch (Exception ex) { Logger.TraceFatal($"Failed while stopping profiler with exception - {ex.Message}", false); Logger.LogDiagnoserErrorEvent("Failed while stopping profiler", ex); } Logger.LogStatus($"Profiler session stopped"); var timeToStopProfile = DateTime.Now.Subtract(stopProfilingTime).TotalSeconds; stats.TimeToStopTraceInSeconds = timeToStopProfile; string filePath = result.FilePath; stats.TraceFileName = filePath; stats.TraceFileSizeInMb = GetFileSize(filePath); try { if (File.Exists(filePath)) { string zipFolderPath = CreateZipFolder(filePath); if (collectRawStacks) { Logger.LogStatus("Collecting raw stack-traces"); var timeToCollectStackTraces = DateTime.Now; CollectStackTracerLog(zipFolderPath, processId, Is64bit); stats.TimeToGenerateRawStackTraces = DateTime.Now.Subtract(timeToCollectStackTraces).TotalSeconds; Logger.LogInfo($"Took [{stats.TimeToGenerateRawStackTraces} s] to generate stacktraces."); Logger.LogStatus("Collected raw stack-traces"); } var zipFile = AddCollectedDataToZip(zipFolderPath, filePath); // Copy the file to DAAS output folders var daasOutputFolder = Path.Combine(daasOutputFilePath, Path.GetFileName(zipFile)); File.Copy(zipFile, daasOutputFolder, true); Logger.LogDiagnoserVerboseEvent($"Copied temporary file [{zipFile}] to DAAS Folders [{daasOutputFolder}]"); try { // Delete the file generated by the Profiler as we already copied that to the DAAS folders File.Delete(zipFile); Logger.LogInfo($"Deleted [{zipFile}]"); foreach (var file in Directory.GetFiles(zipFolderPath)) { try { File.Delete(file); Logger.LogDiagnoserVerboseEvent($"Deleted {file}"); } catch (Exception) { } } Directory.Delete(zipFolderPath); Logger.LogDiagnoserVerboseEvent($"Deleted folder {zipFolderPath}"); } catch (Exception ex) { Logger.LogDiagnoserErrorEvent($"Failed to cleanup temporary zip files and folders", ex); } } } catch (Exception ex) { Logger.TraceFatal($"Failed while copying the trace file - {filePath} \n {ex.Message} \n { ex.StackTrace} "); } Logger.TraceStats(JsonConvert.SerializeObject(stats)); Logger.LogDiagnoserEvent($"CLRProfilingSession completed"); }