From 7d7450a0112ec3b39a971470ecfe1805970aeae4 Mon Sep 17 00:00:00 2001 From: Patrick Simpson Date: Tue, 2 Oct 2018 15:01:52 +0300 Subject: [PATCH] [KOE-176] Added task debug logging --- .../AcaciaZPushPlugin.csproj | 1 + .../DebugSupport/DebugDialog.Designer.cs | 96 +++++ .../Features/DebugSupport/DebugDialog.cs | 91 ++++- .../Features/DebugSupport/DebugDialog.resx | 374 +++++++++++++++--- .../AcaciaZPushPlugin/GlobalOptions.cs | 9 + .../AcaciaZPushPlugin/Utils/Tasks.cs | 41 +- .../AcaciaZPushPlugin/Utils/TasksTracer.cs | 106 +++++ 7 files changed, 644 insertions(+), 74 deletions(-) create mode 100644 src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/TasksTracer.cs diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj index a0a38e9..f3ed4d3 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj @@ -399,6 +399,7 @@ + diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/DebugSupport/DebugDialog.Designer.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/DebugSupport/DebugDialog.Designer.cs index 303f96e..fbd1fb4 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/DebugSupport/DebugDialog.Designer.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/DebugSupport/DebugDialog.Designer.cs @@ -71,6 +71,17 @@ this._layoutEventsButtons = new System.Windows.Forms.FlowLayoutPanel(); this.buttonCleanGC = new System.Windows.Forms.Button(); this.buttonCopyFilter = new System.Windows.Forms.Button(); + this._tabTasks = new System.Windows.Forms.TabPage(); + this._layoutTasks = new System.Windows.Forms.TableLayoutPanel(); + this._listTasks = new System.Windows.Forms.ListView(); + this._columnTaskId = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this._columnTaskCreated = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this._columnTaskAdded = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this._columnTaskStarted = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this._columnTaskFinished = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this._layoutTaskButtons = new System.Windows.Forms.FlowLayoutPanel(); + this._buttonTasksRefresh = new System.Windows.Forms.Button(); + this._columnFailure = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); columnMethod = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); columnFile = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); columnLine = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); @@ -91,6 +102,9 @@ this._tabItemEvents.SuspendLayout(); this._layoutItemEvents.SuspendLayout(); this._layoutEventsButtons.SuspendLayout(); + this._tabTasks.SuspendLayout(); + this._layoutTasks.SuspendLayout(); + this._layoutTaskButtons.SuspendLayout(); this.SuspendLayout(); // // columnMethod @@ -177,6 +191,7 @@ this._tabs.Controls.Add(this._tabWrapperTypes); this._tabs.Controls.Add(this._tabWrapperLocations); this._tabs.Controls.Add(this._tabItemEvents); + this._tabs.Controls.Add(this._tabTasks); resources.ApplyResources(this._tabs, "_tabs"); this._tabs.Name = "_tabs"; this._tabs.SelectedIndex = 0; @@ -391,6 +406,71 @@ this.buttonCopyFilter.UseVisualStyleBackColor = true; this.buttonCopyFilter.Click += new System.EventHandler(this.buttonCopyFilter_Click); // + // _tabTasks + // + this._tabTasks.Controls.Add(this._layoutTasks); + resources.ApplyResources(this._tabTasks, "_tabTasks"); + this._tabTasks.Name = "_tabTasks"; + this._tabTasks.UseVisualStyleBackColor = true; + // + // _layoutTasks + // + resources.ApplyResources(this._layoutTasks, "_layoutTasks"); + this._layoutTasks.Controls.Add(this._listTasks, 0, 0); + this._layoutTasks.Controls.Add(this._layoutTaskButtons, 0, 1); + this._layoutTasks.Name = "_layoutTasks"; + // + // _listTasks + // + this._listTasks.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this._columnTaskId, + this._columnTaskCreated, + this._columnTaskAdded, + this._columnTaskStarted, + this._columnTaskFinished, + this._columnFailure}); + resources.ApplyResources(this._listTasks, "_listTasks"); + this._listTasks.Name = "_listTasks"; + this._listTasks.UseCompatibleStateImageBehavior = false; + this._listTasks.View = System.Windows.Forms.View.Details; + // + // _columnTaskId + // + resources.ApplyResources(this._columnTaskId, "_columnTaskId"); + // + // _columnTaskCreated + // + resources.ApplyResources(this._columnTaskCreated, "_columnTaskCreated"); + // + // _columnTaskAdded + // + resources.ApplyResources(this._columnTaskAdded, "_columnTaskAdded"); + // + // _columnTaskStarted + // + resources.ApplyResources(this._columnTaskStarted, "_columnTaskStarted"); + // + // _columnTaskFinished + // + resources.ApplyResources(this._columnTaskFinished, "_columnTaskFinished"); + // + // _layoutTaskButtons + // + resources.ApplyResources(this._layoutTaskButtons, "_layoutTaskButtons"); + this._layoutTaskButtons.Controls.Add(this._buttonTasksRefresh); + this._layoutTaskButtons.Name = "_layoutTaskButtons"; + // + // _buttonTasksRefresh + // + resources.ApplyResources(this._buttonTasksRefresh, "_buttonTasksRefresh"); + this._buttonTasksRefresh.Name = "_buttonTasksRefresh"; + this._buttonTasksRefresh.UseVisualStyleBackColor = true; + this._buttonTasksRefresh.Click += new System.EventHandler(this._buttonTasksRefresh_Click); + // + // _columnFailure + // + resources.ApplyResources(this._columnFailure, "_columnFailure"); + // // DebugDialog // resources.ApplyResources(this, "$this"); @@ -417,6 +497,11 @@ this._layoutItemEvents.PerformLayout(); this._layoutEventsButtons.ResumeLayout(false); this._layoutEventsButtons.PerformLayout(); + this._tabTasks.ResumeLayout(false); + this._layoutTasks.ResumeLayout(false); + this._layoutTasks.PerformLayout(); + this._layoutTaskButtons.ResumeLayout(false); + this._layoutTaskButtons.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); @@ -458,5 +543,16 @@ private System.Windows.Forms.ColumnHeader columnHeader6; private System.Windows.Forms.ColumnHeader columnHeader7; private System.Windows.Forms.Button buttonCopyFilter; + private System.Windows.Forms.TabPage _tabTasks; + private System.Windows.Forms.ListView _listTasks; + private System.Windows.Forms.TableLayoutPanel _layoutTasks; + private System.Windows.Forms.FlowLayoutPanel _layoutTaskButtons; + private System.Windows.Forms.Button _buttonTasksRefresh; + private System.Windows.Forms.ColumnHeader _columnTaskId; + private System.Windows.Forms.ColumnHeader _columnTaskStarted; + private System.Windows.Forms.ColumnHeader _columnTaskFinished; + private System.Windows.Forms.ColumnHeader _columnTaskCreated; + private System.Windows.Forms.ColumnHeader _columnTaskAdded; + private System.Windows.Forms.ColumnHeader _columnFailure; } } \ No newline at end of file diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/DebugSupport/DebugDialog.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/DebugSupport/DebugDialog.cs index 7e2af22..f9466f1 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/DebugSupport/DebugDialog.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/DebugSupport/DebugDialog.cs @@ -35,15 +35,17 @@ namespace Acacia.Features.DebugSupport { public partial class DebugDialog : KopanoDialog { - private readonly DisposableTracerFull _tracer; + private readonly DisposableTracerFull _wrapperTracer; + private readonly TasksTracer _taskTracer; public DebugDialog() { InitializeComponent(); Properties.SelectedObject = new DebugInfo(); - _tracer = DisposableWrapper.GetTracer(); - if (_tracer == null) + // Check wrapper tracing + _wrapperTracer = DisposableWrapper.GetTracer(); + if (_wrapperTracer == null) { // If we don't have a wrapper tracer, hide the tabs _tabs.SizeMode = TabSizeMode.Fixed; @@ -62,6 +64,8 @@ namespace Acacia.Features.DebugSupport Width = Width + 400; Height = Height + 200; } + + _taskTracer = Tasks.Tracer; } private void UpdateFields() @@ -69,18 +73,88 @@ namespace Acacia.Features.DebugSupport Properties.Refresh(); RefreshWrappers(); RefreshItemEvents(); + RefreshTasks(); } + #region Task tracing + + private void RefreshTasks() + { + if (_taskTracer == null) + return; + + _listTasks.Items.Clear(); + foreach(TasksTracer.TaskInfo info in _taskTracer.Tasks) + { + ListViewItem item = new ListViewItem(info.Task.Id); + item.Tag = info; + switch(info.State) + { + case TasksTracer.TaskInfo.EventType.Finished: + item.ForeColor = Color.Black; + break; + case TasksTracer.TaskInfo.EventType.Created: + item.ForeColor = Color.Yellow; + break; + case TasksTracer.TaskInfo.EventType.Added: + item.ForeColor = Color.Blue; + break; + case TasksTracer.TaskInfo.EventType.Started: + item.ForeColor = Color.Green; + break; + case TasksTracer.TaskInfo.EventType.Failed: + item.ForeColor = Color.Red; + break; + } + item.SubItems.Add(MakeDate(info.Created)); + item.SubItems.Add(MakeDuration(info.Added, info.Created.Value)); + item.SubItems.Add(MakeDuration(info.Started, info.Created.Value)); + item.SubItems.Add(MakeDuration(info.Failed ?? info.Finished, info.Created.Value)); + if (info.FailedCause != null) + { + item.SubItems.Add(info.FailedCause.Message); + } + + _listTasks.Items.Add(item); + } + foreach (ColumnHeader header in _listTasks.Columns) + header.Width = -2; + + } + + private string MakeDate(DateTime? d) + { + if (d == null) + return ""; + + return d.Value.ToString("HH:mm:ss.fff"); + } + + private string MakeDuration(DateTime? d, DateTime origin) + { + if (d == null) + return ""; + + return (d.Value.Subtract(origin)).ToString("fff"); + } + + private void _buttonTasksRefresh_Click(object sender, EventArgs e) + { + RefreshTasks(); + } + + #endregion + #region Wrappers private void RefreshWrappers() { - if (_tracer == null) + if (_wrapperTracer == null) return; // Wrappers listWrappers.Items.Clear(); - foreach (DisposableTracerFull.DisposableInfo wrapperInfo in _tracer.GetActive()) + foreach (DisposableTracerFull.DisposableInfo wrapperInfo in _wrapperTracer.GetActive()) { Type type = wrapperInfo.WrapperType; string name = type.Name; @@ -99,7 +173,7 @@ namespace Acacia.Features.DebugSupport // Wrapper types listWrapperTypes.Items.Clear(); - foreach(KeyValuePair type in _tracer.GetTypes()) + foreach(KeyValuePair type in _wrapperTracer.GetTypes()) { string name = type.Key.Name; if (type.Key.DeclaringType != null) @@ -115,7 +189,7 @@ namespace Acacia.Features.DebugSupport // Wrapper locations listWrapperLocations.Items.Clear(); - foreach (KeyValuePair entry in _tracer.GetLocations()) + foreach (KeyValuePair entry in _wrapperTracer.GetLocations()) { ListViewItem item = new ListViewItem(entry.Key.DisplayName); item.SubItems.Add(entry.Value.ToString()); @@ -180,7 +254,7 @@ namespace Acacia.Features.DebugSupport private void RefreshItemEvents() { - if (_tracer == null) + if (_wrapperTracer == null) return; listItemEvents.Items.Clear(); @@ -407,5 +481,6 @@ namespace Acacia.Features.DebugSupport } #endregion + } } diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/DebugSupport/DebugDialog.resx b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/DebugSupport/DebugDialog.resx index 775337a..a20be31 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/DebugSupport/DebugDialog.resx +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/DebugSupport/DebugDialog.resx @@ -202,13 +202,13 @@ - 483, 6 + 396, 5 - 6, 6, 6, 6 + 5, 5, 5, 5 - 126, 52 + 103, 43 0 @@ -232,13 +232,13 @@ True - 346, 6 + 284, 5 - 6, 6, 6, 6 + 5, 5, 5, 5 - 125, 52 + 102, 43 1 @@ -262,13 +262,13 @@ True - 196, 6 + 161, 5 - 6, 6, 6, 6 + 5, 5, 5, 5 - 138, 52 + 113, 43 2 @@ -292,13 +292,13 @@ True - 81, 6 + 67, 5 - 6, 6, 6, 6 + 5, 5, 5, 5 - 103, 52 + 84, 43 3 @@ -322,13 +322,13 @@ RightToLeft - 4, 703 + 3, 587 - 4, 3, 4, 3 + 3, 2, 3, 2 - 615, 64 + 504, 53 1 @@ -352,13 +352,13 @@ False - 3, 3 + 2, 2 - 4, 3, 4, 3 + 3, 2, 3, 2 - 603, 651 + 494, 544 2 @@ -376,13 +376,16 @@ 0 - 4, 33 + 4, 29 + + + 2, 2, 2, 2 - 3, 3, 3, 3 + 2, 2, 2, 2 - 609, 657 + 498, 548 0 @@ -418,10 +421,13 @@ Fill - 3, 3 + 2, 2 + + + 2, 2, 2, 2 - 603, 651 + 494, 544 0 @@ -444,11 +450,14 @@ 0, 0 + + 2, 2, 2, 2 + 1 - 609, 657 + 498, 548 0 @@ -469,10 +478,13 @@ <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="listWrappers" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,50" /><Rows Styles="Percent,50" /></TableLayoutSettings> - 4, 33 + 4, 29 + + + 2, 2, 2, 2 - 609, 657 + 498, 548 4 @@ -508,10 +520,13 @@ Fill - 3, 3 + 2, 2 + + + 2, 2, 2, 2 - 603, 651 + 494, 544 0 @@ -529,13 +544,16 @@ 0 - 4, 33 + 4, 29 + + + 2, 2, 2, 2 - 3, 3, 3, 3 + 2, 2, 2, 2 - 609, 657 + 498, 548 1 @@ -562,10 +580,13 @@ Fill - 3, 328 + 2, 274 + + + 2, 2, 2, 2 - 597, 320 + 490, 268 3 @@ -598,10 +619,13 @@ Fill - 3, 3 + 2, 2 + + + 2, 2, 2, 2 - 597, 319 + 490, 268 2 @@ -622,13 +646,16 @@ Fill - 3, 3 + 2, 2 + + + 2, 2, 2, 2 2 - 603, 651 + 494, 544 2 @@ -646,16 +673,19 @@ 0 - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="listStackTrace" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="listWrapperLocations" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100,Absolute,20" /><Rows Styles="Percent,50,Percent,50" /></TableLayoutSettings> + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="listStackTrace" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="listWrapperLocations" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100,Absolute,16" /><Rows Styles="Percent,50,Percent,50" /></TableLayoutSettings> - 4, 33 + 4, 29 + + + 2, 2, 2, 2 - 3, 3, 3, 3 + 2, 2, 2, 2 - 609, 657 + 498, 548 2 @@ -685,10 +715,13 @@ Fill - 3, 305 + 2, 255 + + + 2, 2, 2, 2 - 597, 296 + 490, 249 3 @@ -712,10 +745,13 @@ Fill - 3, 3 + 2, 2 + + + 2, 2, 2, 2 - 597, 296 + 490, 249 2 @@ -742,10 +778,13 @@ True - 465, 3 + 382, 2 + + + 2, 2, 2, 2 - 129, 35 + 106, 30 0 @@ -769,10 +808,13 @@ True - 350, 3 + 289, 2 + + + 2, 2, 2, 2 - 109, 35 + 89, 30 1 @@ -799,10 +841,13 @@ RightToLeft - 3, 607 + 2, 508 + + + 2, 2, 2, 2 - 597, 41 + 490, 34 4 @@ -823,13 +868,16 @@ Fill - 3, 3 + 2, 2 + + + 2, 2, 2, 2 3 - 603, 651 + 494, 544 3 @@ -850,13 +898,16 @@ <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="listItemEventDetails" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="listItemEvents" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="_layoutEventsButtons" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="Percent,50,Percent,50,AutoSize,0" /></TableLayoutSettings> - 4, 33 + 4, 29 + + + 2, 2, 2, 2 - 3, 3, 3, 3 + 2, 2, 2, 2 - 609, 657 + 498, 548 3 @@ -876,14 +927,173 @@ 4 + + 1 + + + Id + + + Created + + + Added + + + Started + + + Finished + + + Failure + + + Fill + + + 3, 3 + + + 492, 500 + + + 0 + + + _listTasks + + + System.Windows.Forms.ListView, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + _layoutTasks + + + 0 + + + True + + + True + + + 413, 3 + + + 76, 30 + + + 0 + + + Refresh + + + _buttonTasksRefresh + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + _layoutTaskButtons + + + 0 + + + Fill + + + RightToLeft + + + 3, 509 + + + 492, 36 + + + 1 + + + _layoutTaskButtons + + + System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + _layoutTasks + + + 1 + + + Fill + + + 0, 0 + + + 2 + + + 498, 548 + + + 1 + + + _layoutTasks + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + _tabTasks + + + 0 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="_listTasks" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="_layoutTaskButtons" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="Percent,100,AutoSize,0" /></TableLayoutSettings> + + + 4, 29 + + + 498, 548 + + + 5 + + + Tasks + + + _tabTasks + + + System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + _tabs + + + 5 + Fill - 3, 3 + 2, 2 + + + 2, 2, 2, 2 - 617, 694 + 506, 581 3 @@ -904,13 +1114,13 @@ 0, 0 - 4, 3, 4, 3 + 3, 2, 3, 2 2 - 623, 770 + 510, 642 0 @@ -928,22 +1138,22 @@ 0 - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="flowButtons" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="_tabs" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="Percent,100,AutoSize,0,Absolute,20" /></TableLayoutSettings> + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="flowButtons" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="_tabs" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="Percent,100,AutoSize,0,Absolute,17" /></TableLayoutSettings> True - 11, 24 + 9, 20 True - 623, 766 + 510, 638 - 4, 3, 4, 3 + 3, 2, 3, 2 CenterParent @@ -1053,6 +1263,42 @@ System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + _columnTaskId + + + System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + _columnTaskCreated + + + System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + _columnTaskAdded + + + System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + _columnTaskStarted + + + System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + _columnTaskFinished + + + System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + _columnFailure + + + System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + DebugDialog diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/GlobalOptions.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/GlobalOptions.cs index 3c281ea..081bff2 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/GlobalOptions.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/GlobalOptions.cs @@ -116,6 +116,15 @@ namespace Acacia } private static readonly BoolOption WRAPPER_TRACE = new BoolOption("WrapperTrace", false); + [AcaciaOption("Enables tracing of task execution. Should only be enabled for debugging, as it's very " + + "resource intensive. Requires WrapperTrace.")] + public bool TaskTrace + { + get { return GetOption(null, TASK_TRACE); } + set { SetOption(null, TASK_TRACE, value); } + } + private static readonly BoolOption TASK_TRACE = new BoolOption("TaskTrace", false); + [AcaciaOption("Enables or disables logging completely.")] public bool Logging { diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/Tasks.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/Tasks.cs index 7f8f05e..93cc371 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/Tasks.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/Tasks.cs @@ -31,6 +31,12 @@ namespace Acacia.Utils public readonly string Name; public readonly Action Action; + public long TaskId + { + get; + internal set; + } + public AcaciaTask(CompletionTracker completion, Feature owner, string name, Action action) { this._completion = completion; @@ -44,9 +50,13 @@ namespace Acacia.Utils { get { + string suffix = ""; + if (TaskId != 0) + suffix = ":" + TaskId; + if (Owner != null) - return Owner.Name + "." + Name; - return Name; + return Owner.Name + "." + Name + suffix; + return Name + suffix; } } @@ -80,12 +90,16 @@ namespace Acacia.Utils public abstract class TaskExecutor { + internal TasksTracer Tracer; + public abstract string Name { get; } public void AddTask(AcaciaTask task) { Interlocked.Increment(ref Statistics.StartedTasks); + Tracer?.OnTaskAdding(task); EnqueueTask(task); + Tracer?.OnTaskAdded(task); } abstract protected void EnqueueTask(AcaciaTask task); @@ -94,10 +108,17 @@ namespace Acacia.Utils { try { + Tracer?.OnTaskExecuting(task); task.Execute(); } + catch(Exception e) + { + Tracer?.OnTaskFailed(task, e); + throw e; + } finally { + Tracer?.OnTaskExecuted(task); Interlocked.Increment(ref Statistics.FinishedTasks); } } @@ -106,6 +127,8 @@ namespace Acacia.Utils public static class Tasks { private static TaskExecutor _executor; + private static TasksTracer _tracer; + private static long _taskId; public static TaskExecutor Executor { @@ -125,6 +148,13 @@ namespace Acacia.Utils _executor = new TasksBackground(); break; } + + if (GlobalOptions.INSTANCE.TaskTrace) + { + // Create a tracer + _tracer = new TasksTracer(); + _executor.Tracer = _tracer; + } } return _executor; } @@ -134,6 +164,11 @@ namespace Acacia.Utils } } + public static TasksTracer Tracer + { + get { return _tracer; } + } + public static void Task(CompletionTracker completion, Feature owner, string name, Action action) { Task(new AcaciaTask(completion, owner, name, action)); @@ -141,6 +176,8 @@ namespace Acacia.Utils public static void Task(AcaciaTask task, bool synchronous = false) { + task.TaskId = Interlocked.Increment(ref _taskId); + Logger.Instance.Trace(typeof(Tasks), "TASK added: {0}", task); if (synchronous) { diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/TasksTracer.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/TasksTracer.cs new file mode 100644 index 0000000..f9bf51a --- /dev/null +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/TasksTracer.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Acacia.Utils +{ + public class TasksTracer + { + public class TaskInfo + { + private readonly AcaciaTask _task; + + public enum EventType + { + Created, + Added, + Started, + Failed, + Finished + } + + public DateTime? Created { get; private set; } + public DateTime? Added { get; private set; } + public DateTime? Started { get; private set; } + public DateTime? Finished { get; private set; } + public DateTime? Failed { get; private set; } + public Exception FailedCause { get; private set; } + public EventType State { get; private set; } + public AcaciaTask Task { get { return _task; } } + + public TaskInfo(AcaciaTask task) + { + this._task = task; + } + + public void Event(EventType type) + { + switch(type) + { + case EventType.Created: + Created = DateTime.Now; + break; + case EventType.Added: + Added = DateTime.Now; + break; + case EventType.Started: + Started = DateTime.Now; + break; + case EventType.Finished: + Finished = DateTime.Now; + break; + } + + if (State != EventType.Failed) + State = type; + } + + public void SetFailed(Exception x) + { + State = EventType.Failed; + Failed = DateTime.Now; + FailedCause = x; + } + } + + private readonly ConcurrentDictionary _all = new ConcurrentDictionary(); + + private TaskInfo GetTaskInfo(AcaciaTask task) + { + return _all.GetOrAdd(task.TaskId, new TaskInfo(task)); + } + + internal void OnTaskAdding(AcaciaTask task) + { + GetTaskInfo(task)?.Event(TaskInfo.EventType.Created); + } + + internal void OnTaskAdded(AcaciaTask task) + { + GetTaskInfo(task)?.Event(TaskInfo.EventType.Added); + } + + internal void OnTaskExecuting(AcaciaTask task) + { + GetTaskInfo(task)?.Event(TaskInfo.EventType.Started); + } + + internal void OnTaskFailed(AcaciaTask task, Exception e) + { + GetTaskInfo(task)?.SetFailed(e); + } + + internal void OnTaskExecuted(AcaciaTask task) + { + GetTaskInfo(task)?.Event(TaskInfo.EventType.Finished); + } + + public IEnumerable Tasks + { + get { return _all.Values.Reverse(); } + } + } +}