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);
        }
Example #2
0
        public static ProfileOperation WithOperationData([CanBeNull] this ProfileOperation operation,
                                                         [NotNull] string dataKey,
                                                         [CanBeNull] object dataValue)
        {
            if (operation != null)
            {
                operation[dataKey] = dataValue;
            }

            return(operation);
        }
Example #3
0
        /// <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);
            }
        }