public void RegisterMetrics(MetricFactory metrics) { if (!_threadPoolInfo.Enabled && !_runtimeCounters.Enabled) { return; } NumThreads = metrics.CreateGauge("dotnet_threadpool_num_threads", "The number of active threads in the thread pool"); _runtimeCounters.Events.ThreadPoolThreadCount += e => NumThreads.Set(e.Mean); Throughput = metrics.CreateCounter("dotnet_threadpool_throughput_total", "The total number of work items that have finished execution in the thread pool"); _runtimeCounters.Events.ThreadPoolCompletedItemsCount += e => Throughput.Inc(e.IncrementedBy); QueueLength = metrics.CreateHistogram("dotnet_threadpool_queue_length", "Measures the queue length of the thread pool. Values greater than 0 indicate a backlog of work for the threadpool to process.", new HistogramConfiguration { Buckets = _options.QueueLengthHistogramBuckets } ); _runtimeCounters.Events.ThreadPoolQueueLength += e => QueueLength.Observe(e.Mean); NumTimers = metrics.CreateGauge("dotnet_threadpool_timer_count", "The number of timers active"); _runtimeCounters.Events.ActiveTimerCount += e => NumTimers.Set(e.Mean); if (_threadPoolInfo.Enabled) { AdjustmentsTotal = metrics.CreateCounter( "dotnet_threadpool_adjustments_total", "The total number of changes made to the size of the thread pool, labeled by the reason for change", "adjustment_reason"); _threadPoolInfo.Events.ThreadPoolAdjusted += e => { AdjustmentsTotal.Labels(_adjustmentReasonToLabel[e.AdjustmentReason]).Inc(); }; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // IO threadpool only exists on windows NumIocThreads = metrics.CreateGauge("dotnet_threadpool_io_num_threads", "The number of active threads in the IO thread pool"); _threadPoolInfo.Events.IoThreadPoolAdjusted += e => NumIocThreads.Set(e.NumThreads); } } }