internal ProfileOperation StartMeasure([NotNull] ProfileOperationSpecification specification) { if (specification == null) { throw new ArgumentNullException(nameof(specification)); } if (this.operationsStack.Value == null) { this.operationsStack.Value = new Stack <ProfileOperation>(); } var operation_stack = this.operationsStack.Value; var last_operation = operation_stack.Count > 0 ? operation_stack.Peek() : null; this.newId++; var operation = new ProfileOperation(id: this.newId, profiler: this.Profiler, session: this, specification: specification, parent: last_operation); this.operations.Add(operation); operation_stack.Push(operation); return(operation); }
public static ProfileOperation WithOperationData([CanBeNull] this ProfileOperation operation, [NotNull] string dataKey, [CanBeNull] object dataValue) { if (operation != null) { operation[dataKey] = dataValue; } return(operation); }
/// <summary> /// Initializes a new instance of the <see cref="ProfileOperation" /> class.<br /> /// This method indended to be called from <see cref="ProfileSession"/> /// and should not be called manually. /// </summary> public ProfileOperation(int id, [NotNull] IProfiler profiler, [CanBeNull] ProfileSession session, [NotNull] ProfileOperationSpecification specification, [CanBeNull] ProfileOperation parent) { if (specification == null) { throw new ArgumentNullException(nameof(specification)); } this.Id = id; this.Profiler = profiler ?? throw new ArgumentNullException(nameof(profiler)); if (session != null) { if (session.Profiler != profiler) { throw new InvalidOperationException("Session.Profiler does not match specified profiler."); } this.Session = session; this.StartTime = session.Time; } if (this.Profiler.Configuration.CaptureCallStacks) { var current_assembly = this.GetType().Assembly; this.CallStack = new StackTrace(true).ToAsyncString(x => x.DeclaringType?.Assembly != current_assembly); } this.Name = specification.Name; this.Category = specification.Category; this.Resource = specification.Resource; this.NormalDuration = specification.NormalDuration; this.StartDate = DateTime.UtcNow; this.Parent = parent; if (specification.Data != null) { this.Data = new Dictionary <string, object>(specification.Data, StringComparer.Ordinal); } // start timer as close to the profiled code as possible this.time = Stopwatch.StartNew(); }
/// <summary> /// Stops operation measure. /// This method should not be called directly - it will be called automatically /// uppon disposing of <see cref="ProfileOperation" /> returned from <see cref="StartMeasure" />. /// </summary> /// <exception cref="ArgumentNullException"><paramref name="operation"/> is <see langword="null" />.</exception> internal void StopMeasure([NotNull] ProfileOperation operation) { if (operation == null) { throw new ArgumentNullException(nameof(operation)); } try { if (operation.Session != this) { throw new OperationFromAnotherSessionProfilingException(); } var operation_stack = this.operationsStack.Value; if (operation_stack == null) { throw new OperationsOutOfOrderProfillingException(); } var current_operation = operation_stack.Pop(); if (current_operation != operation) { throw new OperationsOutOfOrderProfillingException(); } var parent_operation = operation_stack.Count > 0 ? operation_stack.Peek() : null; if (parent_operation != operation.Parent) { throw new OperationsOutOfOrderProfillingException(); } operation.EndTime = this.Time; this.Duration += operation.Duration; if (operation.Duration >= operation.NormalDuration) { this.HasOperationLongerThanNormal = true; } } catch (Exception ex) { this.logger.LogError(ex); } }
internal ProfileOperation StartMeasure([NotNull] ProfileOperationSpecification specification) { if (specification == null) { throw new ArgumentNullException(nameof(specification)); } this.newId++; var operation = new ProfileOperation(id: this.newId, profiler: this.Profiler, session: this, specification: specification, parent: this.currentParentOperation.Value); lock (this.operations) this.operations.Add(operation); this.currentParentOperation.Value = operation; return(operation); }
/// <summary> /// Stops operation measure. /// This method should not be called directly - it will be called automatically /// uppon disposing of <see cref="ProfileOperation" /> returned from <see cref="StartMeasure" />. /// </summary> /// <exception cref="ArgumentNullException"><paramref name="operation"/> is <see langword="null" />.</exception> internal void StopMeasure([NotNull] ProfileOperation operation) { if (operation == null) { throw new ArgumentNullException(nameof(operation)); } try { if (operation.Session != this) { throw new OperationFromAnotherSessionProfilingException(); } if (this.currentParentOperation.Value == operation) { this.currentParentOperation.Value = operation.Parent; } else { this.logger.LogWarning($"Operations are out of order. Current parent operation does not match completed operation \"{operation}\"."); } operation.EndTime = this.Time; this.Duration += operation.Duration; if (operation.Duration >= operation.NormalDuration) { this.HasOperationLongerThanNormal = true; } } catch (Exception ex) { this.logger.LogError(ex); } }