##// END OF EJS Templates
Added Skip method to JSON parser to skip contents of the current node
Added Skip method to JSON parser to skip contents of the current node

File last commit:

r52:edf0bc558596 default
r62:62b440d46313 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;
}
}
public void BindLogicalOperationToPromise(IPromiseBase promise) {
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 }
}
}