public void ScheduleSimilarityAnalysis(DumpMetainfo dumpInfo, bool force, DateTime timeFrom) { if (!settings.Value.SimilarityDetectionEnabled) { return; } // schedule actual analysis var outgoingMessageTracer = dynatraceSdk.TraceOutgoingMessage(messagingSystemInfo); outgoingMessageTracer.Trace(() => { string jobId = Hangfire.BackgroundJob.Enqueue <SimilarityService>(repo => repo.CalculateSimilarity(dumpInfo, force, timeFrom, outgoingMessageTracer.GetDynatraceByteTag())); outgoingMessageTracer.SetVendorMessageId(jobId); }); }
public override async Task AnalyzeDump(DumpMetainfo dumpInfo) { BundleMetainfo bundle = bundleRepo.Get(dumpInfo.BundleId); try { SDResult result = await dumpRepo.GetResultAndThrow(dumpInfo.Id); if (result != null) { await elasticSearch.PushResultAsync(result, bundle, dumpInfo); } } catch (Exception ex) { Console.WriteLine(ex.Message); } }
private string ReadCustomTextResult(DumpMetainfo dumpInfo) { SDFileEntry customResultFile = dumpInfo.Files.SingleOrDefault(x => x.Type == SDFileType.CustomTextResult); if (customResultFile == null) { return(null); } FileInfo file = dumpStorage.GetFile(dumpInfo.BundleId, dumpInfo.DumpId, customResultFile.FileName); if (!file.Exists) { return(null); } return(System.IO.File.ReadAllText(file.FullName)); }
private async Task <string> ReadCustomTextResult(DumpMetainfo dumpInfo) { SDFileEntry customResultFile = dumpInfo.Files.FirstOrDefault(x => x.Type == SDFileType.CustomTextResult); if (customResultFile == null) { return(null); } FileInfo file = dumpStorage.GetFile(dumpInfo.BundleId, dumpInfo.DumpId, customResultFile.FileName); if (file == null || !file.Exists) { return(null); } return(await System.IO.File.ReadAllTextAsync(file.FullName)); }
public void ScheduleDumpAnalysis(DumpMetainfo dumpInfo) { string analysisWorkingDir = pathHelper.GetDumpDirectory(dumpInfo.Id); if (!Directory.Exists(analysisWorkingDir)) { throw new DirectoryNotFoundException($"id: {dumpInfo.Id}"); } // schedule actual analysis var outgoingMessageTracer = dynatraceSdk.TraceOutgoingMessage(messagingSystemInfo); outgoingMessageTracer.Trace(() => { string jobId = Hangfire.BackgroundJob.Enqueue <AnalysisService>(repo => Analyze(dumpInfo, analysisWorkingDir, outgoingMessageTracer.GetDynatraceByteTag())); outgoingMessageTracer.SetVendorMessageId(jobId); }); }
public async Task AnalyzeAsync(DumpMetainfo dumpInfo, string dumpFilePath, string analysisWorkingDir) { await BlockIfBundleRepoNotReady($"AnalysisService.Analyze for {dumpInfo.Id}"); try { dumpRepo.SetDumpStatus(dumpInfo.Id, DumpStatus.Analyzing); if (dumpInfo.DumpType == DumpType.WindowsDump) { await AnalyzeWindows(dumpInfo, new DirectoryInfo(analysisWorkingDir), dumpFilePath); } else if (dumpInfo.DumpType == DumpType.LinuxCoreDump) { await LinuxAnalyzationAsync(dumpInfo, new DirectoryInfo(analysisWorkingDir), dumpFilePath); } else { throw new Exception("unknown dumptype. here be dragons"); } // Re-fetch dump info as it was updated dumpInfo = dumpRepo.Get(dumpInfo.Id); SDResult result = await dumpRepo.GetResultAndThrow(dumpInfo.Id); if (result != null) { dumpRepo.WriteResult(dumpInfo.Id, result); dumpRepo.SetDumpStatus(dumpInfo.Id, DumpStatus.Finished); var bundle = bundleRepo.Get(dumpInfo.BundleId); await elasticSearch.PushResultAsync(result, bundle, dumpInfo); } } catch (Exception e) { Console.WriteLine(e.Message); dumpRepo.SetDumpStatus(dumpInfo.Id, DumpStatus.Failed, e.ToString()); } finally { if (settings.Value.DeleteDumpAfterAnalysis) { dumpStorage.DeleteDumpFile(dumpInfo.Id); } await notifications.NotifyDumpAnalysisFinished(dumpInfo); similarityService.ScheduleSimilarityAnalysis(dumpInfo, false, DateTime.Now - TimeSpan.FromDays(settings.Value.SimilarityDetectionMaxDays)); } }
public IEnumerable <SDFileInfo> GetSDFileInfos(DumpMetainfo dumpInfo) { foreach (var filePath in Directory.EnumerateFiles(pathHelper.GetDumpDirectory(dumpInfo.Id))) { // in case the requested file has a "special" entry in FileEntry list, add that information FileInfo fileInfo = new FileInfo(filePath); SDFileEntry fileEntry = GetSDFileEntry(dumpInfo, fileInfo); yield return(new SDFileInfo() { FileInfo = fileInfo, FileEntry = fileEntry, SizeInBytes = fileInfo.Length, Downloadable = fileEntry.Type != SDFileType.PrimaryDump || settings.Value.DumpDownloadable }); } }
private async Task <DumpViewModel> ToDumpViewModel(DumpMetainfo dumpMetainfo, bool includeSimilarities = false) { if (dumpMetainfo == null) { return(null); } var similarities = !includeSimilarities ? null : new Similarities(await similarityService.GetSimilarities(dumpMetainfo.Id)); return(new DumpViewModel(dumpMetainfo, new BundleViewModel(bundleRepo.Get(dumpMetainfo.BundleId)), similarities, new RetentionViewModel( dumpMetainfo, dumpRepo.IsPrimaryDumpAvailable(dumpMetainfo.Id), TimeSpan.FromDays(settings.WarnBeforeDeletionInDays), settings.UseJiraIntegration && jiraIssueRepository.IsPopulated && jiraIssueRepository.HasBundleOpenIssues(dumpMetainfo.BundleId)))); }
public async Task NotifyDumpAnalysisFinished(DumpMetainfo dumpInfo) { if (this.webhookUrls == null) { return; } try { string msg = await GetMessage(dumpInfo); foreach (string webhook in webhookUrls) { await SendMessage(webhook, msg); } } catch (Exception e) { Console.WriteLine($"Slack notifications failed: {e}"); } }
private async Task IncludeOtherFiles(DirectoryInfo dir, DumpMetainfo dumpInfo, HashSet <string> foundPrimaryDumps) { if (settings.Value.IncludeOtherFilesInReport) { foreach (FileInfo siblingFile in dir.EnumerateFiles()) { if (UnpackService.IsSupportedArchive(siblingFile.Name)) { continue; } if (foundPrimaryDumps.Contains(siblingFile.Name)) { continue; } await dumpRepo.AddFileCopy(dumpInfo.Id, siblingFile, SDFileType.SiblingFile); } } }
public void ScheduleDumpAnalysis(DumpMetainfo dumpInfo) { string dumpFilePath = dumpStorage.GetDumpFilePath(dumpInfo.BundleId, dumpInfo.DumpId); if (!File.Exists(dumpFilePath)) { throw new DumpNotFoundException($"bundleid: {dumpInfo.BundleId}, dumpid: {dumpInfo.DumpId}, path: {dumpFilePath}"); } string analysisWorkingDir = pathHelper.GetDumpDirectory(dumpInfo.BundleId, dumpInfo.DumpId); if (!Directory.Exists(analysisWorkingDir)) { throw new DirectoryNotFoundException($"bundleid: {dumpInfo.BundleId}, dumpid: {dumpInfo.DumpId}, path: {dumpFilePath}"); } // schedule actual analysis Hangfire.BackgroundJob.Enqueue <AnalysisService>(repo => Analyze(dumpInfo, dumpFilePath, analysisWorkingDir)); // got a stackoverflow problem here. }
private async Task LinuxAnalyzationAsync(DumpMetainfo dumpInfo, DirectoryInfo workingDir, string dumpFilePath) { string command = settings.Value.LinuxAnalysisCommand; if (string.IsNullOrEmpty(command)) { throw new ArgumentNullException("'LinuxCommandTemplate' setting is not configured."); } command = command.Replace("{bundleid}", dumpInfo.BundleId); command = command.Replace("{dumpid}", dumpInfo.DumpId); command = command.Replace("{dumpdir}", workingDir.FullName); command = command.Replace("{dumppath}", dumpFilePath); command = command.Replace("{dumpname}", Path.GetFileName(dumpFilePath)); command = command.Replace("{outputpath}", pathHelper.GetJsonPath(dumpInfo.BundleId, dumpInfo.DumpId)); command = command.Replace("{outputname}", Path.GetFileName(pathHelper.GetJsonPath(dumpInfo.BundleId, dumpInfo.DumpId))); Utility.ExtractExe(command, out string executable, out string arguments); Console.WriteLine($"running exe='{executable}', args='{arguments}'"); using (var process = await ProcessRunner.Run(executable, workingDir, arguments)) { Console.WriteLine($"stdout: {process.StdOut}"); Console.WriteLine($"stderr: {process.StdErr}"); if (process.StdOut?.Length > 0) { File.WriteAllText(Path.Combine(pathHelper.GetDumpDirectory(dumpInfo.BundleId, dumpInfo.DumpId), "linux-analysis.log"), process.StdOut); } if (process.StdErr?.Length > 0) { File.WriteAllText(Path.Combine(pathHelper.GetDumpDirectory(dumpInfo.BundleId, dumpInfo.DumpId), "linux-analysis.err.log"), process.StdErr); } if (process.ExitCode != 0) { LinuxAnalyzerExitCode exitCode = (LinuxAnalyzerExitCode)process.ExitCode; string error = $"Exit code {process.ExitCode}: {exitCode.Message}"; Console.WriteLine(error); throw new Exception(error); } } }
private async Task AnalyzeWindows(DumpMetainfo dumpInfo, DirectoryInfo workingDir, string dumpFilePath) { string dumpselector = "SuperDumpSelector.exe"; // should be on PATH Console.WriteLine($"launching '{dumpselector}' '{dumpFilePath}'"); using (var process = await ProcessRunner.Run(dumpselector, workingDir, WrapInQuotes(dumpFilePath), WrapInQuotes(pathHelper.GetJsonPath(dumpInfo.BundleId, dumpInfo.DumpId)))) { string selectorLog = $"SuperDumpSelector exited with error code {process.ExitCode}" + $"{Environment.NewLine}{Environment.NewLine}stdout:{Environment.NewLine}{process.StdOut}" + $"{Environment.NewLine}{Environment.NewLine}stderr:{Environment.NewLine}{process.StdErr}"; Console.WriteLine(selectorLog); File.WriteAllText(Path.Combine(pathHelper.GetDumpDirectory(dumpInfo.BundleId, dumpInfo.DumpId), "superdumpselector.log"), selectorLog); if (process.ExitCode != 0) { dumpRepo.SetDumpStatus(dumpInfo.BundleId, dumpInfo.DumpId, DumpStatus.Failed, selectorLog); throw new Exception(selectorLog); } } await RunDebugDiagAnalysis(dumpInfo, workingDir, dumpFilePath); }
private async Task CreateMetainfoForCompat(DumpIdentifier id) { var metainfo = new DumpMetainfo() { BundleId = id.BundleId, DumpId = id.DumpId }; var result = await ReadResults(id); if (result != null) { metainfo.Status = DumpStatus.Finished; metainfo.DumpFileName = result.AnalysisInfo.Path?.Replace(pathHelper.GetUploadsDir(), ""); // AnalysisInfo.FileName used to store full file names. e.g. "C:\superdump\uploads\myzipfilename\subdir\dump.dmp". lets only keep "myzipfilename\subdir\dump.dmp" metainfo.Created = result.AnalysisInfo.ServerTimeStamp; } else { metainfo.Status = DumpStatus.Failed; } WriteMetainfoFile(metainfo, pathHelper.GetDumpMetadataPath(id)); }
private async Task AnalyzeLinux(DumpMetainfo dumpInfo, DirectoryInfo workingDir, string dumpFilePath) { string command = settings.Value.LinuxCommandTemplate; if (string.IsNullOrEmpty(command)) { throw new ArgumentNullException("'LinuxCommandTemplate' setting is not configured."); } command = command.Replace("{coredump}", dumpFilePath); command = command.Replace("{outputjson}", pathHelper.GetJsonPath(dumpInfo.BundleId, dumpInfo.DumpId)); var parts = command.Split(' '); string executable = parts.First(); string arguments = string.Join(" ", parts.Skip(1).ToArray()); Console.WriteLine($"running exe='{executable}', args='{arguments}'"); using (var process = await ProcessRunner.Run(executable, workingDir, arguments)) { File.WriteAllText(Path.Combine(workingDir.FullName, "linux-analysis.txt"), process.StdOut); dumpRepo.AddFile(dumpInfo.BundleId, dumpInfo.DumpId, "linux-analysis.txt", SDFileType.CustomTextResult); } }
public async Task Analyze(DumpMetainfo dumpInfo, string dumpFilePath, string analysisWorkingDir) { try { dumpRepo.SetDumpStatus(dumpInfo.BundleId, dumpInfo.DumpId, DumpStatus.Analyzing); if (dumpInfo.DumpType == DumpType.WindowsDump) { await AnalyzeWindows(dumpInfo, new DirectoryInfo(analysisWorkingDir), dumpFilePath); } else if (dumpInfo.DumpType == DumpType.LinuxCoreDump) { await LinuxAnalyzationAsync(dumpInfo, new DirectoryInfo(analysisWorkingDir), dumpFilePath); } else { throw new Exception("unknown dumptype. here be dragons"); } dumpRepo.SetDumpStatus(dumpInfo.BundleId, dumpInfo.DumpId, DumpStatus.Finished); // Re-fetch dump info as it was updated dumpInfo = dumpRepo.Get(dumpInfo.BundleId, dumpInfo.DumpId); SDResult result = dumpRepo.GetResult(dumpInfo.BundleId, dumpInfo.DumpId, out string err); if (result != null) { var bundle = bundleRepo.Get(dumpInfo.BundleId); await elasticSearch.PushResultAsync(result, bundle, dumpInfo); } } catch (Exception e) { Console.WriteLine(e.Message); dumpRepo.SetDumpStatus(dumpInfo.BundleId, dumpInfo.DumpId, DumpStatus.Failed, e.ToString()); } finally { if (settings.Value.DeleteDumpAfterAnalysis) { dumpStorage.DeleteDumpFile(dumpInfo.BundleId, dumpInfo.DumpId); } await notifications.NotifyDumpAnalysisFinished(dumpInfo); } }
private void CreateMetainfoForCompat(string bundleId, string dumpId) { var metainfo = new DumpMetainfo() { BundleId = bundleId, DumpId = dumpId }; var result = ReadResults(bundleId, dumpId, out string error); if (result != null) { metainfo.Status = DumpStatus.Finished; metainfo.DumpFileName = result.AnalysisInfo.Path?.Replace(pathHelper.GetUploadsDir(), ""); // AnalysisInfo.FileName used to store full file names. e.g. "C:\superdump\uploads\myzipfilename\subdir\dump.dmp". lets only keep "myzipfilename\subdir\dump.dmp" metainfo.Created = result.AnalysisInfo.ServerTimeStamp; } else { metainfo.Status = DumpStatus.Failed; } WriteMetainfoFile(metainfo, pathHelper.GetDumpMetadataPath(bundleId, dumpId)); }
/// <summary> /// Deletes dump files from dumps that are older than the configured retention time. /// There is no exception handling because exceptions are visible in Hangfire as opposed to log messages. /// </summary> private void RemoveOldDumps(DumpMetainfo dump) { string dumpDirectory = pathHelper.GetDumpDirectory(dump.BundleId, dump.DumpId); if (!Directory.Exists(dumpDirectory)) { return; } Console.WriteLine($"[DumpRetention] Deleting dump {dump.BundleId}/{dump.DumpId}"); // Delete all directories in the dump directory foreach (var subdir in Directory.EnumerateDirectories(dumpDirectory)) { Directory.Delete(subdir, true); } // Delete all dump files in the dump directory foreach (var file in Directory.EnumerateFiles(dumpDirectory)) { if (file.EndsWith(".core.gz") || file.EndsWith("libs.tar.gz") || file.EndsWith(".dmp")) { File.Delete(file); } } }
private async Task IncludeOtherFiles(string bundleId, FileInfo file, DumpMetainfo dumpInfo) { if (settings.Value.IncludeOtherFilesInReport) { var dir = file.Directory; foreach (var siblingFile in dir.EnumerateFiles()) { if (siblingFile.FullName == file.FullName) { continue; // don't add actual dump file twice } if (siblingFile.Name.EndsWith(".dmp", StringComparison.OrdinalIgnoreCase)) { continue; // don't include other dumps from same dir } if (siblingFile.Name.EndsWith(".core.gz", StringComparison.OrdinalIgnoreCase)) { continue; // don't include other dumps from same dir } await dumpRepo.AddFileCopy(bundleId, dumpInfo.DumpId, siblingFile, SDFileType.SiblingFile); } } }
private async Task RunDebugDiagAnalysis(DumpMetainfo dumpInfo, DirectoryInfo workingDir, string dumpFilePath) { //--dump = "C:\superdump\data\dumps\hno3391\iwb0664\iwb0664.dmp"--out= "C:\superdump\data\dumps\hno3391\iwb0664\debugdiagout.mht"--symbolPath = "cache*c:\localsymbols;http://msdl.microsoft.com/download/symbols"--overwrite string reportFilePath = Path.Combine(pathHelper.GetDumpDirectory(dumpInfo.Id), "DebugDiagAnalysis.mht"); string debugDiagExe = "SuperDump.DebugDiag.exe"; var tracer = dynatraceSdk.TraceOutgoingRemoteCall("Analyze", debugDiagExe, debugDiagExe, ChannelType.OTHER, debugDiagExe); try { await tracer.TraceAsync(async() => { using (var process = await ProcessRunner.Run(debugDiagExe, workingDir, $"--dump=\"{dumpFilePath}\"", $"--out=\"{reportFilePath}\"", "--overwrite", $"--tracetag \"{tracer.GetDynatraceStringTag()}\"" )) { string log = $"debugDiagExe exited with error code {process.ExitCode}" + $"{Environment.NewLine}{Environment.NewLine}stdout:{Environment.NewLine}{process.StdOut}" + $"{Environment.NewLine}{Environment.NewLine}stderr:{Environment.NewLine}{process.StdErr}"; Console.WriteLine(log); File.WriteAllText(Path.Combine(pathHelper.GetDumpDirectory(dumpInfo.Id), "superdump.debugdiag.log"), log); dumpRepo.AddFile(dumpInfo.Id, "DebugDiagAnalysis.mht", SDFileType.DebugDiagResult); } }); } catch (ProcessRunnerException e) { if (e.InnerException is FileNotFoundException) { Console.Error.WriteLine($"{debugDiagExe} not found. Check BinPath setting in appsettings.json."); } else { Console.Error.WriteLine($"Error during DebugDiag analyis: {e}"); } // do not abort analysis. } }
public async Task CalculateSimilarityAsync(DumpMetainfo dumpA, bool force, DateTime timeFrom) { try { var swTotal = new Stopwatch(); swTotal.Start(); if (!dumpRepo.IsPopulated) { Console.WriteLine($"CalculateSimilarity for {dumpA.Id} is blocked because dumpRepo is not yet fully populated..."); await Utility.BlockUntil(() => dumpRepo.IsPopulated); Console.WriteLine($"...continuing CalculateSimilarity for {dumpA.Id}."); } var resultA = await GetOrCreateMiniInfo(dumpA.Id); var allDumps = dumpRepo.GetAll().Where(x => x.Created >= timeFrom).OrderBy(x => x.Created); Console.WriteLine($"starting CalculateSimilarity for {allDumps.Count()} dumps; {dumpA} (TID:{Thread.CurrentThread.ManagedThreadId})"); foreach (var dumpB in allDumps) { if (!force) { var existingSimilarity = await relationShipRepo.GetRelationShip(dumpA.Id, dumpB.Id); if (existingSimilarity != 0) { // relationship already exists. skip! // but make sure the relationship is stored bi-directional await relationShipRepo.UpdateSimilarity(dumpA.Id, dumpB.Id, existingSimilarity); continue; } } if (!PreSelectOnMetadata(dumpA, dumpB)) { continue; } var resultB = await GetOrCreateMiniInfo(dumpB.Id); if (!PreSelectOnResults(resultA, resultB)) { continue; } CrashSimilarity crashSimilarity = CrashSimilarity.Calculate(resultA, resultB); // only store value if above a certain threshold to avoid unnecessary disk writes if (crashSimilarity.OverallSimilarity > 0.6) { await relationShipRepo.UpdateSimilarity(dumpA.Id, dumpB.Id, crashSimilarity.OverallSimilarity); } //Console.WriteLine($"CalculateSimilarity.Finished for {dumpA}/{dumpB} ({i} to go...); (elapsed: {sw.Elapsed}) (TID:{Thread.CurrentThread.ManagedThreadId})"); } await relationShipRepo.FlushDirtyRelationships(); swTotal.Stop(); Console.WriteLine($"CalculateSimilarity.Finished for all {allDumps.Count()} dumps (total elapsed: {swTotal.Elapsed}); {dumpA} (TID:{Thread.CurrentThread.ManagedThreadId})"); } catch (Exception e) { Console.Error.WriteLine($"CalculateSimilarity failed: {e}"); } }
private void WriteMetainfoFile(DumpMetainfo metaInfo, string filename) { File.WriteAllText(filename, JsonConvert.SerializeObject(metaInfo, Formatting.Indented)); }
private SDFileEntry GetSDFileEntry(DumpMetainfo dumpInfo, FileInfo fileInfo) { // the file should be registered in dumpInfo SDFileEntry fileEntry = dumpInfo.Files.Where(x => x.FileName == fileInfo.Name).FirstOrDefault(); // due to a bug, multiple entries for the same file could exist if (fileEntry != null) { return(fileEntry); } // but if it's not registered, do some heuristic to figure out which type of file it is. fileEntry = new SDFileEntry() { FileName = fileInfo.Name }; if (Path.GetFileName(pathHelper.GetJsonPath(dumpInfo.BundleId, dumpInfo.DumpId)) == fileInfo.Name) { fileEntry.Type = SDFileType.SuperDumpMetaData; return(fileEntry); } if (Path.GetFileName(pathHelper.GetDumpMetadataPath(dumpInfo.BundleId, dumpInfo.DumpId)) == fileInfo.Name) { fileEntry.Type = SDFileType.SuperDumpMetaData; return(fileEntry); } if ("windbg.log" == fileInfo.Name) { fileEntry.Type = SDFileType.WinDbg; return(fileEntry); } if (fileInfo.Extension == ".log") { fileEntry.Type = SDFileType.SuperDumpLogfile; return(fileEntry); } if (fileInfo.Extension == ".json") { fileEntry.Type = SDFileType.SuperDumpData; return(fileEntry); } if (fileInfo.Extension == ".dmp") { fileEntry.Type = SDFileType.PrimaryDump; return(fileEntry); } if (fileInfo.Name.EndsWith(".core.gz", StringComparison.OrdinalIgnoreCase)) { fileEntry.Type = SDFileType.PrimaryDump; return(fileEntry); } if (fileInfo.Name.EndsWith(".core", StringComparison.OrdinalIgnoreCase)) { fileEntry.Type = SDFileType.PrimaryDump; return(fileEntry); } if (fileInfo.Name.EndsWith(".libs.tar.gz", StringComparison.OrdinalIgnoreCase)) { fileEntry.Type = SDFileType.LinuxLibraries; return(fileEntry); } // can't figure out filetype fileEntry.Type = SDFileType.Other; return(fileEntry); }
internal void Store(DumpMetainfo dumpInfo) { WriteMetainfoFile(dumpInfo, pathHelper.GetDumpMetadataPath(dumpInfo.BundleId, dumpInfo.DumpId)); }
public DumpViewModel(DumpMetainfo DumpInfo, BundleViewModel bundleViewModel) { this.DumpInfo = DumpInfo; this.BundleViewModel = bundleViewModel; this.Similarities = new Similarities(new Dictionary <DumpIdentifier, double>()); }
public DumpViewModel(DumpMetainfo DumpInfo, BundleViewModel bundleViewModel, Similarities similarities) { this.DumpInfo = DumpInfo; this.BundleViewModel = bundleViewModel; this.Similarities = similarities; }
public void Store(DumpMetainfo dumpInfo) { WriteMetainfoFile(dumpInfo, pathHelper.GetDumpMetadataPath(dumpInfo.Id)); }
public async Task <string> GetMessage(DumpMetainfo dumpInfo) { var model = new SlackMessageViewModel(); var res = dumpRepo.GetResult(dumpInfo.BundleId, dumpInfo.DumpId, out string error); var engine = new EngineFactory().ForEmbeddedResources(typeof(SlackMessageViewModel)); model.TopProperties.Add(dumpInfo.DumpType == DumpType.WindowsDump ? "Windows" : "Linux"); model.DumpFilename = Path.GetFileName(dumpInfo.DumpFileName); model.Url = $"{superDumpUrl}/Home/Report?bundleId={dumpInfo.BundleId}&dumpId={dumpInfo.DumpId}"; if (res != null) { model.TopProperties.Add(res.SystemContext.ProcessArchitecture); if (res.IsManagedProcess) { model.TopProperties.Add(".NET"); } if (res.SystemContext.Modules.Any(x => x.FileName.Contains("jvm.dll"))) { model.TopProperties.Add("Java"); } if (res.SystemContext.Modules.Any(x => x.FileName.Contains("jvm.so"))) { model.TopProperties.Add("Java"); } if (res.SystemContext.Modules.Any(x => x.FileName.Contains("iiscore.dll"))) { model.TopProperties.Add("IIS"); } if (res.SystemContext.Modules.Any(x => x.FileName.Contains("nginx.so"))) { model.TopProperties.Add("NGINX"); } if (res.SystemContext.Modules.Any(x => x.FileName.Contains("httpd/modules"))) { model.TopProperties.Add("Apache"); } if (res.SystemContext.Modules.Any(x => x.FileName.Contains("node.exe"))) { model.TopProperties.Add("Node.js"); } var agentModules = res.SystemContext.Modules.Where(x => x.Tags.Any(t => t.Equals(SDTag.DynatraceAgentTag))).Select(m => m.ToString()); model.AgentModules = agentModules.ToList(); model.NumManagedExceptions = res.ThreadInformation.Count(x => x.Value.Tags.Any(t => t.Equals(SDTag.ManagedExceptionTag))); model.NumNativeExceptions = res.ThreadInformation.Count(x => x.Value.Tags.Any(t => t.Equals(SDTag.NativeExceptionTag))); model.NumAssertErrors = res.ThreadInformation.Count(x => x.Value.Tags.Any(t => t.Equals(SDTag.AssertionErrorTag))); SDThread managedExceptionThread = res.ThreadInformation.Values.FirstOrDefault(x => x.Tags.Any(t => t.Equals(SDTag.ManagedExceptionTag))); SDClrException clrException = managedExceptionThread?.LastException; if (clrException != null) { model.TopException = clrException.Type; model.Stacktrace = clrException.StackTrace.ToString(); } if (res.LastEvent != null && !res.LastEvent.Description.Contains("Break instruction")) // break instruction events are useless { model.LastEvent = $"{res.LastEvent.Type}: {res.LastEvent.Description}"; } } return(await engine.CompileRenderAsync("SlackMessage", model)); }
public Task SendFaultReport(DumpMetainfo dumpInfo, FaultReport faultReport) { Console.WriteLine("FaultReport: " + dumpInfo.ToString() + " " + faultReport.ToString()); return(Task.CompletedTask); }
public override async Task AnalyzeDump(DumpMetainfo dumpInfo) { similarityService.ScheduleSimilarityAnalysis(dumpInfo, false, DateTime.Now - TimeSpan.FromDays(settings.Value.SimilarityDetectionMaxDays)); }