Mercurial > pub > ImplabNet
changeset 252:6f4630d0bcd9 v3
removed absolete Diagnostics classes
author | cin |
---|---|
date | Mon, 12 Feb 2018 07:24:31 +0300 |
parents | 7c7e9ad6fe4a |
children | 34df34841225 |
files | Implab.Diagnostics.Interactive/Implab.Diagnostics.Interactive.csproj Implab.Diagnostics.Interactive/InteractiveListener.cs Implab.Diagnostics.Interactive/Properties/AssemblyInfo.cs Implab.Diagnostics.Interactive/Properties/DataSources/TraceViewItem.datasource Implab.Diagnostics.Interactive/TextStyle.cs Implab.Diagnostics.Interactive/TraceForm.Designer.cs Implab.Diagnostics.Interactive/TraceForm.cs Implab.Diagnostics.Interactive/TraceForm.resx Implab.Diagnostics.Interactive/TraceViewItem.cs Implab.Test/UnitTest1.cs Implab/Components/Disposable.cs Implab/Components/RunnableComponent.cs Implab/Diagnostics/ConsoleTraceListener.cs Implab/Diagnostics/ILogWriter.cs Implab/Diagnostics/ListenerBase.cs Implab/Diagnostics/LogChannel.cs Implab/Diagnostics/LogEventArgs.cs Implab/Diagnostics/LogEventArgsT.cs Implab/Diagnostics/LogicalOperation.cs Implab/Diagnostics/OperationContext.cs Implab/Diagnostics/TextFileListener.cs Implab/Diagnostics/Trace.cs Implab/Diagnostics/TraceContext.cs Implab/Diagnostics/TraceEvent.cs Implab/Diagnostics/TraceEventType.cs Implab/Diagnostics/TraceLog.cs |
diffstat | 26 files changed, 29 insertions(+), 1303 deletions(-) [+] |
line wrap: on
line diff
--- a/Implab.Diagnostics.Interactive/Implab.Diagnostics.Interactive.csproj Sun Feb 11 00:49:51 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> - <PropertyGroup> - <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> - <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> - <ProjectGuid>{1DB7DB0C-8AA9-484B-A681-33AE94038391}</ProjectGuid> - <OutputType>Library</OutputType> - <AppDesignerFolder>Properties</AppDesignerFolder> - <RootNamespace>Implab.Diagnostics.Interactive</RootNamespace> - <AssemblyName>Implab.Diagnostics.Interactive</AssemblyName> - <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> - <FileAlignment>512</FileAlignment> - </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> - <DebugSymbols>true</DebugSymbols> - <DebugType>full</DebugType> - <Optimize>false</Optimize> - <OutputPath>bin\Debug\</OutputPath> - <DefineConstants>DEBUG;TRACE</DefineConstants> - <ErrorReport>prompt</ErrorReport> - <WarningLevel>4</WarningLevel> - </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> - <DebugType>pdbonly</DebugType> - <Optimize>true</Optimize> - <OutputPath>bin\Release\</OutputPath> - <DefineConstants>TRACE</DefineConstants> - <ErrorReport>prompt</ErrorReport> - <WarningLevel>4</WarningLevel> - </PropertyGroup> - <ItemGroup> - <Reference Include="System" /> - <Reference Include="System.Core" /> - <Reference Include="System.Drawing" /> - <Reference Include="System.Windows.Forms" /> - <Reference Include="System.Xml.Linq" /> - <Reference Include="System.Data.DataSetExtensions" /> - <Reference Include="Microsoft.CSharp" /> - <Reference Include="System.Data" /> - <Reference Include="System.Xml" /> - </ItemGroup> - <ItemGroup> - <Compile Include="InteractiveListener.cs" /> - <Compile Include="Properties\AssemblyInfo.cs" /> - <Compile Include="TextStyle.cs" /> - <Compile Include="TraceForm.cs"> - <SubType>Form</SubType> - </Compile> - <Compile Include="TraceForm.Designer.cs"> - <DependentUpon>TraceForm.cs</DependentUpon> - </Compile> - <Compile Include="TraceViewItem.cs" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="..\Implab\Implab.csproj"> - <Project>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</Project> - <Name>Implab</Name> - </ProjectReference> - </ItemGroup> - <ItemGroup> - <EmbeddedResource Include="TraceForm.resx"> - <DependentUpon>TraceForm.cs</DependentUpon> - </EmbeddedResource> - </ItemGroup> - <ItemGroup> - <None Include="Properties\DataSources\TraceViewItem.datasource" /> - </ItemGroup> - <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> - <!-- To modify your build process, add your task inside one of the targets below and uncomment it. - Other similar extension points exist, see Microsoft.Common.targets. - <Target Name="BeforeBuild"> - </Target> - <Target Name="AfterBuild"> - </Target> - --> -</Project> \ No newline at end of file
--- a/Implab.Diagnostics.Interactive/InteractiveListener.cs Sun Feb 11 00:49:51 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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<TraceViewItem> m_queue = new SimpleAsyncQueue<TraceViewItem>(); - 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); - } - } -}
--- a/Implab.Diagnostics.Interactive/Properties/AssemblyInfo.cs Sun Feb 11 00:49:51 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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")]
--- a/Implab.Diagnostics.Interactive/Properties/DataSources/TraceViewItem.datasource Sun Feb 11 00:49:51 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - This file is automatically generated by Visual Studio .Net. It is - used to store generic object data source configuration information. - Renaming the file extension or editing the content of this file may - cause the file to be unrecognizable by the program. ---> -<GenericObjectDataSource DisplayName="TraceViewItem" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource"> - <TypeInfo>Implab.Diagnostics.Interactive.TraceViewItem, Implab.Diagnostics.Interactive</TypeInfo> -</GenericObjectDataSource> \ No newline at end of file
--- a/Implab.Diagnostics.Interactive/TextStyle.cs Sun Feb 11 00:49:51 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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; - } - } -}
--- a/Implab.Diagnostics.Interactive/TraceForm.Designer.cs Sun Feb 11 00:49:51 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,149 +0,0 @@ -namespace Implab.Diagnostics.Interactive { - partial class TraceForm { - /// <summary> - /// Required designer variable. - /// </summary> - private System.ComponentModel.IContainer components = null; - - /// <summary> - /// Clean up any resources being used. - /// </summary> - /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// <summary> - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// </summary> - 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
--- a/Implab.Diagnostics.Interactive/TraceForm.cs Sun Feb 11 00:49:51 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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<int, Color> m_threadColors = new Dictionary<int,Color>(); - 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); - } - } -}
--- a/Implab.Diagnostics.Interactive/TraceForm.resx Sun Feb 11 00:49:51 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,129 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<root> - <!-- - Microsoft ResX Schema - - Version 2.0 - - The primary goals of this format is to allow a simple XML format - that is mostly human readable. The generation and parsing of the - various data types are done through the TypeConverter classes - associated with the data types. - - Example: - - ... ado.net/XML headers & schema ... - <resheader name="resmimetype">text/microsoft-resx</resheader> - <resheader name="version">2.0</resheader> - <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> - <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> - <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> - <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> - <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> - <value>[base64 mime encoded serialized .NET Framework object]</value> - </data> - <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> - <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> - <comment>This is a comment</comment> - </data> - - There are any number of "resheader" rows that contain simple - name/value pairs. - - Each data row contains a name, and value. The row also contains a - type or mimetype. Type corresponds to a .NET class that support - text/value conversion through the TypeConverter architecture. - Classes that don't support this are serialized and stored with the - mimetype set. - - The mimetype is used for serialized objects, and tells the - ResXResourceReader how to depersist the object. This is currently not - extensible. For a given mimetype the value must be set accordingly: - - Note - application/x-microsoft.net.object.binary.base64 is the format - that the ResXResourceWriter will generate, however the reader can - read any of the formats listed below. - - mimetype: application/x-microsoft.net.object.binary.base64 - value : The object must be serialized with - : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter - : and then encoded with base64 encoding. - - mimetype: application/x-microsoft.net.object.soap.base64 - value : The object must be serialized with - : System.Runtime.Serialization.Formatters.Soap.SoapFormatter - : and then encoded with base64 encoding. - - mimetype: application/x-microsoft.net.object.bytearray.base64 - value : The object must be serialized into a byte array - : using a System.ComponentModel.TypeConverter - : and then encoded with base64 encoding. - --> - <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> - <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> - <xsd:element name="root" msdata:IsDataSet="true"> - <xsd:complexType> - <xsd:choice maxOccurs="unbounded"> - <xsd:element name="metadata"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" /> - </xsd:sequence> - <xsd:attribute name="name" use="required" type="xsd:string" /> - <xsd:attribute name="type" type="xsd:string" /> - <xsd:attribute name="mimetype" type="xsd:string" /> - <xsd:attribute ref="xml:space" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="assembly"> - <xsd:complexType> - <xsd:attribute name="alias" type="xsd:string" /> - <xsd:attribute name="name" type="xsd:string" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="data"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> - <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> - </xsd:sequence> - <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> - <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> - <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> - <xsd:attribute ref="xml:space" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="resheader"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> - </xsd:sequence> - <xsd:attribute name="name" type="xsd:string" use="required" /> - </xsd:complexType> - </xsd:element> - </xsd:choice> - </xsd:complexType> - </xsd:element> - </xsd:schema> - <resheader name="resmimetype"> - <value>text/microsoft-resx</value> - </resheader> - <resheader name="version"> - <value>2.0</value> - </resheader> - <resheader name="reader"> - <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </resheader> - <resheader name="writer"> - <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </resheader> - <metadata name="TimeDelta.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> - <value>True</value> - </metadata> - <metadata name="Channel.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> - <value>True</value> - </metadata> - <metadata name="traceViewItemBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> - <value>17, 17</value> - </metadata> -</root> \ No newline at end of file
--- a/Implab.Diagnostics.Interactive/TraceViewItem.cs Sun Feb 11 00:49:51 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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; - } - } - } -}
--- a/Implab.Test/UnitTest1.cs Sun Feb 11 00:49:51 2018 +0300 +++ b/Implab.Test/UnitTest1.cs Mon Feb 12 07:24:31 2018 +0300 @@ -1,29 +1,37 @@ using System; using System.Diagnostics; using System.Threading; +using Implab.Diagnostics; using Xunit; namespace Implab.Test { + using static Trace<UnitTest1>; 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(); } } }
--- a/Implab/Components/Disposable.cs Sun Feb 11 00:49:51 2018 +0300 +++ b/Implab/Components/Disposable.cs Mon Feb 12 07:24:31 2018 +0300 @@ -48,16 +48,8 @@ } } - /// <summary> - /// Записывает сообщение об утечке объекта. - /// </summary> - 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
--- a/Implab/Components/RunnableComponent.cs Sun Feb 11 00:49:51 2018 +0300 +++ b/Implab/Components/RunnableComponent.cs Mon Feb 12 07:24:31 2018 +0300 @@ -15,7 +15,7 @@ public class RunnableComponent : IRunnable, IInitializable, IDisposable { /// <summary> - /// This class bound <see cref="CancellationTokenSource"/> lifetime to the task, + /// This class bounds <see cref="CancellationTokenSource"/> lifetime to the task, /// when the task completes the associated token source will be disposed. /// </summary> class AsyncOperationDescriptor { @@ -161,7 +161,7 @@ /// <remarks> /// This method should be used for short and mostly syncronous operations, /// other operations which require time to run shoud be placed in - /// <see cref="StartInternal(CancellationToken)"/> method. + /// <see cref="StartInternalAsync(CancellationToken)"/> method. /// </remarks> protected virtual Task InitializeInternalAsync(CancellationToken ct) { return Task.CompletedTask; @@ -170,10 +170,10 @@ 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; }
--- a/Implab/Diagnostics/ConsoleTraceListener.cs Sun Feb 11 00:49:51 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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); - } - } - } -}
--- a/Implab/Diagnostics/ILogWriter.cs Sun Feb 11 00:49:51 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -using System; - -namespace Implab.Diagnostics { - public interface ILogWriter<in TEvent> { - void Write(LogEventArgs args, TEvent entry); - } -} -
--- a/Implab/Diagnostics/ListenerBase.cs Sun Feb 11 00:49:51 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -using System; -using System.Collections.Generic; -using Implab.Components; - -namespace Implab.Diagnostics { - public abstract class ListenerBase : ServiceLocator, ILogWriter<object>, ILogWriter<TraceEvent> { - - readonly Dictionary<object, Action> m_subscriptions = new Dictionary<object, Action>(); - - 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<TEvent>() { - Subscribe<TEvent>(LogChannel<TEvent>.Default); - } - - public void Subscribe<TEvent>(LogChannel<TEvent> channel) { - if (channel == null) - throw new ArgumentNullException("channel"); - - lock (m_subscriptions) { - AssertNotDisposed(); - if (m_subscriptions.ContainsKey(channel)) - return; - - var writer = GetService<ILogWriter<TEvent>>(); - - EventHandler<LogEventArgs<TEvent>> handler = (sender, args) => writer.Write(args,args.Value); - - channel.Events += handler; - - Action unsubscribe = () => { - channel.Events -= handler; - }; - - m_subscriptions.Add(channel, unsubscribe); - } - } - - public void Unsubscribe<TEvent>(LogChannel<TEvent> 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(); - } - } - } -}
--- a/Implab/Diagnostics/LogChannel.cs Sun Feb 11 00:49:51 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Implab.Diagnostics { - /// <summary> - /// Канал, через который публикуются события журнала. - /// </summary> - /// <typeparam name="TEvent">Тип событий в канале</typeparam> - /// <remarks> - /// Событиями журнала могут быть любые типы, например строки, в которых будет передаваться - /// информация, или структуры с набором полей, описывающих важность, текст и другую информацию. - /// </remarks> - public class LogChannel<TEvent> { - static LogChannel<TEvent> _default = new LogChannel<TEvent>(); - - /// <summary> - /// Канал по-умолчанию для событий типа <typeparam name="TEvent"/>. - /// </summary> - public static LogChannel<TEvent> Default { - get { - return _default; - } - } - - /// <summary> - /// Событие появление новой записи в журнале, на это событие подписываются слушатели. - /// </summary> - public event EventHandler<LogEventArgs<TEvent>> Events; - - /// <summary> - /// Имя канала, полезно для отображения в журнале - /// </summary> - public string Name { - get; - private set; - } - - /// <summary> - /// Создает журнал, имя типа событий назначается в качетве имени канала. - /// </summary> - public LogChannel() - : this(null) { - } - - /// <summary> - /// Содает канал с указанным именем. - /// </summary> - /// <param name="name">Имя канала.</param> - public LogChannel(string name) { - if (String.IsNullOrEmpty(name)) - name = typeof(TEvent).Name; - Name = name; - } - - /// <summary> - /// Отправляет запись журнала через канал подписчикам. - /// </summary> - /// <param name="data">Запись журнала.</param> - /// <remarks> - /// Контекст трассировки от которого рассылается сообщение определяется автоматически из текущего потока. - /// </remarks> - public void LogEvent(TEvent data) { - var t = Events; - if (t != null) { - var traceContext = TraceContext.Instance; - t( - this, - new LogEventArgs<TEvent>( - data, - this, - traceContext.ThreadId, - traceContext.CurrentOperation, - traceContext.CurrentOperation.Duration - ) - ); - } - } - - public override string ToString() { - return Name; - } - } -}
--- a/Implab/Diagnostics/LogEventArgs.cs Sun Feb 11 00:49:51 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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; - } - } -} -
--- a/Implab/Diagnostics/LogEventArgsT.cs Sun Feb 11 00:49:51 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -namespace Implab.Diagnostics { - public class LogEventArgs<TEvent> : 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; - } - } -} -
--- a/Implab/Diagnostics/LogicalOperation.cs Sun Feb 11 00:49:51 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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; } - } - } -}
--- a/Implab/Diagnostics/OperationContext.cs Sun Feb 11 00:49:51 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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); - } - } -} -
--- a/Implab/Diagnostics/TextFileListener.cs Sun Feb 11 00:49:51 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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); - } - } - } - - - } -}
--- a/Implab/Diagnostics/Trace.cs Sun Feb 11 00:49:51 2018 +0300 +++ b/Implab/Diagnostics/Trace.cs Mon Feb 12 07:24:31 2018 +0300 @@ -8,10 +8,10 @@ namespace Implab.Diagnostics { public static class Trace<T> { - readonly static LogChannel<TraceEvent> _channel = new LogChannel<TraceEvent>(typeof(T).Name); - - public static LogChannel<TraceEvent> Channel { - get { return _channel; } + readonly static TraceSource _traceSource = new TraceSource(typeof(T).Name); + + public static TraceSource TraceSource { + get { return _traceSource; } } /// <summary> @@ -19,7 +19,7 @@ /// </summary> [Conditional("TRACE")] public static void StartLogicalOperation() { - TraceContext.Instance.StartLogicalOperation(); + Trace.CorrelationManager.StartLogicalOperation(); } @@ -29,17 +29,15 @@ /// <param name="name">Name.</param> [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(); } /// <summary> /// Ends the logical operation and restores the previous one. /// </summary> [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(); } /// <summary> @@ -49,7 +47,7 @@ /// <param name="arguments">Arguments.</param> [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); } /// <summary> @@ -59,17 +57,17 @@ /// <param name="arguments">Arguments.</param> [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); } } }
--- a/Implab/Diagnostics/TraceContext.cs Sun Feb 11 00:49:51 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading; - -namespace Implab.Diagnostics { - /// <summary> - /// Trace context is bound to the specific thread, each thread has it's own ThreadContext. - /// </summary> - /// <remarks> - /// ThreadContext manages relations between logical operations and threads. - /// </remarks> - public class TraceContext { - - [ThreadStatic] - static TraceContext _instance; - - OperationContext m_current = OperationContext.EMPTY; - readonly Stack<OperationContext> m_stack = new Stack<OperationContext>(); - 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<TraceEvent>.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<TraceEvent>.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<TraceEvent>.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<TraceEvent>.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; - } - } - } -} -
--- a/Implab/Diagnostics/TraceEvent.cs Sun Feb 11 00:49:51 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -using System; - -namespace Implab.Diagnostics { - public class TraceEvent { - public string Message { - get; - private set; - } - - public TraceEventType EventType { - get; - private set; - } - - /// <summary> - /// The logical operation this event belongs to. - /// </summary> - public LogicalOperation Operation { - get; - private set; - } - - /// <summary> - /// Gets the time offset in milliseconds from the start of the operation, if the operation is not specified the value is zero. - /// </summary> - 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)); - } - } -}
--- a/Implab/Diagnostics/TraceEventType.cs Sun Feb 11 00:49:51 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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 - } -}
--- a/Implab/Diagnostics/TraceLog.cs Sun Feb 11 00:49:51 2018 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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 { - /// <summary> - /// This class is used to trace a logical flow of the application, it publishes events to the default <see cref="TraceEvent"/> channel. - /// </summary> - public static class TraceLog { - /// <summary> - /// Starts the logical operation nested to the current operation nested to the current one. - /// </summary> - [Conditional("TRACE")] - public static void StartLogicalOperation() { - TraceContext.Instance.StartLogicalOperation(); - - } - - /// <summary> - /// Starts the logical operation with the specified name, this name is usefull in logs. - /// </summary> - /// <param name="name">Name.</param> - [Conditional("TRACE")] - public static void StartLogicalOperation(string name) { - TraceContext.Instance.StartLogicalOperation(name); - } - - /// <summary> - /// Ends the logical operation and restores the previous one. - /// </summary> - [Conditional("TRACE")] - public static void EndLogicalOperation() { - var op = TraceContext.Instance.EndLogicalOperation(); - LogChannel<TraceEvent>.Default.LogEvent(new TraceEvent(op, TraceEventType.OperationCompleted, String.Format("-{0} : {1}ms",op.Name, op.Duration))); - } - - /// <summary> - /// Writes an informational message. - /// </summary> - /// <param name="format">Format.</param> - /// <param name="arguments">Arguments.</param> - [Conditional("TRACE")] - public static void TraceInformation(string format, params object[] arguments) { - LogChannel<TraceEvent>.Default.LogEvent(TraceEvent.Create(TraceContext.Instance.CurrentOperation, TraceEventType.Information, format, arguments)); - } - - /// <summary> - /// Writes a warning message. - /// </summary> - /// <param name="format">Format.</param> - /// <param name="arguments">Arguments.</param> - [Conditional("TRACE")] - public static void TraceWarning(string format, params object[] arguments) { - LogChannel<TraceEvent>.Default.LogEvent(TraceEvent.Create(TraceContext.Instance.CurrentOperation, TraceEventType.Warning, format, arguments)); - } - - [Conditional("TRACE")] - public static void TraceError(string format, params object[] arguments) { - LogChannel<TraceEvent>.Default.LogEvent(TraceEvent.Create(TraceContext.Instance.CurrentOperation, TraceEventType.Error, format, arguments)); - } - - [Conditional("TRACE")] - public static void TraceError(Exception err) { - TraceError("{0}", err); - } - } -}