From 4df0bb7880ac0bae5cef0481e5620a32aa5d2eef Mon Sep 17 00:00:00 2001 From: Michael Gratton Date: Fri, 5 Jul 2019 09:47:37 +1000 Subject: [PATCH] Capture log records in Geary.ProblemReport Allow getting both the earliest and latest log records from Geary.Logging and record these when constructing new ProblemReport instances. Update InspectorLogView.load to have starting and end log record parameters, and specify these when displaying a problem report. This ensures that only those log records up to the point of the problem report being generated are included in the report, and not any later records. --- .../components-inspector-log-view.vala | 21 ++++++++++++------- .../components/components-inspector.vala | 5 +++-- .../dialogs-problem-details-dialog.vala | 18 +++++++++------- src/engine/api/geary-logging.vala | 11 +++++++--- src/engine/api/geary-problem-report.vala | 10 ++++++++- 5 files changed, 44 insertions(+), 21 deletions(-) diff --git a/src/client/components/components-inspector-log-view.vala b/src/client/components/components-inspector-log-view.vala index ed37c855..8bb5cea4 100644 --- a/src/client/components/components-inspector-log-view.vala +++ b/src/client/components/components-inspector-log-view.vala @@ -51,6 +51,8 @@ public class Components.InspectorLogView : Gtk.Grid { private Geary.AccountInformation? account_filter = null; + private bool listener_installed = false; + /** Emitted when the number of selected records changes. */ public signal void record_selection_changed(); @@ -70,15 +72,18 @@ public class Components.InspectorLogView : Gtk.Grid { } /** Loads log records from the logging system into the view. */ - public void load() { - // Install the listener then start adding the backlog - // (ba-doom-tish) so to avoid the race. - Geary.Logging.set_log_listener(this.on_log_record); + public void load(Geary.Logging.Record first, Geary.Logging.Record? last) { + if (last == null) { + // Install the listener then start adding the backlog + // (ba-doom-tish) so to avoid the race. + Geary.Logging.set_log_listener(this.on_log_record); + this.listener_installed = true; + } Gtk.ListStore logs_store = this.logs_store; - Geary.Logging.Record? logs = Geary.Logging.get_logs(); + Geary.Logging.Record? logs = first; int index = 0; - while (logs != null) { + while (logs != last) { if (should_append(logs)) { string message = logs.format(); Gtk.TreeIter iter; @@ -114,7 +119,9 @@ public class Components.InspectorLogView : Gtk.Grid { /** {@inheritDoc} */ public override void destroy() { - Geary.Logging.set_log_listener(null); + if (this.listener_installed) { + Geary.Logging.set_log_listener(null); + } base.destroy(); } diff --git a/src/client/components/components-inspector.vala b/src/client/components/components-inspector.vala index 1a3ac94d..b0eecd36 100644 --- a/src/client/components/components-inspector.vala +++ b/src/client/components/components-inspector.vala @@ -69,9 +69,10 @@ public class Components.Inspector : Gtk.ApplicationWindow { /// Translators: Title for Inspector system system information pane this.stack.add_titled(this.system_pane, "system_pane", _("System")); - // Enable updates to get the log marker, then load log records in + // Enable updates to get the log marker, then load log all log + // records in enable_log_updates(true); - this.log_pane.load(); + this.log_pane.load(Geary.Logging.get_earliest_record(), null); } public override bool key_press_event(Gdk.EventKey event) { diff --git a/src/client/dialogs/dialogs-problem-details-dialog.vala b/src/client/dialogs/dialogs-problem-details-dialog.vala index 4105f1af..c5cead87 100644 --- a/src/client/dialogs/dialogs-problem-details-dialog.vala +++ b/src/client/dialogs/dialogs-problem-details-dialog.vala @@ -48,19 +48,21 @@ public class Dialogs.ProblemDetailsDialog : Hdy.Dialog { private Geary.ServiceInformation? service; - public ProblemDetailsDialog(MainWindow parent, - Geary.ErrorContext error, - Geary.AccountInformation? account, - Geary.ServiceInformation? service) { + public ProblemDetailsDialog(MainWindow parent, Geary.ProblemReport report) { Object( transient_for: parent, use_header_bar: 1 ); set_default_size(600, 400); - this.error = error; - this.account = account; - this.service = service; + Geary.AccountProblemReport? account_report = + report as Geary.AccountProblemReport; + Geary.ServiceProblemReport? service_report = + report as Geary.ServiceProblemReport; + + this.error = report.error; + this.account = (account_report != null) ? account_report.account : null; + this.service = (service_report != null) ? service_report.service : null; GLib.SimpleActionGroup actions = new GLib.SimpleActionGroup(); actions.add_action_entries(ProblemDetailsDialog.action_entries, this); @@ -73,7 +75,7 @@ public class Dialogs.ProblemDetailsDialog : Hdy.Dialog { this.log_pane = new Components.InspectorLogView( parent.application.config, account ); - this.log_pane.load(); + this.log_pane.load(report.earliest_log, report.latest_log); this.log_pane.record_selection_changed.connect( on_logs_selection_changed ); diff --git a/src/engine/api/geary-logging.vala b/src/engine/api/geary-logging.vala index 95a1cd7f..f3fbb244 100644 --- a/src/engine/api/geary-logging.vala +++ b/src/engine/api/geary-logging.vala @@ -99,8 +99,8 @@ public enum Flag { * * A record is created for each message logged, and stored in a * limited-length, singly-linked buffer. Applications can retrieve - * this by calling {@link get_logs} and then {get_next}, and can be - * notified of new records via {@link set_log_listener}. + * this by calling {@link get_earliest_record} and then {get_next}, + * and can be notified of new records via {@link set_log_listener}. */ public class Record { @@ -447,10 +447,15 @@ public inline void logv(Flag flags, } /** Returns the oldest log record in the logging system's buffer. */ -public Record? get_logs() { +public Record? get_earliest_record() { return first_record; } +/** Returns the most recent log record in the logging system's buffer. */ +public Record? get_latest_record() { + return last_record; +} + /** * Registers a FileStream to receive all log output from the Engine, be it via the specialized * Logging calls (which use the topic-based {@link Flag} or GLib's standard issue diff --git a/src/engine/api/geary-problem-report.vala b/src/engine/api/geary-problem-report.vala index 109a2301..7a4b056d 100644 --- a/src/engine/api/geary-problem-report.vala +++ b/src/engine/api/geary-problem-report.vala @@ -15,11 +15,19 @@ public class Geary.ProblemReport : Object { /** The exception caused the problem, if any. */ public ErrorContext? error { get; private set; default = null; } + /** The oldest log record when the report was first created. */ + public Logging.Record? earliest_log { get; private set; default = null; } - public ProblemReport(Error? error) { + /** The newest log record when the report was first created. */ + public Logging.Record? latest_log { get; private set; default = null; } + + + public ProblemReport(GLib.Error? error) { if (error != null) { this.error = new ErrorContext(error); } + this.earliest_log = Logging.get_earliest_record(); + this.latest_log = Logging.get_latest_record(); } /** Returns a string representation of the report, for debugging only. */