示例#1
0
        /// <summary>
        /// Keep track of thread statistics, mainly timing, can be created outside the thread to be tracked.
        /// </summary>
        /// <param name="threadName">Name used for logging the collected stastistics</param>
        /// <param name="storage"></param>
        public ThreadTrackingStatistic(string threadName)
        {
            ExecutingCpuCycleTime   = new TimeIntervalThreadCycleCounterBased();
            ExecutingWallClockTime  = TimeIntervalFactory.CreateTimeInterval(true);
            ProcessingCpuCycleTime  = new TimeIntervalThreadCycleCounterBased();
            ProcessingWallClockTime = TimeIntervalFactory.CreateTimeInterval(true);

            NumRequests = 0;
            firstStart  = true;
            Name        = threadName;

            CounterStorage storage             = StatisticsCollector.ReportDetailedThreadTimeTrackingStats ? CounterStorage.LogOnly : CounterStorage.DontStore;
            CounterStorage aggrCountersStorage = CounterStorage.LogOnly;

            // 4 direct counters
            allExecutingCpuCycleTime.Add(
                FloatValueStatistic.FindOrCreate(new StatisticName(StatisticNames.THREADS_EXECUTION_TIME_TOTAL_CPU_CYCLES, threadName),
                                                 () => (float)ExecutingCpuCycleTime.Elapsed.TotalMilliseconds, storage));

            allExecutingWallClockTime.Add(
                FloatValueStatistic.FindOrCreate(new StatisticName(StatisticNames.THREADS_EXECUTION_TIME_TOTAL_WALL_CLOCK, threadName),
                                                 () => (float)ExecutingWallClockTime.Elapsed.TotalMilliseconds, storage));

            allProcessingCpuCycleTime.Add(
                FloatValueStatistic.FindOrCreate(new StatisticName(StatisticNames.THREADS_PROCESSING_TIME_TOTAL_CPU_CYCLES, threadName),
                                                 () => (float)ProcessingCpuCycleTime.Elapsed.TotalMilliseconds, storage));

            allProcessingWallClockTime.Add(
                FloatValueStatistic.FindOrCreate(new StatisticName(StatisticNames.THREADS_PROCESSING_TIME_TOTAL_WALL_CLOCK, threadName),
                                                 () => (float)ProcessingWallClockTime.Elapsed.TotalMilliseconds, storage));

            // numRequests
            allNumProcessedRequests.Add(
                FloatValueStatistic.FindOrCreate(new StatisticName(StatisticNames.THREADS_PROCESSED_REQUESTS_PER_THREAD, threadName),
                                                 () => (float)NumRequests, storage));

            // aggregate stats
            if (totalExecutingCpuCycleTime == null)
            {
                totalExecutingCpuCycleTime = FloatValueStatistic.FindOrCreate(
                    new StatisticName(StatisticNames.THREADS_EXECUTION_TIME_AVERAGE_CPU_CYCLES, "AllThreads"),
                    () => CalculateTotalAverage(allExecutingCpuCycleTime, totalNumProcessedRequests), aggrCountersStorage);
            }
            if (totalExecutingWallClockTime == null)
            {
                totalExecutingWallClockTime = FloatValueStatistic.FindOrCreate(
                    new StatisticName(StatisticNames.THREADS_EXECUTION_TIME_AVERAGE_WALL_CLOCK, "AllThreads"),
                    () => CalculateTotalAverage(allExecutingWallClockTime, totalNumProcessedRequests), aggrCountersStorage);
            }
            if (totalProcessingCpuCycleTime == null)
            {
                totalProcessingCpuCycleTime = FloatValueStatistic.FindOrCreate(
                    new StatisticName(StatisticNames.THREADS_PROCESSING_TIME_AVERAGE_CPU_CYCLES, "AllThreads"),
                    () => CalculateTotalAverage(allProcessingCpuCycleTime, totalNumProcessedRequests), aggrCountersStorage);
            }
            if (totalProcessingWallClockTime == null)
            {
                totalProcessingWallClockTime = FloatValueStatistic.FindOrCreate(
                    new StatisticName(StatisticNames.THREADS_PROCESSING_TIME_AVERAGE_WALL_CLOCK, "AllThreads"),
                    () => CalculateTotalAverage(allProcessingWallClockTime, totalNumProcessedRequests), aggrCountersStorage);
            }
            if (totalNumProcessedRequests == null)
            {
                totalNumProcessedRequests = FloatValueStatistic.FindOrCreate(
                    new StatisticName(StatisticNames.THREADS_PROCESSED_REQUESTS_PER_THREAD, "AllThreads"),
                    () => (float)allNumProcessedRequests.Select(cs => cs.GetCurrentValue()).Sum(), aggrCountersStorage);
            }

            if (StatisticsCollector.PerformStageAnalysis)
            {
                globalStageAnalyzer.AddTracking(this);
            }
        }
        internal void Start()
        {
            if (!countersAvailable)
            {
                logger.Warn(ErrorCode.PerfCounterNotRegistered,
                            "CPU & Memory perf counters did not initialize correctly - try repairing Windows perf counter config on this machine with 'lodctr /r' command");
            }

            if (cpuCounterPF != null)
            {
                cpuUsageTimer = new SafeTimer(CheckCpuUsage, null, CPU_CHECK_PERIOD, CPU_CHECK_PERIOD);
            }
            try
            {
                if (cpuCounterPF != null)
                {
                    // Read initial value of CPU Usage counter
                    CpuUsage = cpuCounterPF.NextValue();
                }
            }
            catch (InvalidOperationException)
            {
                // Can sometimes get exception accessing CPU Usage counter for first time in some runtime environments
                CpuUsage = 0;
            }

            FloatValueStatistic.FindOrCreate(StatisticNames.RUNTIME_CPUUSAGE, () => CpuUsage);
            IntValueStatistic.FindOrCreate(StatisticNames.RUNTIME_GC_TOTALMEMORYKB, () => (long)((MemoryUsage + KB - 1.0) / KB)); // Round up
#if LOG_MEMORY_PERF_COUNTERS                                                                                                      // print GC stats in the silo log file.
            StringValueStatistic.FindOrCreate(StatisticNames.RUNTIME_GC_GENCOLLECTIONCOUNT, () => GCGenCollectionCount);
            StringValueStatistic.FindOrCreate(StatisticNames.RUNTIME_GC_GENSIZESKB, () => GCGenSizes);
            if (timeInGCPF != null)
            {
                FloatValueStatistic.FindOrCreate(StatisticNames.RUNTIME_GC_PERCENTOFTIMEINGC, () => timeInGCPF.NextValue());
            }
            if (allocatedBytesPerSecPF != null)
            {
                FloatValueStatistic.FindOrCreate(StatisticNames.RUNTIME_GC_ALLOCATEDBYTESINKBPERSEC, () => allocatedBytesPerSecPF.NextValue() / KB);
            }
            if (promotedMemoryFromGen1PF != null)
            {
                FloatValueStatistic.FindOrCreate(StatisticNames.RUNTIME_GC_PROMOTEDMEMORYFROMGEN1KB, () => promotedMemoryFromGen1PF.NextValue() / KB);
            }
            if (largeObjectHeapSizePF != null)
            {
                FloatValueStatistic.FindOrCreate(StatisticNames.RUNTIME_GC_LARGEOBJECTHEAPSIZEKB, () => largeObjectHeapSizePF.NextValue() / KB);
            }
            if (promotedFinalizationMemoryFromGen0PF != null)
            {
                FloatValueStatistic.FindOrCreate(StatisticNames.RUNTIME_GC_PROMOTEDMEMORYFROMGEN0KB, () => promotedFinalizationMemoryFromGen0PF.NextValue() / KB);
            }
            if (numberOfInducedGCsPF != null)
            {
                FloatValueStatistic.FindOrCreate(StatisticNames.RUNTIME_GC_NUMBEROFINDUCEDGCS, () => numberOfInducedGCsPF.NextValue());
            }
            IntValueStatistic.FindOrCreate(StatisticNames.RUNTIME_MEMORY_TOTALPHYSICALMEMORYMB, () => (long)((TotalPhysicalMemory / KB) / KB));
            if (availableMemoryCounterPF != null)
            {
                IntValueStatistic.FindOrCreate(StatisticNames.RUNTIME_MEMORY_AVAILABLEMEMORYMB, () => (long)((AvailableMemory / KB) / KB)); // Round up
            }
#endif
            IntValueStatistic.FindOrCreate(StatisticNames.RUNTIME_DOT_NET_THREADPOOL_INUSE_WORKERTHREADS, () =>
            {
                int maXworkerThreads;
                int maXcompletionPortThreads;
                ThreadPool.GetMaxThreads(out maXworkerThreads, out maXcompletionPortThreads);
                int workerThreads;
                int completionPortThreads;
                // GetAvailableThreads Retrieves the difference between the maximum number of thread pool threads
                // and the number currently active.
                // So max-Available is the actual number in use. If it goes beyond min, it means we are stressing the thread pool.
                ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
                return(maXworkerThreads - workerThreads);
            });
            IntValueStatistic.FindOrCreate(StatisticNames.RUNTIME_DOT_NET_THREADPOOL_INUSE_COMPLETIONPORTTHREADS, () =>
            {
                int maXworkerThreads;
                int maXcompletionPortThreads;
                ThreadPool.GetMaxThreads(out maXworkerThreads, out maXcompletionPortThreads);
                int workerThreads;
                int completionPortThreads;
                ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
                return(maXcompletionPortThreads - completionPortThreads);
            });
        }
示例#3
0
        private float CalculateTotalAverage(List <FloatValueStatistic> allthreasCounters, FloatValueStatistic allNumRequestsCounter)
        {
            float allThreads  = allthreasCounters.Select(cs => cs.GetCurrentValue()).Sum();
            float numRequests = allNumRequestsCounter.GetCurrentValue();

            if (numRequests == 0)
            {
                return(0);
            }
            return(allThreads / numRequests);
        }
 static public void Delete(StatisticName name)
 {
     FloatValueStatistic.Delete(name);
 }