diff --git a/Implab.Diagnostics.Interactive/Implab.Diagnostics.Interactive.csproj b/Implab.Diagnostics.Interactive/Implab.Diagnostics.Interactive.csproj deleted file mode 100644 --- a/Implab.Diagnostics.Interactive/Implab.Diagnostics.Interactive.csproj +++ /dev/null @@ -1,77 +0,0 @@ - - - - - Debug - AnyCPU - {1DB7DB0C-8AA9-484B-A681-33AE94038391} - Library - Properties - Implab.Diagnostics.Interactive - Implab.Diagnostics.Interactive - v4.5 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - Form - - - TraceForm.cs - - - - - - {F550F1F8-8746-4AD0-9614-855F4C4B7F05} - Implab - - - - - TraceForm.cs - - - - - - - - \ No newline at end of file diff --git a/Implab.Diagnostics.Interactive/InteractiveListener.cs b/Implab.Diagnostics.Interactive/InteractiveListener.cs deleted file mode 100644 --- a/Implab.Diagnostics.Interactive/InteractiveListener.cs +++ /dev/null @@ -1,147 +0,0 @@ -using Implab.Parallels; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace Implab.Diagnostics.Interactive -{ - public class InteractiveListener: ListenerBase - { - TraceForm m_form; - - SynchronizationContext m_syncGuiThread; - readonly Promise m_guiStarted = new Promise(); - - readonly IPromise m_guiFinished; - - readonly SimpleAsyncQueue m_queue = new SimpleAsyncQueue(); - readonly AutoResetEvent m_queueEvent = new AutoResetEvent(false); - - int m_queueLength; - bool m_exitPending; - - readonly object m_pauseLock = new object(); - bool m_paused; - readonly ManualResetEvent m_pauseEvent = new ManualResetEvent(true); - - public InteractiveListener() { - m_guiFinished = RunGuiThread(); - AsyncPool.RunThread(QueueThread); - - m_guiStarted.Join(); - } - - void GuiThread() { - m_form = new TraceForm(); // will create SynchronizationContext - - m_form.PauseEvents += (s,a) => Pause(); - m_form.ResumeEvents += (s, a) => Resume(); - - m_syncGuiThread = SynchronizationContext.Current; - m_guiStarted.Resolve(); - Application.Run(); - } - - void QueueThread() { - while (!m_exitPending) { - if (m_paused) - m_pauseEvent.WaitOne(); - - TraceViewItem item; - if (m_queue.TryDequeue(out item)) { - Interlocked.Decrement(ref m_queueLength); - - m_syncGuiThread.Post(x => m_form.AddTraceEvent(item),null); - } else { - m_queueEvent.WaitOne(); - } - } - } - - public IPromise RunGuiThread() { - var p = new Promise(); - - var caller = TraceContext.Instance.CurrentOperation; - - var worker = new Thread(() => { - TraceContext.Instance.EnterLogicalOperation(caller, false); - try { - Application.OleRequired(); - GuiThread(); - p.Resolve(); - } catch (Exception e) { - p.Reject(e); - } finally { - TraceContext.Instance.Leave(); - } - }); - worker.SetApartmentState(ApartmentState.STA); - worker.IsBackground = true; - worker.Name = string.Format("{0} GUI Thread", nameof(InteractiveListener)); - worker.Start(); - - return p; - } - - public void Pause() { - // for consistency we need to set this properties atomically - lock (m_pauseLock) { - m_pauseEvent.Reset(); - m_paused = true; - } - } - - public void Resume() { - // for consistency we need to set this properties atomically - lock (m_pauseLock) { - m_paused = false; - m_pauseEvent.Set(); - } - } - - void Enqueue(TraceViewItem item) { - m_queue.Enqueue(item); - if (Interlocked.Increment(ref m_queueLength) == 1) - m_queueEvent.Set(); - } - - public void ShowForm() { - m_syncGuiThread.Post(x => m_form.Show(), null); - } - - public void HideForm() { - m_syncGuiThread.Post(x => m_form.Hide(), null); - } - - void Terminate() { - m_exitPending = true; - Resume(); - m_syncGuiThread.Post(x => Application.ExitThread(), null); - } - - protected override void Dispose(bool disposing) { - if (disposing) { - Terminate(); - m_guiFinished.Join(); - } - base.Dispose(disposing); - } - - public override void Write(LogEventArgs args, object entry) { - var item = new TraceViewItem { - Indent = args.Operation.Level, - Message = entry.ToString(), - Thread = args.ThreadId, - Channel = args.Channel.ToString(), - Timestamp = Environment.TickCount, - TimeDelta = args.OperationTimeOffset - }; - - Enqueue(item); - } - } -} diff --git a/Implab.Diagnostics.Interactive/Properties/AssemblyInfo.cs b/Implab.Diagnostics.Interactive/Properties/AssemblyInfo.cs deleted file mode 100644 --- a/Implab.Diagnostics.Interactive/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Implab.Diagnostics.Interactive")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Implab.Diagnostics.Interactive")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("1c156c51-4884-43b2-a823-d86313872e82")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Implab.Diagnostics.Interactive/Properties/DataSources/TraceViewItem.datasource b/Implab.Diagnostics.Interactive/Properties/DataSources/TraceViewItem.datasource deleted file mode 100644 --- a/Implab.Diagnostics.Interactive/Properties/DataSources/TraceViewItem.datasource +++ /dev/null @@ -1,10 +0,0 @@ - - - - Implab.Diagnostics.Interactive.TraceViewItem, Implab.Diagnostics.Interactive - \ No newline at end of file diff --git a/Implab.Diagnostics.Interactive/TextStyle.cs b/Implab.Diagnostics.Interactive/TextStyle.cs deleted file mode 100644 --- a/Implab.Diagnostics.Interactive/TextStyle.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Implab.Diagnostics.Interactive { - class TextStyle { - public Color TextColor { - get; - set; - } - - public FontStyle FontStyle { - get; - set; - } - - public int PaddingLeft { - get; - set; - } - } -} diff --git a/Implab.Diagnostics.Interactive/TraceForm.Designer.cs b/Implab.Diagnostics.Interactive/TraceForm.Designer.cs deleted file mode 100644 --- a/Implab.Diagnostics.Interactive/TraceForm.Designer.cs +++ /dev/null @@ -1,149 +0,0 @@ -namespace Implab.Diagnostics.Interactive { - partial class TraceForm { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle(); - this.eventsDataGrid = new System.Windows.Forms.DataGridView(); - this.traceViewItemBindingSource = new System.Windows.Forms.BindingSource(); - this.threadDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.TimeDelta = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.Channel = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.messageDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); - ((System.ComponentModel.ISupportInitialize)(this.eventsDataGrid)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.traceViewItemBindingSource)).BeginInit(); - this.SuspendLayout(); - // - // eventsDataGrid - // - this.eventsDataGrid.AllowUserToAddRows = false; - this.eventsDataGrid.AllowUserToDeleteRows = false; - this.eventsDataGrid.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.eventsDataGrid.AutoGenerateColumns = false; - this.eventsDataGrid.BackgroundColor = System.Drawing.SystemColors.Window; - dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; - dataGridViewCellStyle1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224))))); - dataGridViewCellStyle1.Font = new System.Drawing.Font("Lucida Console", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText; - dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight; - dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText; - dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True; - this.eventsDataGrid.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1; - this.eventsDataGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.eventsDataGrid.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { - this.threadDataGridViewTextBoxColumn, - this.TimeDelta, - this.Channel, - this.messageDataGridViewTextBoxColumn}); - this.eventsDataGrid.DataSource = this.traceViewItemBindingSource; - dataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; - dataGridViewCellStyle4.BackColor = System.Drawing.SystemColors.Window; - dataGridViewCellStyle4.Font = new System.Drawing.Font("Lucida Console", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - dataGridViewCellStyle4.ForeColor = System.Drawing.SystemColors.ControlText; - dataGridViewCellStyle4.SelectionBackColor = System.Drawing.SystemColors.Highlight; - dataGridViewCellStyle4.SelectionForeColor = System.Drawing.SystemColors.HighlightText; - dataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.False; - this.eventsDataGrid.DefaultCellStyle = dataGridViewCellStyle4; - this.eventsDataGrid.Location = new System.Drawing.Point(12, 12); - this.eventsDataGrid.Name = "eventsDataGrid"; - this.eventsDataGrid.ReadOnly = true; - this.eventsDataGrid.RowHeadersVisible = false; - this.eventsDataGrid.RowHeadersWidth = 17; - this.eventsDataGrid.RowTemplate.Resizable = System.Windows.Forms.DataGridViewTriState.False; - this.eventsDataGrid.Size = new System.Drawing.Size(939, 480); - this.eventsDataGrid.TabIndex = 1; - this.eventsDataGrid.CellFormatting += new System.Windows.Forms.DataGridViewCellFormattingEventHandler(this.eventsDataGrid_CellFormatting); - // - // traceViewItemBindingSource - // - this.traceViewItemBindingSource.DataSource = typeof(Implab.Diagnostics.Interactive.TraceViewItem); - // - // threadDataGridViewTextBoxColumn - // - this.threadDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; - this.threadDataGridViewTextBoxColumn.DataPropertyName = "Thread"; - this.threadDataGridViewTextBoxColumn.HeaderText = "TID"; - this.threadDataGridViewTextBoxColumn.Name = "threadDataGridViewTextBoxColumn"; - this.threadDataGridViewTextBoxColumn.ReadOnly = true; - this.threadDataGridViewTextBoxColumn.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; - this.threadDataGridViewTextBoxColumn.Width = 32; - // - // TimeDelta - // - this.TimeDelta.DataPropertyName = "TimeDelta"; - dataGridViewCellStyle2.Format = "\'+\' 0 \'ms\'"; - dataGridViewCellStyle2.NullValue = null; - this.TimeDelta.DefaultCellStyle = dataGridViewCellStyle2; - this.TimeDelta.HeaderText = "TimeDelta"; - this.TimeDelta.Name = "TimeDelta"; - this.TimeDelta.ReadOnly = true; - this.TimeDelta.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; - // - // Channel - // - this.Channel.DataPropertyName = "Channel"; - this.Channel.HeaderText = "Channel"; - this.Channel.Name = "Channel"; - this.Channel.ReadOnly = true; - this.Channel.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; - // - // messageDataGridViewTextBoxColumn - // - this.messageDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; - this.messageDataGridViewTextBoxColumn.DataPropertyName = "FormattedMessage"; - dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.False; - this.messageDataGridViewTextBoxColumn.DefaultCellStyle = dataGridViewCellStyle3; - this.messageDataGridViewTextBoxColumn.HeaderText = "Message"; - this.messageDataGridViewTextBoxColumn.Name = "messageDataGridViewTextBoxColumn"; - this.messageDataGridViewTextBoxColumn.ReadOnly = true; - this.messageDataGridViewTextBoxColumn.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; - // - // TraceForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(963, 504); - this.Controls.Add(this.eventsDataGrid); - this.Name = "TraceForm"; - this.Text = "TraceForm"; - ((System.ComponentModel.ISupportInitialize)(this.eventsDataGrid)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.traceViewItemBindingSource)).EndInit(); - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.DataGridView eventsDataGrid; - private System.Windows.Forms.BindingSource traceViewItemBindingSource; - private System.Windows.Forms.DataGridViewTextBoxColumn threadDataGridViewTextBoxColumn; - private System.Windows.Forms.DataGridViewTextBoxColumn TimeDelta; - private System.Windows.Forms.DataGridViewTextBoxColumn Channel; - private System.Windows.Forms.DataGridViewTextBoxColumn messageDataGridViewTextBoxColumn; - } -} \ No newline at end of file diff --git a/Implab.Diagnostics.Interactive/TraceForm.cs b/Implab.Diagnostics.Interactive/TraceForm.cs deleted file mode 100644 --- a/Implab.Diagnostics.Interactive/TraceForm.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace Implab.Diagnostics.Interactive { - public partial class TraceForm : Form { - readonly Dictionary m_threadColors = new Dictionary(); - readonly Random m_rand = new Random(); - - public event EventHandler PauseEvents; - - public event EventHandler ResumeEvents; - - public TraceForm() { - InitializeComponent(); - } - - protected override void OnFormClosing(FormClosingEventArgs e) { - base.OnFormClosing(e); - if (!e.Cancel && e.CloseReason == CloseReason.UserClosing) { - e.Cancel = true; - Hide(); - } - } - - public void AddTraceEvent(TraceViewItem item) { - traceViewItemBindingSource.Add(item); - if(eventsDataGrid.RowCount > 0) - eventsDataGrid.FirstDisplayedScrollingRowIndex = eventsDataGrid.RowCount - 1; - } - - Color GetThreadColor(int thread) { - Color result; - if (!m_threadColors.TryGetValue(thread, out result)) { - result = Color.FromArgb(m_rand.Next(4)*64, m_rand.Next(4)*64, m_rand.Next(4)*64); - m_threadColors[thread] = result; - } - return result; - } - - private void eventsDataGrid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) { - var data = (TraceViewItem)traceViewItemBindingSource[e.RowIndex]; - if (e.ColumnIndex == messageDataGridViewTextBoxColumn.Index) - e.CellStyle.Padding = new Padding(data.Indent * 10,0,0,0); - e.CellStyle.ForeColor = GetThreadColor(data.Thread); - } - } -} diff --git a/Implab.Diagnostics.Interactive/TraceForm.resx b/Implab.Diagnostics.Interactive/TraceForm.resx deleted file mode 100644 --- a/Implab.Diagnostics.Interactive/TraceForm.resx +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - True - - - True - - - 17, 17 - - \ No newline at end of file diff --git a/Implab.Diagnostics.Interactive/TraceViewItem.cs b/Implab.Diagnostics.Interactive/TraceViewItem.cs deleted file mode 100644 --- a/Implab.Diagnostics.Interactive/TraceViewItem.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Implab.Diagnostics.Interactive { - public class TraceViewItem { - string m_formattedValue; - - public string Message { get; set; } - public int TimeDelta { get; set; } - public int Timestamp { get; set; } - public int Indent { get; set; } - public int Thread { get; set; } - public string Channel { get; set; } - - public string FormattedMessage { - get { - if (m_formattedValue == null) { - m_formattedValue = Message.Replace("\r",String.Empty).Replace("\n", " | "); - } - return m_formattedValue; - } - } - } -} diff --git a/Implab.Test/UnitTest1.cs b/Implab.Test/UnitTest1.cs --- a/Implab.Test/UnitTest1.cs +++ b/Implab.Test/UnitTest1.cs @@ -1,29 +1,37 @@ using System; using System.Diagnostics; using System.Threading; +using Implab.Diagnostics; using Xunit; namespace Implab.Test { + using static Trace; public class UnitTest1 { [Fact] public void Test1() { var listener = new TextWriterTraceListener(Console.Out); - var source = new TraceSource("Custom",SourceLevels.ActivityTracing); + var source = TraceSource; + source.Switch.Level = SourceLevels.All; source.Listeners.Add(listener); + Trace.Listeners.Add(listener); - Trace.Listeners.Add(listener); Trace.WriteLine("Hello!"); - Trace.CorrelationManager.StartLogicalOperation(); + StartLogicalOperation(); + Trace.WriteLine("Inner"); foreach(var x in Trace.CorrelationManager.LogicalOperationStack) Trace.WriteLine($"-{x}"); - source.TraceEvent(TraceEventType.Information, 1, "source event"); + Log("source event"); + + listener.IndentLevel = 1; + source.TraceData(TraceEventType.Start, 1, DateTime.Now); - Trace.CorrelationManager.StopLogicalOperation(); + + StopLogicalOperation(); } } } diff --git a/Implab/Components/Disposable.cs b/Implab/Components/Disposable.cs --- a/Implab/Components/Disposable.cs +++ b/Implab/Components/Disposable.cs @@ -48,16 +48,8 @@ namespace Implab.Components { } } - /// - /// Записывает сообщение об утечке объекта. - /// - protected virtual void ReportObjectLeaks() { - TraceLog.TraceWarning("The object is marked as disposable but isn't disposed properly: {0}", this); - } - ~Disposable() { Dispose(false); - ReportObjectLeaks(); } } } \ No newline at end of file diff --git a/Implab/Components/RunnableComponent.cs b/Implab/Components/RunnableComponent.cs --- a/Implab/Components/RunnableComponent.cs +++ b/Implab/Components/RunnableComponent.cs @@ -15,7 +15,7 @@ namespace Implab.Components { public class RunnableComponent : IRunnable, IInitializable, IDisposable { /// - /// This class bound lifetime to the task, + /// This class bounds lifetime to the task, /// when the task completes the associated token source will be disposed. /// class AsyncOperationDescriptor { @@ -161,7 +161,7 @@ namespace Implab.Components { /// /// This method should be used for short and mostly syncronous operations, /// other operations which require time to run shoud be placed in - /// method. + /// method. /// protected virtual Task InitializeInternalAsync(CancellationToken ct) { return Task.CompletedTask; @@ -170,10 +170,10 @@ namespace Implab.Components { public void Start(CancellationToken ct) { var cookie = new object(); if (MoveStart(cookie)) - ScheduleTask(StartInternal, ct, cookie); + ScheduleTask(StartInternalAsync, ct, cookie); } - protected virtual Task StartInternal(CancellationToken ct) { + protected virtual Task StartInternalAsync(CancellationToken ct) { return Task.CompletedTask; } diff --git a/Implab/Diagnostics/ConsoleTraceListener.cs b/Implab/Diagnostics/ConsoleTraceListener.cs deleted file mode 100644 --- a/Implab/Diagnostics/ConsoleTraceListener.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Text; - -namespace Implab.Diagnostics { - public class ConsoleTraceListener: ListenerBase { - - static readonly object _consoleLock = new object(); - - public override void Write(LogEventArgs args, object entry) { - var msg = new StringBuilder(); - - for (int i = 0; i < args.Operation.Level; i++) - msg.Append(" "); - msg.AppendFormat("[{0}]: {1}", args.ThreadId, entry); - - lock (_consoleLock) { - Console.ForegroundColor = (ConsoleColor)(args.ThreadId % 15 + 1); - Console.WriteLine(msg); - } - } - } -} diff --git a/Implab/Diagnostics/ILogWriter.cs b/Implab/Diagnostics/ILogWriter.cs deleted file mode 100644 --- a/Implab/Diagnostics/ILogWriter.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System; - -namespace Implab.Diagnostics { - public interface ILogWriter { - void Write(LogEventArgs args, TEvent entry); - } -} - diff --git a/Implab/Diagnostics/ListenerBase.cs b/Implab/Diagnostics/ListenerBase.cs deleted file mode 100644 --- a/Implab/Diagnostics/ListenerBase.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using System.Collections.Generic; -using Implab.Components; - -namespace Implab.Diagnostics { - public abstract class ListenerBase : ServiceLocator, ILogWriter, ILogWriter { - - readonly Dictionary m_subscriptions = new Dictionary(); - - protected ListenerBase() { - Register(this); - } - - public void Subscribe(Type eventType) { - if (eventType == null) - throw new ArgumentNullException("eventType"); - GetType().GetMethod("Subscribe", new Type[0]).MakeGenericMethod(eventType).Invoke(this, null); - } - - public void Subscribe() { - Subscribe(LogChannel.Default); - } - - public void Subscribe(LogChannel channel) { - if (channel == null) - throw new ArgumentNullException("channel"); - - lock (m_subscriptions) { - AssertNotDisposed(); - if (m_subscriptions.ContainsKey(channel)) - return; - - var writer = GetService>(); - - EventHandler> handler = (sender, args) => writer.Write(args,args.Value); - - channel.Events += handler; - - Action unsubscribe = () => { - channel.Events -= handler; - }; - - m_subscriptions.Add(channel, unsubscribe); - } - } - - public void Unsubscribe(LogChannel channel) { - if (channel == null) - throw new ArgumentNullException("channel"); - - lock (m_subscriptions) { - Action subscription; - if (m_subscriptions.TryGetValue(channel, out subscription)) { - subscription(); - m_subscriptions.Remove(channel); - } - } - } - - public void UnsubscribeAll() { - lock (m_subscriptions) { - foreach (var remove in m_subscriptions.Values) - remove(); - m_subscriptions.Clear(); - } - } - - #region ILogWriter implementation - public abstract void Write(LogEventArgs args, object entry); - #endregion - - #region ILogWriter implementation - public virtual void Write(LogEventArgs args, TraceEvent entry) { - Write(args, (object)entry); - } - #endregion - - - protected override void Dispose(bool disposing) { - base.Dispose(disposing); - if (disposing) { - UnsubscribeAll(); - } - } - } -} diff --git a/Implab/Diagnostics/LogChannel.cs b/Implab/Diagnostics/LogChannel.cs deleted file mode 100644 --- a/Implab/Diagnostics/LogChannel.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Implab.Diagnostics { - /// - /// Канал, через который публикуются события журнала. - /// - /// Тип событий в канале - /// - /// Событиями журнала могут быть любые типы, например строки, в которых будет передаваться - /// информация, или структуры с набором полей, описывающих важность, текст и другую информацию. - /// - public class LogChannel { - static LogChannel _default = new LogChannel(); - - /// - /// Канал по-умолчанию для событий типа . - /// - public static LogChannel Default { - get { - return _default; - } - } - - /// - /// Событие появление новой записи в журнале, на это событие подписываются слушатели. - /// - public event EventHandler> Events; - - /// - /// Имя канала, полезно для отображения в журнале - /// - public string Name { - get; - private set; - } - - /// - /// Создает журнал, имя типа событий назначается в качетве имени канала. - /// - public LogChannel() - : this(null) { - } - - /// - /// Содает канал с указанным именем. - /// - /// Имя канала. - public LogChannel(string name) { - if (String.IsNullOrEmpty(name)) - name = typeof(TEvent).Name; - Name = name; - } - - /// - /// Отправляет запись журнала через канал подписчикам. - /// - /// Запись журнала. - /// - /// Контекст трассировки от которого рассылается сообщение определяется автоматически из текущего потока. - /// - public void LogEvent(TEvent data) { - var t = Events; - if (t != null) { - var traceContext = TraceContext.Instance; - t( - this, - new LogEventArgs( - data, - this, - traceContext.ThreadId, - traceContext.CurrentOperation, - traceContext.CurrentOperation.Duration - ) - ); - } - } - - public override string ToString() { - return Name; - } - } -} diff --git a/Implab/Diagnostics/LogEventArgs.cs b/Implab/Diagnostics/LogEventArgs.cs deleted file mode 100644 --- a/Implab/Diagnostics/LogEventArgs.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; - -namespace Implab.Diagnostics { - public class LogEventArgs : EventArgs { - public object Channel { - get; - private set; - } - public int ThreadId { - get; - private set; - } - public LogicalOperation Operation { - get; - private set; - } - public int OperationTimeOffset { - get; - private set; - } - public LogEventArgs(object channel, int threadId, LogicalOperation operation, int timeOffset) { - Channel = channel; - ThreadId = threadId; - Operation = operation; - OperationTimeOffset = timeOffset; - } - } -} - diff --git a/Implab/Diagnostics/LogEventArgsT.cs b/Implab/Diagnostics/LogEventArgsT.cs deleted file mode 100644 --- a/Implab/Diagnostics/LogEventArgsT.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Implab.Diagnostics { - public class LogEventArgs : LogEventArgs { - public TEvent Value { - get; - private set; - } - - public LogEventArgs(TEvent value,object channel, int threadId, LogicalOperation operation, int timeOffset) : base(channel, threadId, operation, timeOffset) { - Value = value; - } - } -} - diff --git a/Implab/Diagnostics/LogicalOperation.cs b/Implab/Diagnostics/LogicalOperation.cs deleted file mode 100644 --- a/Implab/Diagnostics/LogicalOperation.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; - -namespace Implab.Diagnostics { - public class LogicalOperation { - public static readonly LogicalOperation EMPTY = new LogicalOperation("__EMPTY__", null); - - readonly LogicalOperation m_parent; - readonly string m_name; - readonly int m_level; - readonly int m_timestamp; - - public LogicalOperation() - : this(null, null) { - } - - public LogicalOperation(string name, LogicalOperation parent) { - m_name = name ?? String.Empty; - m_parent = parent; - - m_level = parent == null ? 0 : parent.Level + 1; - m_timestamp = Environment.TickCount; - } - - public int Duration { - get { - var dt = Environment.TickCount - m_timestamp; - return dt < 0 ? int.MaxValue + dt : dt; // handle overflow - } - } - - public LogicalOperation Parent { - get { - return m_parent; - } - } - - public int Level { - get { return m_level; } - } - - public string Name { - get { return m_name; } - } - } -} diff --git a/Implab/Diagnostics/OperationContext.cs b/Implab/Diagnostics/OperationContext.cs deleted file mode 100644 --- a/Implab/Diagnostics/OperationContext.cs +++ /dev/null @@ -1,65 +0,0 @@ -namespace Implab.Diagnostics { - struct OperationContext { - public readonly static OperationContext EMPTY = new OperationContext(LogicalOperation.EMPTY, false); - - LogicalOperation m_initial; - LogicalOperation m_current; - bool m_ownership; - - public OperationContext(LogicalOperation operation, bool ownership) { - Safe.ArgumentNotNull(operation, "operation"); - - m_initial = operation; - m_current = operation; - m_ownership = ownership; - } - - public LogicalOperation CurrentOperation { - get { return m_current; } - } - - public void BeginLogicalOperation(string name) { - m_current = new LogicalOperation(name, m_current); - } - - public LogicalOperation DetachLogicalOperation() { - var detached = m_current; - if (m_current != LogicalOperation.EMPTY) { - if (m_current != m_initial) - m_current = m_current.Parent; - else if (m_ownership) - m_current = LogicalOperation.EMPTY; - else { - TraceLog.TraceWarning("DetachLogicalOperation can't be performed in the current context"); - detached = LogicalOperation.EMPTY; - } - } else { - TraceLog.TraceWarning("DetachLogicalOperation can't be performed in the current context"); - } - - return detached; - } - - public LogicalOperation EndLogicalOperation() { - var current = m_current; - if (m_current != LogicalOperation.EMPTY && (m_current != m_initial || m_ownership)) { - m_current = m_current.Parent; - if (current == m_initial) { - // we have complete the owned operation - m_initial = m_current; - m_ownership = false; - } - } else { - TraceLog.TraceWarning("EndLogicalOperation can't be performed in the current context"); - } - return current; - } - - public void Leave() { - - if ((m_ownership && m_current != LogicalOperation.EMPTY) || (!m_ownership && m_current != m_initial) ) - TraceLog.TraceWarning("Trying to leave unfinished logical operation {0}", m_current.Name); - } - } -} - diff --git a/Implab/Diagnostics/TextFileListener.cs b/Implab/Diagnostics/TextFileListener.cs deleted file mode 100644 --- a/Implab/Diagnostics/TextFileListener.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.IO; -using System.Text; - -namespace Implab.Diagnostics { - public class TextFileListener: ListenerBase { - readonly TextWriter m_textWriter; - readonly object m_lock = new object(); - - public TextFileListener(string fileName) { - m_textWriter = File.CreateText(fileName); - - m_textWriter.WriteLine("LOG {0}", DateTime.Now); - } - - #region implemented abstract members of ListenerBase - - public override void Write(LogEventArgs args, object entry) { - var msg = new StringBuilder(); - for (int i = 0; i < args.Operation.Level; i++) - msg.Append(" "); - msg.AppendFormat("[{0}]+{3}ms:{1}: {2}", args.ThreadId, args.Channel, entry, args.OperationTimeOffset); - - lock (m_lock) { - if (!IsDisposed) { - // тут гарантировано еще не освобожден m_textWriter - m_textWriter.WriteLine(msg); - m_textWriter.Flush(); - } - } - } - - #endregion - - protected override void Dispose(bool disposing) { - base.Dispose(disposing); - if (disposing) { - // IsDisposed = true - lock (m_lock) { - Safe.Dispose(m_textWriter); - } - } - } - - - } -} diff --git a/Implab/Diagnostics/Trace.cs b/Implab/Diagnostics/Trace.cs --- a/Implab/Diagnostics/Trace.cs +++ b/Implab/Diagnostics/Trace.cs @@ -8,10 +8,10 @@ using System.Threading.Tasks; namespace Implab.Diagnostics { public static class Trace { - readonly static LogChannel _channel = new LogChannel(typeof(T).Name); - - public static LogChannel Channel { - get { return _channel; } + readonly static TraceSource _traceSource = new TraceSource(typeof(T).Name); + + public static TraceSource TraceSource { + get { return _traceSource; } } /// @@ -19,7 +19,7 @@ namespace Implab.Diagnostics { /// [Conditional("TRACE")] public static void StartLogicalOperation() { - TraceContext.Instance.StartLogicalOperation(); + Trace.CorrelationManager.StartLogicalOperation(); } @@ -29,17 +29,15 @@ namespace Implab.Diagnostics { /// Name. [Conditional("TRACE")] public static void StartLogicalOperation(string name) { - Channel.LogEvent(new TraceEvent(TraceContext.Instance.CurrentOperation, TraceEventType.OperationStarted, name)); - TraceContext.Instance.StartLogicalOperation(name); + Trace.CorrelationManager.StartLogicalOperation(); } /// /// Ends the logical operation and restores the previous one. /// [Conditional("TRACE")] - public static void EndLogicalOperation() { - var op = TraceContext.Instance.EndLogicalOperation(); - Channel.LogEvent(new TraceEvent(op, TraceEventType.OperationCompleted, String.Format("-{0} : {1}ms", op.Name, op.Duration))); + public static void StopLogicalOperation() { + Trace.CorrelationManager.StopLogicalOperation(); } /// @@ -49,7 +47,7 @@ namespace Implab.Diagnostics { /// Arguments. [Conditional("TRACE")] public static void Log(string format, params object[] arguments) { - Channel.LogEvent(TraceEvent.Create(TraceContext.Instance.CurrentOperation, TraceEventType.Information, format, arguments)); + TraceSource.TraceEvent(TraceEventType.Information, 1, format, arguments); } /// @@ -59,17 +57,17 @@ namespace Implab.Diagnostics { /// Arguments. [Conditional("TRACE")] public static void Warn(string format, params object[] arguments) { - Channel.LogEvent(TraceEvent.Create(TraceContext.Instance.CurrentOperation, TraceEventType.Warning, format, arguments)); + TraceSource.TraceEvent(TraceEventType.Warning, 1, format, arguments); } [Conditional("TRACE")] public static void Error(string format, params object[] arguments) { - Channel.LogEvent(TraceEvent.Create(TraceContext.Instance.CurrentOperation, TraceEventType.Error, format, arguments)); + TraceSource.TraceEvent(TraceEventType.Error, 1, format, arguments); } [Conditional("TRACE")] public static void Error(Exception err) { - Error("{0}", err); + TraceSource.TraceData(TraceEventType.Error, 1, err); } } } diff --git a/Implab/Diagnostics/TraceContext.cs b/Implab/Diagnostics/TraceContext.cs deleted file mode 100644 --- a/Implab/Diagnostics/TraceContext.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading; - -namespace Implab.Diagnostics { - /// - /// Trace context is bound to the specific thread, each thread has it's own ThreadContext. - /// - /// - /// ThreadContext manages relations between logical operations and threads. - /// - public class TraceContext { - - [ThreadStatic] - static TraceContext _instance; - - OperationContext m_current = OperationContext.EMPTY; - readonly Stack m_stack = new Stack(); - readonly int m_threadId; - - public static TraceContext Instance { - get { - if (_instance == null) - _instance = new TraceContext(); - return _instance; - } - } - - public TraceContext() { - m_threadId = Thread.CurrentThread.ManagedThreadId; - } - - public int ThreadId { - get { return m_threadId; } - } - - public LogicalOperation CurrentOperation { - get { - return m_current.CurrentOperation; - } - } - - public void EnterLogicalOperation(LogicalOperation operation, bool takeOwnership) { - //var prev = CurrentOperation; - //LogChannel.Default.LogEvent(new TraceEvent(takeOwnership ? TraceEventType.Attach : TraceEventType.Enter, String.Format("{0} -> {1}",prev.Name, operation.Name))); - m_stack.Push(m_current); - m_current = new OperationContext(operation, takeOwnership); - } - - public void StartLogicalOperation(string name) { - //LogChannel.Default.LogEvent(new TraceEvent(TraceContext.Instance.CurrentOperation, TraceEventType.OperationStarted, name)); - m_current.BeginLogicalOperation(name); - } - - public void StartLogicalOperation() { - StartLogicalOperation(String.Empty); - } - - public LogicalOperation EndLogicalOperation() { - return m_current.EndLogicalOperation(); - } - - public LogicalOperation DetachLogicalOperation() { - var prev = m_current.DetachLogicalOperation(); - //LogChannel.Default.LogEvent(new TraceEvent(TraceEventType.Detach, String.Format("{0} -> {1}",prev.Name, CurrentOperation.Name))); - return prev; - } - - public void Leave() { - if (m_stack.Count > 0) { - m_current.Leave(); - //var prev = CurrentOperation; - m_current = m_stack.Pop(); - //LogChannel.Default.LogEvent(new TraceEvent(TraceEventType.Leave, String.Format("{0} -> {1}", prev.Name, CurrentOperation.Name))); - } else { - TraceLog.TraceWarning("Attempt to leave the last operation context"); - m_current = OperationContext.EMPTY; - } - } - } -} - diff --git a/Implab/Diagnostics/TraceEvent.cs b/Implab/Diagnostics/TraceEvent.cs deleted file mode 100644 --- a/Implab/Diagnostics/TraceEvent.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; - -namespace Implab.Diagnostics { - public class TraceEvent { - public string Message { - get; - private set; - } - - public TraceEventType EventType { - get; - private set; - } - - /// - /// The logical operation this event belongs to. - /// - public LogicalOperation Operation { - get; - private set; - } - - /// - /// Gets the time offset in milliseconds from the start of the operation, if the operation is not specified the value is zero. - /// - public int OperationTime { - get; - private set; - } - - public TraceEvent(LogicalOperation operation, TraceEventType type, string message) { - EventType = type; - Message = message; - Operation = operation; - if (operation != null) - OperationTime = operation.Duration; - } - - public override string ToString() { - return Message; - } - - public static TraceEvent Create(LogicalOperation operation, TraceEventType type, string format, params object[] args) { - return new TraceEvent(operation, type, format == null ? String.Empty : args == null || args.Length == 0 ? format : String.Format(format, args)); - } - } -} diff --git a/Implab/Diagnostics/TraceEventType.cs b/Implab/Diagnostics/TraceEventType.cs deleted file mode 100644 --- a/Implab/Diagnostics/TraceEventType.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Implab.Diagnostics { - public enum TraceEventType { - Information = 1, - Warning, - Error, - OperationStarted, - OperationCompleted, - Attach, - Detach, - Enter, - Leave - } -} diff --git a/Implab/Diagnostics/TraceLog.cs b/Implab/Diagnostics/TraceLog.cs deleted file mode 100644 --- a/Implab/Diagnostics/TraceLog.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Implab.Diagnostics { - /// - /// This class is used to trace a logical flow of the application, it publishes events to the default channel. - /// - public static class TraceLog { - /// - /// Starts the logical operation nested to the current operation nested to the current one. - /// - [Conditional("TRACE")] - public static void StartLogicalOperation() { - TraceContext.Instance.StartLogicalOperation(); - - } - - /// - /// Starts the logical operation with the specified name, this name is usefull in logs. - /// - /// Name. - [Conditional("TRACE")] - public static void StartLogicalOperation(string name) { - TraceContext.Instance.StartLogicalOperation(name); - } - - /// - /// Ends the logical operation and restores the previous one. - /// - [Conditional("TRACE")] - public static void EndLogicalOperation() { - var op = TraceContext.Instance.EndLogicalOperation(); - LogChannel.Default.LogEvent(new TraceEvent(op, TraceEventType.OperationCompleted, String.Format("-{0} : {1}ms",op.Name, op.Duration))); - } - - /// - /// Writes an informational message. - /// - /// Format. - /// Arguments. - [Conditional("TRACE")] - public static void TraceInformation(string format, params object[] arguments) { - LogChannel.Default.LogEvent(TraceEvent.Create(TraceContext.Instance.CurrentOperation, TraceEventType.Information, format, arguments)); - } - - /// - /// Writes a warning message. - /// - /// Format. - /// Arguments. - [Conditional("TRACE")] - public static void TraceWarning(string format, params object[] arguments) { - LogChannel.Default.LogEvent(TraceEvent.Create(TraceContext.Instance.CurrentOperation, TraceEventType.Warning, format, arguments)); - } - - [Conditional("TRACE")] - public static void TraceError(string format, params object[] arguments) { - LogChannel.Default.LogEvent(TraceEvent.Create(TraceContext.Instance.CurrentOperation, TraceEventType.Error, format, arguments)); - } - - [Conditional("TRACE")] - public static void TraceError(Exception err) { - TraceError("{0}", err); - } - } -}