private static bool GetCredentialsIfNeeded(Configuration configuration) { if (configuration.OpenTickets) { // Get use name and password Console.Write("Redmine Username: "******"Redmine password: "); _password = Console.ReadLine(); _redmineManager = new RedmineManager(configuration.RedmineUrl, _user, _password); try { _redmineManager.GetCurrentUser(); return true; } catch (RedmineException) { return false; } } return true; }
private static DumpData Analyze(string dump, Configuration configuration) { using (var da = new DumpAnalyzer(dump)) { EventInformation lastEvent = da.GetLastEvent(); IList<StackFrame> st = da.GetStackTrace(lastEvent.ThreadId); StackFrame frame = st.FirstOrDefault(f => !configuration.Ignores.Any(f.Match) && configuration.Filters.Any(f.Match)); Filter filter = frame == null ? null : configuration.Filters.First(frame.Match); return new DumpData { LastEvent = lastEvent, CallStack = st, FilterOfInterest = filter, FrameOfInterest = frame }; } }
private static bool GetProjectDetailsIfNeeded(Configuration configuration) { if (configuration.OpenTickets) { try { _project = _redmineManager.GetObject<Project>(configuration.Project, null); _projectMembers = _redmineManager.GetTotalObjectList<ProjectMembership>(new NameValueCollection { {"project_id", _project.Identifier} }).Select(p => p.User).ToList(); return _projectMembers != null && _projectMembers.Any(); } catch (RedmineException) { return false; } } return true; }
private static DumpData Process(string dump, Configuration configuration) { var res = Analyze(dump, configuration); Report(res); OpenTicketIfNeeded(dump, res, configuration); return res; }
private static void Process(Configuration configuration) { string[] dumps; if (!string.IsNullOrEmpty(configuration.DumpFile)) { dumps = new[] { configuration.DumpFile }; } else { SearchOption searchOptions = configuration.RecursiveSearch ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; dumps = Directory.GetFiles(configuration.DumpsFolder, "*.dmp", searchOptions); } List<DumpData> dumpsData = new List<DumpData>(); int counter = 1; foreach (string d in dumps) { try { using (new ConsoleForegroundFormatter(ConsoleColor.Cyan)) { Console.WriteLine("Analyzing {0}/{1}: {2}", counter++, dumps.Length, d); } dumpsData.Add(Process(d, configuration)); } catch (Exception e) { using (new ConsoleForegroundFormatter(ConsoleColor.Red)) { Console.Error.WriteLine("Error while analyzing {0}: {1}", d, e); } } if (!configuration.OpenTickets) { Console.WriteLine("Press <Enter> to continue..."); Console.ReadLine(); } } ReportStatistics(dumpsData); }
private static void OpenTicketIfNeeded(string dump, DumpData res, Configuration configuration) { if (configuration.OpenTickets) { OpenTicket(dump, res, configuration); } }
private static void OpenTicket(string dump, DumpData res, Configuration configuration) { OwnershipData ownershipData = configuration.Owners.FirstOrDefault(o => o.Filter == res.FilterOfInterest); Owner assignee = configuration.DefaultOwner; if (ownershipData != null) { assignee = ownershipData.Owner; } var author = new IdentifiableName { Id = _redmineManager.GetCurrentUser().Id }; IdentifiableName assignedTo = _projectMembers.SingleOrDefault(pm => pm != null && pm.Name == assignee.Name) ?? _projectMembers.SingleOrDefault(pm => pm != null && pm.Name == configuration.DefaultOwner.Name); if (assignedTo == null) { // TODO: do something about this? } string subject = "Unexpected exception occurred"; string description = string.Format("Please investigate a dump located at {0}.{1}{2}Here's the beginning of the call stack for the last event:{3}{4}", dump, Environment.NewLine, Environment.NewLine, Environment.NewLine, string.Join(Environment.NewLine, res.CallStack.Take(Math.Min(res.CallStack.Count, 30)))); if (res.FrameOfInterest != null) { subject = string.Format("A problem occurred in {0}.{1}: {2}", res.FrameOfInterest.ModuleName, res.FrameOfInterest.MethodName, res.LastEvent.Description); description = string.Format("There was a problem in {0}: {1}.{2}Please investigate a dump located at {3}.{4}{5}Here's the call stack for the last event:{6}{7}", res.FrameOfInterest.ModuleName, res.LastEvent, Environment.NewLine, dump, Environment.NewLine, Environment.NewLine, Environment.NewLine, string.Join(Environment.NewLine, res.CallStack.Take(Math.Min(res.CallStack.Count, 30)))); } var issue = new Issue { Subject = subject.Substring(0, Math.Min(subject.Length, 255)), Description = description, AssignedTo = assignedTo, Author = author, Project = new IdentifiableName { Id = _project.Id }, }; _redmineManager.CreateObject(issue); }