/// <summary> /// Binds processes to performance counters instance names and adds performance counters to the collection. /// </summary> /// <remarks>This operation is expensive, but must be done periodically to account for IIS changing instance names /// of the counters it reports Web Sites on as worker processes start and terminate.</remarks> private void EnsurePerformanceCountersRegistered() { if (DateTime.Now - this.lastRefreshTimestamp < this.registrationPeriod) { // re-registration period hasn't elapsed yet, do nothing return; } PerformanceCounterUtility.InvalidatePlaceholderCache(); if (this.lastRefreshTimestamp == DateTime.MinValue) { // this is the initial registration, register everything this.ProcessCustomCounters(); string error; var errors = new List <string>(); foreach (PerformanceCounterCollectionRequest req in this.DefaultCounters.Union(this.Counters)) { this.collector.RegisterCounter( req.PerformanceCounter, req.ReportAs, true, out error, false); if (!string.IsNullOrWhiteSpace(error)) { errors.Add( string.Format( CultureInfo.InvariantCulture, "Counter {0}: {1}", req.PerformanceCounter, error)); } } if (errors.Any()) { // send out the unified error message PerformanceCollectorEventSource.Log.CounterCheckConfigurationEvent( errors.Count.ToString(CultureInfo.InvariantCulture), string.Join(Environment.NewLine, errors)); } } else { // this is a periodic refresh this.collector.RefreshCounters(); } // as per MSDN, we need to wait at least 1s before proceeding with counter collection Thread.Sleep(TimeSpan.FromSeconds(1)); this.lastRefreshTimestamp = DateTime.Now; }
public void PerformanceCounterUtilityPlaceholderExpansionTest() { PerformanceCounterUtility.InvalidatePlaceholderCache(); var win32Instances = PerformanceCounterUtility.GetWin32ProcessInstances(); var clrInstances = PerformanceCounterUtility.GetClrProcessInstances(); bool usesInstanceNamePlaceholder; var pc = PerformanceCounterUtility.ParsePerformanceCounter(@"\Processor(??APP_WIN32_PROC??)\% Processor Time", win32Instances, clrInstances, out usesInstanceNamePlaceholder); Assert.IsFalse(pc.InstanceName.Contains("?")); pc = PerformanceCounterUtility.ParsePerformanceCounter(@"\Processor(??APP_CLR_PROC??)\% Processor Time", win32Instances, clrInstances, out usesInstanceNamePlaceholder); Assert.IsFalse(pc.InstanceName.Contains("?")); pc = PerformanceCounterUtility.ParsePerformanceCounter(@"\Processor(??APP_W3SVC_PROC??)\% Processor Time", win32Instances, clrInstances, out usesInstanceNamePlaceholder); Assert.IsFalse(pc.InstanceName.Contains("?")); pc = PerformanceCounterUtility.ParsePerformanceCounter(@"\ASP.NET Applications(??APP_W3SVC_PROC??)\Request Execution Time", win32Instances, clrInstances, out usesInstanceNamePlaceholder); Assert.IsFalse(pc.InstanceName.Contains("?")); pc = PerformanceCounterUtility.ParsePerformanceCounter(@"\Processor(??NON_EXISTENT??)\% Processor Time", win32Instances, clrInstances, out usesInstanceNamePlaceholder); Assert.AreEqual("??NON_EXISTENT??", pc.InstanceName); // validate placeholder cache state var cache = new PrivateType(typeof(PerformanceCounterUtility)).GetStaticField( "PlaceholderCache", BindingFlags.NonPublic) as ConcurrentDictionary <string, string>; Assert.AreEqual(3, cache.Count); Assert.IsTrue(cache.ContainsKey("APP_WIN32_PROC")); Assert.IsTrue(cache.ContainsKey("APP_CLR_PROC")); Assert.IsTrue(cache.ContainsKey("APP_W3SVC_PROC")); PerformanceCounterUtility.InvalidatePlaceholderCache(); Assert.IsFalse(cache.Any()); }
/// <summary> /// Binds processes to performance counters instance names and adds performance counters to the collection. /// </summary> /// <remarks>This operation is expensive, but must be done periodically to account for IIS changing instance names /// of the counters it reports Web Sites on as worker processes start and terminate.</remarks> private void EnsurePerformanceCountersRegistered() { if (DateTime.Now - this.lastRefreshTimestamp < this.registrationPeriod) { // re-registration period hasn't elapsed yet, do nothing return; } // get all instances that currently exist in the system var win32Instances = PerformanceCounterUtility.GetWin32ProcessInstances(); var clrInstances = PerformanceCounterUtility.GetClrProcessInstances(); PerformanceCounterUtility.InvalidatePlaceholderCache(); if (this.lastRefreshTimestamp == DateTime.MinValue) { this.ProcessCustomCounters(); string error; var errors = new List <string>(); // this is the initial registration, register everything this.defaultCounters.ForEach(pcName => this.RegisterCounter(pcName, string.Empty, win32Instances, clrInstances, false, out error)); foreach (PerformanceCounterCollectionRequest req in this.Counters) { this.RegisterCounter( req.PerformanceCounter, req.ReportAs, win32Instances, clrInstances, true, out error); if (!string.IsNullOrWhiteSpace(error)) { errors.Add( string.Format( CultureInfo.InvariantCulture, Resources.PerformanceCounterCheckConfigurationEntry, req.PerformanceCounter, error)); } } if (errors.Any()) { // send out the unified error message PerformanceCollectorEventSource.Log.CounterCheckConfigurationEvent( errors.Count.ToString(CultureInfo.InvariantCulture), this.Counters.Count.ToString(CultureInfo.InvariantCulture), string.Join(Environment.NewLine, errors)); } } else { // this is a periodic refresh this.RefreshCounters(win32Instances, clrInstances); } // as per MSDN, we need to wait at least 1s before proceeding with counter collection Thread.Sleep(TimeSpan.FromSeconds(1)); this.lastRefreshTimestamp = DateTime.Now; }