Ejemplo n.º 1
0
 /// <summary>
 /// Constructs a CallContextServiceProfiler.
 /// </summary>
 /// <param name="distributor">A <see cref="ScopeOnSystemSwitchedDistributor"/> to hook into to receive system change events.</param>
 /// <param name="scopeName">The name of the call contxt being tracked.</param>
 /// <param name="systemGroupTransform">A <see cref="Regex"/> string to transform the procesor into a system group.</param>
 /// <param name="startSystem">The optional starting system.</param>
 public CallContextServiceProfiler(ScopeOnSystemSwitchedDistributor distributor, string scopeName, Regex?systemGroupTransform, string startSystem = "")
 {
     _distributor                     = distributor;
     _systemGroupTransform            = systemGroupTransform;
     _scopeName                       = scopeName;
     _stopwatchTicksUsedByGroup       = new Dictionary <string, (long, long)>();
     _currentGroup                    = ProcessOrSingleTimeWindowServiceProfiler.GroupSystem(_systemGroupTransform, startSystem);
     _currentGroupStartStopwatchTicks = AmbientClock.Ticks;
     distributor.RegisterSystemSwitchedNotificationSink(this);
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates a service profiler which profiles the entire process for the entire (remaining) duration of execution.
        /// Note that this is only useful to determine the distribution for an entire process from start to finish, which is not very useful if the process is very long-lived.
        /// <see cref="CreateTimeWindowProfiler"/> is a better match in most situations.
        /// </summary>
        /// <param name="scopeName">A name for the contxt to attach to the analyzer.</param>
        /// <param name="overrideSystemGroupTransformRegex">A <see cref="Regex"/> string to transform the procesor into a processor group.</param>
        /// <returns>A <see cref="IAmbientServiceProfile"/> containing a service profile for the entire process.  Note that the returned object is NOT thread-safe.</returns>
        /// <remarks>
        /// This is different from using <see cref="CreateCallContextProfiler"/> because that will only analyze the call context it's called from,
        /// whereas this will analyze all threads and call contexts in the process.
        /// They will produce the same results only for programs where there is only a single call context (no parallelization)
        /// </remarks>
        public IAmbientServiceProfile?CreateProcessProfiler(string scopeName, string?overrideSystemGroupTransformRegex = null)
        {
            IAmbientServiceProfiler?metrics = _AmbientServiceProfiler.Local;

            if (metrics != null)
            {
                Regex?groupTransform = (overrideSystemGroupTransformRegex == null) ? _defaultSystemGroupTransformSetting.Value : new Regex(overrideSystemGroupTransformRegex, RegexOptions.Compiled);
                ProcessOrSingleTimeWindowServiceProfiler tracker = new ProcessOrSingleTimeWindowServiceProfiler(metrics, scopeName, groupTransform);
                return(tracker);
            }
            return(null);
        }
Ejemplo n.º 3
0
        private ProcessOrSingleTimeWindowServiceProfiler?Rotate(IAmbientServiceProfiler metrics, TimeSpan windowPeriod, Regex?systemGroupTransform)
        {
            string windowName = WindowScope.WindowId(AmbientClock.UtcNow, windowPeriod);
            string newAccumulatorScopeName = _scopeNamePrefix + windowName + "(" + WindowScope.WindowSize(windowPeriod) + ")";;
            ProcessOrSingleTimeWindowServiceProfiler newAccumulator = new ProcessOrSingleTimeWindowServiceProfiler(metrics, newAccumulatorScopeName, systemGroupTransform);
            ProcessOrSingleTimeWindowServiceProfiler?oldAccumulator = System.Threading.Interlocked.Exchange(ref _timeWindowCallContextCollector, newAccumulator);

            if (oldAccumulator != null)
            {
                // close out the old accumulator
                oldAccumulator.CloseSampling();
            }
            return(oldAccumulator);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Notifies the notification sink that the system has switched.
        /// </summary>
        /// <remarks>
        /// This function will be called whenever the service profiler is told that the currently-processing system has switched.
        /// Note that the previously-executing system may or may not be revised at this time.
        /// Such revisions can be used to distinguish between processing that resulted in success or failure, or other similar outcomes that the notifier wishes to distinguish.
        /// </remarks>
        /// <param name="newSystemStartStopwatchTimestamp">The stopwatch timestamp when the new system started.</param>
        /// <param name="newSystem">The identifier for the system that is starting to run.</param>
        /// <param name="oldSystemStartStopwatchTimestamp">The stopwatch timestamp when the old system started running.</param>
        /// <param name="revisedOldSystem">The (possibly-revised) name for the system that has just finished running, or null if the identifier for the old system does not need revising.</param>
        public void OnSystemSwitched(long newSystemStartStopwatchTimestamp, string newSystem, long oldSystemStartStopwatchTimestamp, string?revisedOldSystem = null)
        {
            string?justEndedGroup = (revisedOldSystem == null)
                ? _currentGroup
                : ProcessOrSingleTimeWindowServiceProfiler.GroupSystem(_systemGroupTransform, revisedOldSystem);
            // update the just ended group
            ValueTuple <long, long> values;

            if (!_stopwatchTicksUsedByGroup.TryGetValue(justEndedGroup, out values))
            {
                _stopwatchTicksUsedByGroup.Add(justEndedGroup, (newSystemStartStopwatchTimestamp - oldSystemStartStopwatchTimestamp, 1));
            }
            else
            {
                _stopwatchTicksUsedByGroup[justEndedGroup] = (values.Item1 + newSystemStartStopwatchTimestamp - oldSystemStartStopwatchTimestamp, values.Item2 + 1);
            }
            string?newGroup = ProcessOrSingleTimeWindowServiceProfiler.GroupSystem(_systemGroupTransform, newSystem);

            // switch to the new processor
            _currentGroup = newGroup;
            _currentGroupStartStopwatchTicks = newSystemStartStopwatchTimestamp;
        }