private int CreatePerfCounterProxies(string processInstanceName) { var perfCounterProxies = new Dictionary <GCSampleType, IPerformanceCounterProxy>(); var failedSampleTypes = new List <GCSampleType>(); foreach (var sampleTypeEnum in _perfCounterNames.Keys) { try { perfCounterProxies[sampleTypeEnum] = _pcProxyFactory.CreatePerformanceCounterProxy(GCPerfCounterCategoryName, _perfCounterNames[sampleTypeEnum], processInstanceName); } catch (UnauthorizedAccessException) { throw; //Let the caller receive this so that they may shutdown the sampler. } catch (Exception ex) { failedSampleTypes.Add(sampleTypeEnum); LogMessage(LogLevel.Debug, $"Error encountered during the creation of performance counter for '{sampleTypeEnum}' for Performance Counter Instance '{processInstanceName}'. Metrics of this type will not be captured. Error : {ex}"); } } //Print message indicating which perf counter proxies failed to start. if (failedSampleTypes.Count > 0) { var msgToken = string.Join(", ", failedSampleTypes.Select(x => x.ToString()).ToArray()); LogMessage(LogLevel.Warn, $"The following Performance Counters for Performance Counter Instance '{processInstanceName}' could not be started: {msgToken}. Debug Level logs will contain more information."); } var oldProxies = Interlocked.Exchange(ref _perfCounterProxies, perfCounterProxies); if (_perfCounterProxies.Count > 0) { LogMessage(LogLevel.Debug, $"Sampler is collecting {_perfCounterProxies.Count} performance counter(s) for Performance Counter Instance '{processInstanceName}'."); } if (oldProxies != null && oldProxies.Count > 0) { DisposeProxies(oldProxies.Values); } return(_perfCounterProxies.Count); }
public void SamplerCalculatesValuesCorrectly() { const int expectedSampleCount = 2; const float startVal = 3f; const float deltaVal = 10f; var lastPerfCounterValue = 0f; var testPerfCounterValue = startVal; //Create a mock proxy that allows us to return a specific value and ensure that the proxy factory returns this proxy. var mockProxy = Mock.Create <IPerformanceCounterProxy>(); Mock.Arrange(() => mockProxy.NextValue()) .Returns(() => { return(testPerfCounterValue); }); Mock.Arrange(() => _perfCounterProxyFactory.CreatePerformanceCounterProxy(Arg.IsAny <string>(), Arg.IsAny <string>(), Arg.IsAny <string>())) .Returns(mockProxy); Mock.Arrange(() => _perfCounterProxyFactory.GetCurrentProcessInstanceNameForCategory(Arg.IsAny <string>(), Arg.IsAny <string>())) .Returns("Test Value"); //Holds the results of the perf counter captures so that we may compare them as part of our assertions. List <Dictionary <GCSampleType, float> > perfCounterValues = new List <Dictionary <GCSampleType, float> >(); //Intercept the transform method so that we can collect the values that were sampled from the performance counters var gcSampleTransformer = Mock.Create <IGcSampleTransformer>(); Mock.Arrange(() => gcSampleTransformer.Transform(Arg.IsAny <Dictionary <GCSampleType, float> >())) .DoInstead <Dictionary <GCSampleType, float> >((sampleValues) => { lastPerfCounterValue = testPerfCounterValue; perfCounterValues.Add(sampleValues); testPerfCounterValue += deltaVal; }); var sampler = new GcSampler(_scheduler, gcSampleTransformer, _perfCounterProxyFactory); //Act sampler.Start(); _sampleAction(); //Collect Sample 1 _sampleAction(); //Collect Sample 2 //Assert NrAssert.Multiple( () => Assert.AreEqual(expectedSampleCount, perfCounterValues.Count, $"There should have been {expectedSampleCount} samples collected"), () => Assert.AreEqual(_countSampleTypes, perfCounterValues[0].Count, $"There should be {_countSampleTypes} in the first sample"), () => Assert.AreEqual(_countSampleTypes, perfCounterValues[1].Count, $"There should be {_countSampleTypes} in the second sample") ); //Validate the sampled(calculated) value for each counter type. foreach (var gcSampleType in perfCounterValues[0].Keys) { //For the first sample, all should have the same value Assert.AreEqual(startVal, perfCounterValues[0][gcSampleType]); //For the second sample... switch (gcSampleType) { //...delta values should represent the size of the delta case GCSampleType.Gen0CollectionCount: case GCSampleType.Gen1CollectionCount: case GCSampleType.Gen2CollectionCount: case GCSampleType.InducedCount: Assert.AreEqual(deltaVal, perfCounterValues[1][gcSampleType]); break; //...other measurements should be passed through with the perf counter value default: Assert.AreEqual(lastPerfCounterValue, perfCounterValues[1][gcSampleType]); break; } } }