Ejemplo n.º 1
0
        public AppModelDetectionResult Get()
        {
            AppModelDetector detector = new AppModelDetector();
            var version = detector.Detect(new DirectoryInfo(Path.Combine(Environment.GetEnvironmentVariable("HOME_EXPANDED"), "site", "wwwroot")));

            return(version);
        }
Ejemplo n.º 2
0
        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");
        }