##// END OF EJS Templates
code cleanup
code cleanup

File last commit:

r66:790e8a997d30 default
r71:1714fd8678ef default
Show More
TraceContext.cs
238 lines | 11.2 KiB | text/x-csharp | CSharpLexer
cin
improved log concept
r36 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Implab.Diagnostics {
cin
improved tracing...
r40 /// <summary>
/// Контекст трассировки, привязывается к потоку и содержит в себе информацию о стеке логических операций.
/// </summary>
/// <remarks>
/// Контекст трассировки передается слушателям событий для определения места, где возникло событие.
/// </remarks>
cin
improved log concept
r36 public class TraceContext {
LogicalOperation m_currentOperation;
cin
improved tracing...
r40 readonly LogicalOperation m_bound;
cin
improved log concept
r36 readonly int m_threadId;
[ThreadStatic]
static TraceContext _current;
cin
improved tracing...
r40 /// <summary>
/// Текущий контекст трассировки для потока, создается астоматически при первом обращении.
/// </summary>
cin
improved log concept
r36 public static TraceContext Current {
get {
cin
Interactive tracing...
r48 if (_current == null) {
cin
improved log concept
r36 _current = new TraceContext();
cin
Interactive tracing...
r48 _current.LogEvent(TraceEventType.Created,"[{0}]", _current.ThreadId);
}
cin
improved log concept
r36 return _current;
}
}
cin
Interactive tracing...
r48 TraceContext(TraceContext context)
: this(context, false) {
}
TraceContext(TraceContext context, bool attach) {
cin
improved log concept
r36 if (context == null)
throw new ArgumentNullException("context");
m_currentOperation = context.CurrentOperation;
cin
Interactive tracing...
r48 m_bound = attach ? context.BoundOperation : context.CurrentOperation;
cin
improved log concept
r36 m_threadId = Thread.CurrentThread.ManagedThreadId;
}
TraceContext() {
m_currentOperation = new LogicalOperation();
cin
improved tracing...
r40 m_bound = m_currentOperation;
cin
improved log concept
r36 m_threadId = Thread.CurrentThread.ManagedThreadId;
}
cin
improved tracing...
r40 /// <summary>
/// При необходимости копирует состояние контекста трассивровки в текущий поток.
/// </summary>
/// <param name="from">Исходный контекст трассировки, который передается.</param>
/// <remarks>
/// <para>
/// Копирование происходит за счет создания нового контекста трассировки и заполнением его
/// состояния из переданного контекста. При этом копируется стек операций, однако в новом
/// контексте ранее начатые логические операции не могут быть завершены.
/// </para>
/// <para>
cin
Interactive tracing...
r48 /// Если передача состояния состоялась, то вызывается событие трассировки <see cref="TraceEventType.Fork"/>.
cin
improved tracing...
r40 /// </para>
/// </remarks>
cin
Interactive tracing...
r48 public static void Fork(TraceContext from) {
cin
improved tracing...
r40 if (_current == from)
return;
if (from != null) {
var context = new TraceContext(from);
cin
Interactive tracing...
r48 context.LogEvent(TraceEventType.Fork, "[{0}]-->[{1}]",from.ThreadId, context.ThreadId);
cin
improved tracing...
r40 _current = context;
} else {
_current = new TraceContext();
cin
improved log concept
r36 }
}
cin
improved tracing...
r40 /// <summary>
cin
Interactive tracing...
r48 /// Задает текущему потоку указанный контекст, текущей поток может заканчивать ранее начатые
/// логические операции в указанном контексте.
/// </summary>
/// <param name="source"></param>
public static void Attach(TraceContext source) {
if (_current == source)
return;
if (source != null) {
var context = new TraceContext(source, true);
context.LogEvent(TraceEventType.Attach, "[{0}]-->[{1}]", source.ThreadId, context.ThreadId);
_current = context;
} else {
_current = new TraceContext();
}
}
/// <summary>
/// Отсоединяет текущий контекст трассировки от потока, для дальнейшей его передачи другому потоку
/// <see cref="Attach(TraceContext)"/>.
/// </summary>
/// <returns>Контекст трассировки потока</returns>
/// <remarks>
/// После отсоединения контекста трассировки от потока, при первом обращении к трассировке в этом
/// потоке будет создан новый контекст.
/// </remarks>
public static TraceContext Detach() {
var context = Current;
context.LogEvent(TraceEventType.Detach, null);
_current = null;
return context;
}
/// <summary>
/// Создает постоянную копию текущего контекста, данную копию можно хранить и использовать для передачи через <see cref="Fork(TraceContext)"/>
cin
improved tracing...
r40 /// </summary>
cin
Added TraceContext support to array traits
r41 /// <returns>Копия текущего контекста трассировки.</returns>
cin
improved tracing...
r40 public static TraceContext Snapshot() {
cin
improved trace system
r52 return _current == null ? new TraceContext() : new TraceContext(_current,false);
cin
improved tracing...
r40 }
/// <summary>
/// Выполняет переданное действие в указанном контексте трассировки, по окончании восстанавливает предыдущий контекст трассировки потока.
/// </summary>
/// <param name="action"></param>
public void Invoke(Action action) {
if (action == null)
throw new ArgumentNullException("action");
var old = _current;
cin
Interactive tracing...
r48 Fork(this);
cin
improved tracing...
r40 try {
action();
} finally {
cin
improved trace system
r52 if(_current != null)
_current.EndAllOperations();
cin
improved tracing...
r40 _current = old;
}
}
/// <summary>
/// Текущая логическая операция.
/// </summary>
cin
improved log concept
r36 public LogicalOperation CurrentOperation {
get {
return m_currentOperation;
}
}
cin
improved tracing...
r40 /// <summary>
/// Операция ниже которой нельзя опускаться в стеке логических операций, т.е. она не может быть завершена в текущем контексте.
/// </summary>
public LogicalOperation BoundOperation {
cin
improved log concept
r36 get {
cin
improved tracing...
r40 return m_bound;
cin
improved log concept
r36 }
}
cin
improved tracing...
r40 /// <summary>
/// Поток, в котором создан контекст трассировки.
/// </summary>
cin
improved log concept
r36 public int ThreadId {
get {
return m_threadId;
}
}
cin
improved tracing...
r40 /// <summary>
/// Начинает безымянную логическую операцию.
/// </summary>
cin
improved log concept
r36 public void StartLogicalOperation() {
StartLogicalOperation(null);
}
cin
improved tracing...
r40 /// <summary>
/// Начинает логическую операцию с указанным именем. Созданная операция будет добвалена в стек логических операций контекста, затем будет создано соответсвующее событие.
/// </summary>
/// <param name="name">Имя начинаемой операции.</param>
cin
improved log concept
r36 public void StartLogicalOperation(string name) {
m_currentOperation = new LogicalOperation(name, m_currentOperation);
cin
improved tracing...
r40 LogEvent(TraceEventType.OperationStarted, name);
cin
improved log concept
r36 }
cin
improved tracing...
r40 /// <summary>
/// Заканчивает логическую операцию начатую в текущем контексте. Операции, начатые в других контекстах не могут быть закончены в текущем контексте.
/// </summary>
/// <remarks>
/// При вызове данного метода создается событие журнала трассировки, либо о завершении операции, либо об ошибки, поскольку данная операция
/// начата в другом контексте.
/// </remarks>
cin
improved log concept
r36 public void EndLogicalOperation() {
cin
improved tracing...
r40 if (m_bound == m_currentOperation) {
cin
improved log concept
r36 LogEvent(TraceEventType.Error, "Trying to end the operation which isn't belongs to current trace");
} else {
var op = m_currentOperation;
cin
improved tracing...
r40 LogEvent(TraceEventType.OperationCompleted, "{0} {1} ms", op.Name, op.Duration);
cin
improved log concept
r36 m_currentOperation = m_currentOperation.Parent;
}
}
cin
improved tracing, TextListenerBase can be bound to logical operation scope.
r43 /// <summary>
cin
improved trace system
r52 /// Создает копию контекста и возвращается на предыдущую операцию в текущем контексте, это позволяет начать операцию в одном потоке, а завершить - в другом.
/// </summary>
/// <returns>Контекст трассировки, который можно присоединить к другому потоку.</returns>
public TraceContext DetachLogicalOperation() {
if (m_bound == m_currentOperation) {
return new TraceContext();
} else {
var detached = new TraceContext(this, true);
m_currentOperation = m_currentOperation.Parent;
return detached;
}
}
cin
Refactoring
r66 public void BindLogicalOperationToPromise(IPromise promise) {
cin
improved trace system
r52 Safe.ArgumentNotNull(promise, "promise");
var ctx = DetachLogicalOperation();
promise.Finally(() => {
var old = _current;
TraceContext.Attach(ctx);
TraceContext.Current.EndLogicalOperation();
_current = old;
});
}
/// <summary>
cin
improved tracing, TextListenerBase can be bound to logical operation scope.
r43 /// Заврешает все начатые в этом контексте операции
/// </summary>
public void EndAllOperations() {
while (m_bound != m_currentOperation)
EndLogicalOperation();
}
cin
improved log concept
r36 void LogEvent(TraceEventType type, string format, params object[] args) {
cin
working version of diagnostics logging
r37 LogChannel<TraceEvent>.Default.LogEvent(this, TraceEvent.Create(type, format, args));
cin
improved log concept
r36 }
}
}