diff --git a/Src/Microsoft.ApplicationInsights.Web.sln b/Src/Microsoft.ApplicationInsights.Web.sln index 43551714b..cda67e6ea 100644 --- a/Src/Microsoft.ApplicationInsights.Web.sln +++ b/Src/Microsoft.ApplicationInsights.Web.sln @@ -82,17 +82,17 @@ Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Perf.Shared.NetStandard", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Perf", "PerformanceCollector\PerformanceCollector\Perf.csproj", "{00BF736C-B562-4251-9836-EF80282956AF}" EndProject -Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Perf.Shared.NetStandard20", "PerformanceCollector\Perf.Shared.NetStandard20\Perf.Shared.NetStandard20.shproj", "{054C25DC-E545-4712-95C4-81F30CF65CE8}" -EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Perf.Shared.NetStandard.Stubs", "PerformanceCollector\Perf.Shared.NetStandard.Stubs\Perf.Shared.NetStandard.Stubs.shproj", "{30A45441-0849-48FE-AD37-5D29D0E3068A}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Perf-NetCore20.Tests", "PerformanceCollector\NetCore20.Tests\Perf-NetCore20.Tests\Perf-NetCore20.Tests.csproj", "{AC7D8533-C823-4E93-B008-51B3C4744E2E}" EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Perf.Shared.NetStandard20Net45", "PerformanceCollector\Perf.Shared.NetStandard20Net45\Perf.Shared.NetStandard20Net45.shproj", "{054C25DC-E545-4712-95C4-81F30CF65CE8}" +EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Perf.Shared.NetStandard20", "PerformanceCollector\Perf.Shared.NetStandard20\Perf.Shared.NetStandard20.shproj", "{A8BA3BD0-19CE-488D-B2BD-0B9B677F4E03}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution - PerformanceCollector\Perf.Shared.NetStandard20\Perf.Shared.NetStandard20.projitems*{054c25dc-e545-4712-95c4-81f30cf65ce8}*SharedItemsImports = 13 - DependencyCollector\Shared.Tests\DependencyCollector.Shared.Tests.projitems*{257fce5a-0779-45a5-b541-0ce43d79d009}*SharedItemsImports = 4 - TestFramework\Shared\TestFramework.Shared.projitems*{257fce5a-0779-45a5-b541-0ce43d79d009}*SharedItemsImports = 4 + PerformanceCollector\Perf.Shared.NetStandard20Net45\Perf.Shared.NetStandard20Net45.projitems*{054c25dc-e545-4712-95c4-81f30cf65ce8}*SharedItemsImports = 13 PerformanceCollector\Perf.Shared.NetStandard.Stubs\Perf.Shared.NetStandard.Stubs.projitems*{30a45441-0849-48fe-ad37-5d29d0e3068a}*SharedItemsImports = 13 Web\Web.Shared.Net\Web.Shared.Net.projitems*{395e03bb-d061-4c9d-9d47-18676566444d}*SharedItemsImports = 13 PerformanceCollector\Filtering.Shared\Filtering.Shared.projitems*{568aeb4f-ba4c-47a5-9fa3-68f06cd11fed}*SharedItemsImports = 13 @@ -104,6 +104,7 @@ Global TestFramework\Shared\TestFramework.Shared.projitems*{9718f051-147f-4f5f-9ff3-c926430efcf7}*SharedItemsImports = 13 PerformanceCollector\Perf.Shared.Tests\Perf.Shared.Tests.projitems*{9b524bd3-682d-4b6f-9251-d4b2911df0fd}*SharedItemsImports = 13 PerformanceCollector\Perf.Shared\Perf.Shared.projitems*{a78f50d4-f518-4dcb-878b-526fd54cca35}*SharedItemsImports = 13 + PerformanceCollector\Perf.Shared.NetStandard20\Perf.Shared.NetStandard20.projitems*{a8ba3bd0-19ce-488d-b2bd-0b9b677f4e03}*SharedItemsImports = 13 Web\Web.Shared.Net.Tests\Web.Shared.Net.Tests.projitems*{ac2e85bb-05f7-43cb-b966-3611ccf47156}*SharedItemsImports = 13 DependencyCollector\Shared.Tests\DependencyCollector.Shared.Tests.projitems*{ace58393-3419-4fca-87cc-c33eb756c7e4}*SharedItemsImports = 13 Common\Common.projitems*{ccab7a34-8dc5-4a6f-b637-46ceba93c687}*SharedItemsImports = 13 @@ -274,9 +275,10 @@ Global {76B21FAA-270D-47DE-B14B-BEC87EDC34F1} = {A318CC6C-51C8-4BD6-BC85-2B4F35123BE7} {D13C3EC7-B300-4158-9054-216156B203BE} = {A318CC6C-51C8-4BD6-BC85-2B4F35123BE7} {00BF736C-B562-4251-9836-EF80282956AF} = {A318CC6C-51C8-4BD6-BC85-2B4F35123BE7} - {054C25DC-E545-4712-95C4-81F30CF65CE8} = {A318CC6C-51C8-4BD6-BC85-2B4F35123BE7} {30A45441-0849-48FE-AD37-5D29D0E3068A} = {A318CC6C-51C8-4BD6-BC85-2B4F35123BE7} {AC7D8533-C823-4E93-B008-51B3C4744E2E} = {A318CC6C-51C8-4BD6-BC85-2B4F35123BE7} + {054C25DC-E545-4712-95C4-81F30CF65CE8} = {A318CC6C-51C8-4BD6-BC85-2B4F35123BE7} + {A8BA3BD0-19CE-488D-B2BD-0B9B677F4E03} = {A318CC6C-51C8-4BD6-BC85-2B4F35123BE7} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {F99E0A07-C363-49BF-BFA7-C748391CE38E} diff --git a/Src/PerformanceCollector/NetCore.Tests/Perf.NetCore.Tests.csproj b/Src/PerformanceCollector/NetCore.Tests/Perf.NetCore.Tests.csproj index 32339af41..6c4712d1c 100644 --- a/Src/PerformanceCollector/NetCore.Tests/Perf.NetCore.Tests.csproj +++ b/Src/PerformanceCollector/NetCore.Tests/Perf.NetCore.Tests.csproj @@ -26,8 +26,7 @@ - - + diff --git a/Src/PerformanceCollector/NetCore20.Tests/Perf-NetCore20.Tests/Perf-NetCore20.Tests.csproj b/Src/PerformanceCollector/NetCore20.Tests/Perf-NetCore20.Tests/Perf-NetCore20.Tests.csproj index 4fec4c20e..84de3fe16 100644 --- a/Src/PerformanceCollector/NetCore20.Tests/Perf-NetCore20.Tests/Perf-NetCore20.Tests.csproj +++ b/Src/PerformanceCollector/NetCore20.Tests/Perf-NetCore20.Tests/Perf-NetCore20.Tests.csproj @@ -24,8 +24,7 @@ - - + diff --git a/Src/PerformanceCollector/NetCore20.Tests/Perf-NetCore20.Tests/PerformanceCollectorXPlatformTestBase.cs b/Src/PerformanceCollector/NetCore20.Tests/Perf-NetCore20.Tests/PerformanceCollectorXPlatformTestBase.cs new file mode 100644 index 000000000..ef6703e0e --- /dev/null +++ b/Src/PerformanceCollector/NetCore20.Tests/Perf-NetCore20.Tests/PerformanceCollectorXPlatformTestBase.cs @@ -0,0 +1,84 @@ +namespace Microsoft.ApplicationInsights.Tests +{ + using System; + using System.Diagnostics; + using System.Globalization; + using System.Linq; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.XPlatform; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + /// + /// PerformanceCollector test base. + /// + public class PerformanceCollectorXPlatformTestBase + { + internal void PerformanceCollectorSanityTest(IPerformanceCollector collector, string counter, string categoryName, string counterName, string instanceName) + { + const int CounterCount = 3; + + for (int i = 0; i < CounterCount; i++) + { + string error; + collector.RegisterCounter( + counter, + null, + out error, + false); + } + + var results = collector.Collect().ToList(); + + Assert.AreEqual(CounterCount, results.Count); + + foreach (var result in results) + { + var value = result.Item2; + + Assert.AreEqual(categoryName, result.Item1.PerformanceCounter.CategoryName); + Assert.AreEqual(counterName, result.Item1.PerformanceCounter.CounterName); + + if (instanceName != null) + { + Assert.AreEqual(instanceName, result.Item1.PerformanceCounter.InstanceName); + } + + Assert.IsTrue(value >= 0 && value <= 100, "actual value:" + value + ". Should be 0-100"); + } + } + + internal void PerformanceCollectorAddRemoveCountersForXPlatformTest(PerformanceCollectorXPlatform collector) + { + var counterRequests = new[] + { + new PerformanceCounterCollectionRequest(@"\Process(??APP_WIN32_PROC??)\Private Bytes", @"\Process(??APP_WIN32_PROC??)\Private Bytes"), + new PerformanceCounterCollectionRequest(@"\Process(??APP_WIN32_PROC??)\% Processor Time", @"\Process(??APP_WIN32_PROC??)\% Processor Time") + }; + + foreach (var counterRequest in counterRequests) + { + string error; + collector.RegisterCounter( + counterRequest.PerformanceCounter, + counterRequest.ReportAs, + out error, + false); + } + + var twoCounters = collector.PerformanceCounters.ToArray(); + + collector.RemoveCounter( + @"\Process(??APP_WIN32_PROC??)\Private Bytes", + counterRequests[0].ReportAs); + + var oneCounter = collector.PerformanceCounters.ToArray(); + + Assert.AreEqual(2, twoCounters.Count()); + Assert.AreEqual(@"\Process(??APP_WIN32_PROC??)\Private Bytes", twoCounters[0].OriginalString); + Assert.AreEqual(@"\Process(??APP_WIN32_PROC??)\% Processor Time", twoCounters[1].OriginalString); + + Assert.AreEqual(@"\Process(??APP_WIN32_PROC??)\% Processor Time", oneCounter.Single().OriginalString); + } + } +} \ No newline at end of file diff --git a/Src/PerformanceCollector/NetCore20.Tests/Perf-NetCore20.Tests/PerformanceCollectorXPlatformTests.cs b/Src/PerformanceCollector/NetCore20.Tests/Perf-NetCore20.Tests/PerformanceCollectorXPlatformTests.cs new file mode 100644 index 000000000..8579e4259 --- /dev/null +++ b/Src/PerformanceCollector/NetCore20.Tests/Perf-NetCore20.Tests/PerformanceCollectorXPlatformTests.cs @@ -0,0 +1,25 @@ +namespace Microsoft.ApplicationInsights.Tests +{ + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.XPlatform; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + /// + /// WebAppPerformanceCollector tests. + /// + [TestClass] + public class PerformanceCollectorXPlatformTests : PerformanceCollectorXPlatformTestBase + { + [TestMethod] + public void PerformanceCollectorSanityTest() + { + this.PerformanceCollectorSanityTest(new PerformanceCollectorXPlatform(), @"\Process(??APP_WIN32_PROC??)\% Processor Time Normalized", "Process", @"% Processor Time Normalized", null); + } + + [TestMethod] + public void PerformanceCollectorAddRemoveCountersForXPlatformTest() + { + this.PerformanceCollectorAddRemoveCountersForXPlatformTest(new PerformanceCollectorXPlatform()); + } + } +} \ No newline at end of file diff --git a/Src/PerformanceCollector/Perf.NetFull.Tests/Perf.NetFull.Tests.csproj b/Src/PerformanceCollector/Perf.NetFull.Tests/Perf.NetFull.Tests.csproj index ecee541a0..ad5059932 100644 --- a/Src/PerformanceCollector/Perf.NetFull.Tests/Perf.NetFull.Tests.csproj +++ b/Src/PerformanceCollector/Perf.NetFull.Tests/Perf.NetFull.Tests.csproj @@ -1,4 +1,4 @@ - + @@ -24,14 +24,14 @@ true full false - DEBUG;TRACE + DEBUG;TRACE;NET45 prompt 4 pdbonly true - TRACE + TRACE;NET45 prompt 4 true @@ -72,10 +72,6 @@ - - - - {00bf736c-b562-4251-9836-ef80282956af} @@ -87,4 +83,4 @@ - + \ No newline at end of file diff --git a/Src/PerformanceCollector/Perf.NetFull.Tests/PerformanceCollectorTestBase.cs b/Src/PerformanceCollector/Perf.NetFull.Tests/PerformanceCollectorTestBase.cs index d4d39b9f9..7249ef16e 100644 --- a/Src/PerformanceCollector/Perf.NetFull.Tests/PerformanceCollectorTestBase.cs +++ b/Src/PerformanceCollector/Perf.NetFull.Tests/PerformanceCollectorTestBase.cs @@ -5,8 +5,8 @@ using System.Globalization; using System.Linq; using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation; - using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.StandardPerformanceCollector; - using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.StandardPerfCollector; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector; using Microsoft.VisualStudio.TestTools.UnitTesting; /// @@ -24,7 +24,6 @@ internal void PerformanceCollectorSanityTest(IPerformanceCollector collector, st collector.RegisterCounter( counter, null, - true, out error, false); } @@ -66,7 +65,6 @@ internal void PerformanceCollectorRefreshCountersTest(IPerformanceCollector coll collector.RegisterCounter( PerformanceCounterUtility.FormatPerformanceCounter(pc), null, - true, out error, false); } @@ -98,7 +96,6 @@ internal void PerformanceCollectorBadStateTest(IPerformanceCollector collector) collector.RegisterCounter( PerformanceCounterUtility.FormatPerformanceCounter(pc), null, - true, out error, false); } @@ -125,7 +122,6 @@ internal void PerformanceCollectorAddRemoveCountersTest(StandardPerformanceColle collector.RegisterCounter( PerformanceCounterUtility.FormatPerformanceCounter(pc), pc.GetHashCode().ToString(CultureInfo.InvariantCulture), - true, out error, false); } @@ -157,7 +153,6 @@ internal void PerformanceCollectorAddRemoveCountersForWebAppTest(WebAppPerforman collector.RegisterCounter( PerformanceCounterUtility.FormatPerformanceCounter(pc), pc.GetHashCode().ToString(CultureInfo.InvariantCulture), - true, out error, false); } @@ -183,14 +178,12 @@ internal void PerformanceCollectorNormalizedCpuTest(IPerformanceCollector collec collector.RegisterCounter( @"\Process(??APP_WIN32_PROC??)\% Processor Time Normalized", null, - true, out error, false); collector.RegisterCounter( @"\Process(??APP_WIN32_PROC??)\% Processor Time", null, - true, out error, false); diff --git a/Src/PerformanceCollector/Perf.NetFull.Tests/PerformanceCounterUtilityTests.cs b/Src/PerformanceCollector/Perf.NetFull.Tests/PerformanceCounterUtilityTests.cs index fedb16753..2447eebba 100644 --- a/Src/PerformanceCollector/Perf.NetFull.Tests/PerformanceCounterUtilityTests.cs +++ b/Src/PerformanceCollector/Perf.NetFull.Tests/PerformanceCounterUtilityTests.cs @@ -32,19 +32,19 @@ public void PerformanceCounterUtilityPlaceholderExpansionTest() var clrInstances = PerformanceCounterUtility.GetClrProcessInstances(); bool usesInstanceNamePlaceholder; - var pc = PerformanceCounterUtility.ParsePerformanceCounter(@"\Processor(??APP_WIN32_PROC??)\% Processor Time", win32Instances, clrInstances, out usesInstanceNamePlaceholder); + var pc = PerformanceCounterUtility.ParsePerformanceCounter(@"\Processor(??APP_WIN32_PROC??)\% Processor Time", win32Instances, clrInstances, true, out usesInstanceNamePlaceholder); Assert.IsFalse(pc.InstanceName.Contains("?")); - pc = PerformanceCounterUtility.ParsePerformanceCounter(@"\Processor(??APP_CLR_PROC??)\% Processor Time", win32Instances, clrInstances, out usesInstanceNamePlaceholder); + pc = PerformanceCounterUtility.ParsePerformanceCounter(@"\Processor(??APP_CLR_PROC??)\% Processor Time", win32Instances, clrInstances, true, out usesInstanceNamePlaceholder); Assert.IsFalse(pc.InstanceName.Contains("?")); - pc = PerformanceCounterUtility.ParsePerformanceCounter(@"\Processor(??APP_W3SVC_PROC??)\% Processor Time", win32Instances, clrInstances, out usesInstanceNamePlaceholder); + pc = PerformanceCounterUtility.ParsePerformanceCounter(@"\Processor(??APP_W3SVC_PROC??)\% Processor Time", win32Instances, clrInstances, true, out usesInstanceNamePlaceholder); Assert.IsFalse(pc.InstanceName.Contains("?")); - pc = PerformanceCounterUtility.ParsePerformanceCounter(@"\ASP.NET Applications(??APP_W3SVC_PROC??)\Request Execution Time", win32Instances, clrInstances, out usesInstanceNamePlaceholder); + pc = PerformanceCounterUtility.ParsePerformanceCounter(@"\ASP.NET Applications(??APP_W3SVC_PROC??)\Request Execution Time", win32Instances, clrInstances, true, out usesInstanceNamePlaceholder); Assert.IsFalse(pc.InstanceName.Contains("?")); - pc = PerformanceCounterUtility.ParsePerformanceCounter(@"\Processor(??NON_EXISTENT??)\% Processor Time", win32Instances, clrInstances, out usesInstanceNamePlaceholder); + pc = PerformanceCounterUtility.ParsePerformanceCounter(@"\Processor(??NON_EXISTENT??)\% Processor Time", win32Instances, clrInstances, true, out usesInstanceNamePlaceholder); Assert.AreEqual("??NON_EXISTENT??", pc.InstanceName); // validate placeholder cache state @@ -88,12 +88,12 @@ public void ParsePerformanceCounterTest() PerformanceCounterStructure pc; bool usesInstanceNamePlaceholder; - pc = PerformanceCounterUtility.ParsePerformanceCounter(@"\Processor(_Total)\% Processor Time", null, null, out usesInstanceNamePlaceholder); + pc = PerformanceCounterUtility.ParsePerformanceCounter(@"\Processor(_Total)\% Processor Time", null, null, true, out usesInstanceNamePlaceholder); Assert.AreEqual("Processor", pc.CategoryName); Assert.AreEqual("% Processor Time", pc.CounterName); Assert.AreEqual("_Total", pc.InstanceName); - pc = PerformanceCounterUtility.ParsePerformanceCounter(@"\Memory\Available Memory", null, null, out usesInstanceNamePlaceholder); + pc = PerformanceCounterUtility.ParsePerformanceCounter(@"\Memory\Available Memory", null, null, true, out usesInstanceNamePlaceholder); Assert.AreEqual("Memory", pc.CategoryName); Assert.AreEqual("Available Memory", pc.CounterName); Assert.AreEqual(string.Empty, pc.InstanceName); diff --git a/Src/PerformanceCollector/Perf.NetFull.Tests/StandardPerformanceCollectorTests.cs b/Src/PerformanceCollector/Perf.NetFull.Tests/StandardPerformanceCollectorTests.cs index d779f7a81..4f732ff84 100644 --- a/Src/PerformanceCollector/Perf.NetFull.Tests/StandardPerformanceCollectorTests.cs +++ b/Src/PerformanceCollector/Perf.NetFull.Tests/StandardPerformanceCollectorTests.cs @@ -1,6 +1,6 @@ namespace Microsoft.ApplicationInsights.Tests { - using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.StandardPerformanceCollector; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.StandardPerfCollector; using Microsoft.VisualStudio.TestTools.UnitTesting; /// diff --git a/Src/PerformanceCollector/Perf.NetFull.Tests/packages.config b/Src/PerformanceCollector/Perf.NetFull.Tests/packages.config index 59a9406f8..2979b0526 100644 --- a/Src/PerformanceCollector/Perf.NetFull.Tests/packages.config +++ b/Src/PerformanceCollector/Perf.NetFull.Tests/packages.config @@ -1,7 +1,6 @@ - + - - + \ No newline at end of file diff --git a/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs b/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs index 09fd8e43d..02a1784ad 100644 --- a/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs +++ b/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs @@ -48,10 +48,6 @@ internal sealed class QuickPulseServiceClient : IQuickPulseServiceClient private readonly HttpClient httpClient = new HttpClient(); -#if NETSTANDARD2_0 - private static bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); -#endif - public QuickPulseServiceClient( Uri serviceUri, string instanceName, @@ -226,24 +222,6 @@ private static double Round(double value) return Math.Round(value, 4, MidpointRounding.AwayFromZero); } - private bool IsPerfCounterSupported() - { - bool perfCollectionSupported = false; -#if NETSTANDARD2_0 - if (isWindows) - { - perfCollectionSupported = true; - } - else - { - perfCollectionSupported = this.isWebApp; - } -#else - perfCollectionSupported = this.isWebApp; -#endif - return perfCollectionSupported; - } - private void WritePingData(DateTimeOffset timestamp, Stream stream) { var dataPoint = new MonitoringDataPoint @@ -256,7 +234,7 @@ private void WritePingData(DateTimeOffset timestamp, Stream stream) MachineName = this.machineName, Timestamp = timestamp.UtcDateTime, IsWebApp = this.isWebApp, - PerformanceCollectionSupported = IsPerfCounterSupported(), + PerformanceCollectionSupported = PerformanceCounterUtility.IsPerfCounterSupported(), ProcessorCount = this.processorCount, }; @@ -294,7 +272,7 @@ private void WriteSamples(IEnumerable samples, string inst MachineName = this.machineName, Timestamp = sample.EndTimestamp.UtcDateTime, IsWebApp = this.isWebApp, - PerformanceCollectionSupported = IsPerfCounterSupported(), + PerformanceCollectionSupported = PerformanceCounterUtility.IsPerfCounterSupported(), ProcessorCount = this.processorCount, Metrics = metricPoints.ToArray(), Documents = documents, diff --git a/Src/PerformanceCollector/Perf.Shared.NetStandard16.Stubs/Implementation/StandardPerformanceCollector/StandardPerformanceCollector.cs b/Src/PerformanceCollector/Perf.Shared.NetStandard16.Stubs/Implementation/StandardPerformanceCollector/StandardPerformanceCollector.cs index 18d8df0ae..a6fd30f5a 100644 --- a/Src/PerformanceCollector/Perf.Shared.NetStandard16.Stubs/Implementation/StandardPerformanceCollector/StandardPerformanceCollector.cs +++ b/Src/PerformanceCollector/Perf.Shared.NetStandard16.Stubs/Implementation/StandardPerformanceCollector/StandardPerformanceCollector.cs @@ -1,9 +1,9 @@ -namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.StandardPerformanceCollector +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.StandardPerfCollector { using System; using System.Collections.Generic; - internal class StandardPerformanceCollector : IPerformanceCollector + internal class StandardPerformanceCollectorStub : IPerformanceCollector { private static readonly Tuple[] emptyCollectResult = Array.Empty>(); @@ -13,9 +13,9 @@ internal class StandardPerformanceCollector : IPerformanceCollector public IEnumerable PerformanceCounters { get; } = Array.Empty(); /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - public StandardPerformanceCollector() + public StandardPerformanceCollectorStub() { PerformanceCollectorEventSource.Log.PerfCounterNetCoreOnlyOnAzureWebApp(); } @@ -26,7 +26,7 @@ public StandardPerformanceCollector() /// Invoked when an individual counter fails to be read. public IEnumerable> Collect(Action onReadingFailure = null) { - return StandardPerformanceCollector.emptyCollectResult; + return StandardPerformanceCollectorStub.emptyCollectResult; } /// @@ -41,13 +41,11 @@ public void RefreshCounters() /// /// Name of the performance counter. /// Report as name for the performance counter. - /// Boolean to check if the performance counter is custom defined. /// Captures the error logged. /// Boolean that controls the registry of the counter based on the availability of instance place holder. public void RegisterCounter( string perfCounterName, string reportAs, - bool isCustomCounter, out string error, bool blockCounterWithInstancePlaceHolder = false) { diff --git a/Src/PerformanceCollector/Perf.Shared.NetStandard20/CounterFactoryXPlatform.cs b/Src/PerformanceCollector/Perf.Shared.NetStandard20/CounterFactoryXPlatform.cs new file mode 100644 index 000000000..8017339b8 --- /dev/null +++ b/Src/PerformanceCollector/Perf.Shared.NetStandard20/CounterFactoryXPlatform.cs @@ -0,0 +1,30 @@ +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.XPlatform +{ + using System; + + /// + /// Factory to create different counters. + /// + internal static class CounterFactoryXPlatform + { + /// + /// Gets a counter. + /// + /// Counter name. + /// The counter identified by counter name. + internal static ICounterValue GetCounter(string counterName) + { + switch (counterName) + { + case @"\Process(??APP_WIN32_PROC??)\% Processor Time Normalized": + return new XPlatProcessCPUPerformanceCounterNormalized(); + case @"\Process(??APP_WIN32_PROC??)\% Processor Time": + return new XPlatProcessCPUPerformanceCounter(); + case @"\Process(??APP_WIN32_PROC??)\Private Bytes": + return new XPlatProcessMemoryPerformanceCounter(); + default: + throw new ArgumentException("Performance counter not supported in XPlatform.", counterName); + } + } + } +} \ No newline at end of file diff --git a/Src/PerformanceCollector/Perf.Shared.NetStandard20/Perf.Shared.NetStandard20.projitems b/Src/PerformanceCollector/Perf.Shared.NetStandard20/Perf.Shared.NetStandard20.projitems index 6cc8c0026..5ee4b0520 100644 --- a/Src/PerformanceCollector/Perf.Shared.NetStandard20/Perf.Shared.NetStandard20.projitems +++ b/Src/PerformanceCollector/Perf.Shared.NetStandard20/Perf.Shared.NetStandard20.projitems @@ -3,16 +3,16 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) true - 054c25dc-e545-4712-95c4-81f30cf65ce8 + a8ba3bd0-19ce-488d-b2bd-0b9b677f4e03 Perf.Shared.NetStandard20 - - - - - + + + + + \ No newline at end of file diff --git a/Src/PerformanceCollector/Perf.Shared.NetStandard20/Perf.Shared.NetStandard20.shproj b/Src/PerformanceCollector/Perf.Shared.NetStandard20/Perf.Shared.NetStandard20.shproj index 468c97577..506a57598 100644 --- a/Src/PerformanceCollector/Perf.Shared.NetStandard20/Perf.Shared.NetStandard20.shproj +++ b/Src/PerformanceCollector/Perf.Shared.NetStandard20/Perf.Shared.NetStandard20.shproj @@ -1,7 +1,7 @@ - 054c25dc-e545-4712-95c4-81f30cf65ce8 + a8ba3bd0-19ce-488d-b2bd-0b9b677f4e03 14.0 diff --git a/Src/PerformanceCollector/Perf.Shared.NetStandard20/PerformanceCollectorXPlatform.cs b/Src/PerformanceCollector/Perf.Shared.NetStandard20/PerformanceCollectorXPlatform.cs new file mode 100644 index 000000000..dfb213e6d --- /dev/null +++ b/Src/PerformanceCollector/Perf.Shared.NetStandard20/PerformanceCollectorXPlatform.cs @@ -0,0 +1,219 @@ +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.XPlatform +{ + using System; + using System.Collections.Generic; + using System.Globalization; + using System.Linq; + using Microsoft.ApplicationInsights.Common; + + internal class PerformanceCollectorXPlatform : IPerformanceCollector + { + private readonly List> performanceCounters = new List>(); + + /// + /// Gets a collection of registered performance counters. + /// + public IEnumerable PerformanceCounters + { + get { return this.performanceCounters.Select(t => t.Item1).ToList(); } + } + + /// + /// Performs collection for all registered counters. + /// + /// Invoked when an individual counter fails to be read. + public IEnumerable> Collect( + Action onReadingFailure = null) + { + return this.performanceCounters.Where(pc => !pc.Item1.IsInBadState).SelectMany( + counter => + { + double value; + + try + { + value = CollectCounter(counter.Item1.OriginalString, counter.Item2); + } + catch (InvalidOperationException e) + { + onReadingFailure?.Invoke(counter.Item1.OriginalString, e); + + return ArrayExtensions.Empty>(); + } + + return new[] { Tuple.Create(counter.Item1, value) }; + }); + } + + /// + /// Refreshes counters. + /// + public void RefreshCounters() + { + var countersToRefresh = + this.PerformanceCounters.Where(pc => pc.IsInBadState) + .ToList(); + + countersToRefresh.ForEach(this.RefreshPerformanceCounter); + + PerformanceCollectorEventSource.Log.CountersRefreshedEvent(countersToRefresh.Count.ToString(CultureInfo.InvariantCulture)); + } + + /// + /// Registers a counter using the counter name and reportAs value to the total list of counters. + /// + /// Name of the performance counter. + /// Report as name for the performance counter. + /// Captures the error logged. + /// Boolean that controls the registry of the counter based on the availability of instance place holder. + public void RegisterCounter( + string perfCounter, + string reportAs, + out string error, + bool blockCounterWithInstancePlaceHolder) + { + try + { + bool useInstancePlaceHolder = false; + var pc = PerformanceCounterUtility.CreateAndValidateCounter(perfCounter, null, null, false, out useInstancePlaceHolder, out error); + + if (pc != null) + { + this.RegisterPerformanceCounter(perfCounter, GetCounterReportAsName(perfCounter, reportAs), pc.CategoryName, pc.CounterName, pc.InstanceName, useInstancePlaceHolder); + } + else + { + // Even if validation failed, we might still be able to collect perf counter in WebApp. + this.RegisterPerformanceCounter(perfCounter, GetCounterReportAsName(perfCounter, reportAs), string.Empty, perfCounter, string.Empty, useInstancePlaceHolder); + } + } + catch (Exception e) + { + PerformanceCollectorEventSource.Log.WebAppCounterRegistrationFailedEvent( + e.Message, + perfCounter); + error = e.Message; + } + } + + /// + /// Removes a counter. + /// + /// Name of the performance counter to remove. + /// ReportAs value of the performance counter to remove. + public void RemoveCounter(string perfCounter, string reportAs) + { + Tuple keyToRemove = + this.performanceCounters.FirstOrDefault( + pair => + string.Equals(pair.Item1.ReportAs, reportAs, StringComparison.Ordinal) + && string.Equals(pair.Item1.OriginalString, perfCounter, StringComparison.OrdinalIgnoreCase)); + + if (keyToRemove != null) + { + this.performanceCounters.Remove(keyToRemove); + } + } + + /// + /// Rebinds performance counters to Windows resources. + /// + public void RefreshPerformanceCounter(PerformanceCounterData pcd) + { + Tuple tupleToRemove = this.performanceCounters.FirstOrDefault(t => t.Item1 == pcd); + if (tupleToRemove != null) + { + this.performanceCounters.Remove(tupleToRemove); + } + + this.RegisterPerformanceCounter( + pcd.OriginalString, + pcd.ReportAs, + pcd.PerformanceCounter.CategoryName, + pcd.PerformanceCounter.CounterName, + pcd.PerformanceCounter.InstanceName, + pcd.UsesInstanceNamePlaceholder); + } + + /// + /// Collects a value for a single counter. + /// + private static double CollectCounter(string counterOriginalString, ICounterValue counter) + { + try + { + return counter.Collect(); + } + catch (Exception e) + { + throw new InvalidOperationException( + string.Format( + CultureInfo.CurrentCulture, + "Failed to perform a read for web app performance counter {0}", + counterOriginalString), + e); + } + } + + /// + /// Gets metric alias to be the value given by the user. + /// + /// Name of the counter to retrieve. + /// Alias to report the counter. + /// Alias that will be used for the counter. + private static string GetCounterReportAsName(string counterName, string reportAs) + { + return reportAs ?? counterName; + } + + /// + /// Register a performance counter for collection. + /// + private void RegisterPerformanceCounter(string originalString, string reportAs, string categoryName, string counterName, string instanceName, bool usesInstanceNamePlaceholder) + { + ICounterValue counter = null; + + try + { + counter = CounterFactoryXPlatform.GetCounter(originalString); + } + catch + { + PerformanceCollectorEventSource.Log.CounterNotXPlatformSupported(originalString); + return; + } + + bool firstReadOk = false; + + try + { + // perform the first read. For many counters the first read will always return 0 + // since a single sample is not enough to calculate a value + var value = counter.Collect(); + firstReadOk = true; + } + catch (Exception e) + { + throw new InvalidOperationException( + string.Format( + CultureInfo.CurrentCulture, + "Failed to perform the first read for web app performance counter. Please make sure it exists. Counter: {0}", + counterName), + e); + } + finally + { + PerformanceCounterData perfData = new PerformanceCounterData( + originalString, + reportAs, + usesInstanceNamePlaceholder, + !firstReadOk, + categoryName, + counterName, + instanceName); + + this.performanceCounters.Add(new Tuple(perfData, counter)); + } + } + } +} diff --git a/Src/PerformanceCollector/Perf.Shared.NetStandard20/XPlatProcessCPUPerformanceCounter.cs b/Src/PerformanceCollector/Perf.Shared.NetStandard20/XPlatProcessCPUPerformanceCounter.cs new file mode 100644 index 000000000..991296149 --- /dev/null +++ b/Src/PerformanceCollector/Perf.Shared.NetStandard20/XPlatProcessCPUPerformanceCounter.cs @@ -0,0 +1,73 @@ +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.XPlatform +{ + using System; + using System.Diagnostics; + using System.Globalization; + + /// + /// Represents value of CPU Utilization by Process counter value. + /// + internal class XPlatProcessCPUPerformanceCounter : ICounterValue + { + private double lastCollectedValue = 0; + private DateTimeOffset lastCollectedTime = DateTimeOffset.MinValue; + + /// + /// Initializes a new instance of the class. + /// + internal XPlatProcessCPUPerformanceCounter() + { + this.lastCollectedValue = Process.GetCurrentProcess().TotalProcessorTime.Ticks; + this.lastCollectedTime = DateTimeOffset.UtcNow; + } + + /// + /// Returns the current value of the counter. + /// + /// Value of the counter. + public virtual double Collect() + { + try + { + double previouslyCollectedValue = this.lastCollectedValue; + this.lastCollectedValue = Process.GetCurrentProcess().TotalProcessorTime.Ticks; + + var previouslyCollectedTime = this.lastCollectedTime; + this.lastCollectedTime = DateTimeOffset.UtcNow; + + double value = 0; + if (previouslyCollectedTime != DateTimeOffset.MinValue) + { + var baseValue = this.lastCollectedTime.Ticks - previouslyCollectedTime.Ticks; + if (baseValue < 0) + { + // Not likely to happen but being safe here incase of clock issues in multi-core. + PerformanceCollectorEventSource.Log.WebAppCounterNegativeValue( + this.lastCollectedTime.Ticks, + previouslyCollectedTime.Ticks, + "XPlatProcessCPUPerformanceCounter.BaseValue"); + return 0; + } + + baseValue = baseValue != 0 ? baseValue : 1; + + var diff = this.lastCollectedValue - previouslyCollectedValue; + + if (diff >= 0) + { + value = (double)(diff * 100.0 / baseValue); + } + } + + return value; + } + catch (Exception e) + { + throw new InvalidOperationException( + string.Format( + CultureInfo.CurrentCulture, + "Failed to perform a read for performance counter NormalizedXPlatProcessCPUPerformanceCounter. Exception: {0}", e)); + } + } + } +} diff --git a/Src/PerformanceCollector/Perf.Shared.NetStandard20/XPlatProcessCPUPerformanceCounterNormalized.cs b/Src/PerformanceCollector/Perf.Shared.NetStandard20/XPlatProcessCPUPerformanceCounterNormalized.cs new file mode 100644 index 000000000..686e0097c --- /dev/null +++ b/Src/PerformanceCollector/Perf.Shared.NetStandard20/XPlatProcessCPUPerformanceCounterNormalized.cs @@ -0,0 +1,50 @@ +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.XPlatform +{ + using System; + using System.Diagnostics; + using System.Globalization; + + /// + /// Represents normalized value of CPU Utilization by Process counter value (divided by the processors count). + /// + internal class XPlatProcessCPUPerformanceCounterNormalized : XPlatProcessCPUPerformanceCounter + { + private readonly bool isInitialized = false; + private readonly int processorsCount = -1; + + /// + /// Initializes a new instance of the class. + /// + internal XPlatProcessCPUPerformanceCounterNormalized() : base() + { + int? count = PerformanceCounterUtility.GetProcessorCount(); + + if (count.HasValue) + { + this.processorsCount = count.Value; + this.isInitialized = true; + } + } + + /// + /// Returns the current value of the counter as a . + /// + /// Value of the counter. + public override double Collect() + { + if (!this.isInitialized) + { + return 0; + } + + double result = 0; + if (this.processorsCount >= 1) + { + double value = base.Collect(); + result = value / this.processorsCount; + } + + return result; + } + } +} diff --git a/Src/PerformanceCollector/Perf.Shared.NetStandard20/XPlatProcessMemoryPerformanceCounter.cs b/Src/PerformanceCollector/Perf.Shared.NetStandard20/XPlatProcessMemoryPerformanceCounter.cs new file mode 100644 index 000000000..26d4a5e5c --- /dev/null +++ b/Src/PerformanceCollector/Perf.Shared.NetStandard20/XPlatProcessMemoryPerformanceCounter.cs @@ -0,0 +1,32 @@ +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.XPlatform +{ + using System; + using System.Diagnostics; + using System.Globalization; + + /// + /// Represents Private Bytes performance counter equivalent for the current process. + /// https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.privatememorysize64. + /// + internal class XPlatProcessMemoryPerformanceCounter : ICounterValue + { + /// + /// Returns the current value of the counter. + /// + /// Value of the counter. + public double Collect() + { + try + { + return Process.GetCurrentProcess().PrivateMemorySize64; + } + catch (Exception e) + { + throw new InvalidOperationException( + string.Format( + CultureInfo.CurrentCulture, + "Failed to perform a read for performance counter XPlatProcessMemoryPerformanceCounter. Exception: {0}", e)); + } + } + } +} diff --git a/Src/PerformanceCollector/Perf.Shared.NetStandard20Net45/Perf.Shared.NetStandard20Net45.projitems b/Src/PerformanceCollector/Perf.Shared.NetStandard20Net45/Perf.Shared.NetStandard20Net45.projitems new file mode 100644 index 000000000..6b25d5485 --- /dev/null +++ b/Src/PerformanceCollector/Perf.Shared.NetStandard20Net45/Perf.Shared.NetStandard20Net45.projitems @@ -0,0 +1,17 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + 054c25dc-e545-4712-95c4-81f30cf65ce8 + + + Perf.Shared.NetStandard20Net45 + + + + + + + + \ No newline at end of file diff --git a/Src/PerformanceCollector/Perf.Shared.NetStandard20Net45/Perf.Shared.NetStandard20Net45.shproj b/Src/PerformanceCollector/Perf.Shared.NetStandard20Net45/Perf.Shared.NetStandard20Net45.shproj new file mode 100644 index 000000000..6f5cfb9d0 --- /dev/null +++ b/Src/PerformanceCollector/Perf.Shared.NetStandard20Net45/Perf.Shared.NetStandard20Net45.shproj @@ -0,0 +1,13 @@ + + + + 054c25dc-e545-4712-95c4-81f30cf65ce8 + 14.0 + + + + + + + + diff --git a/Src/PerformanceCollector/Perf.Shared.NetStandard20/StandardPerformanceCollector/CounterFactory.cs b/Src/PerformanceCollector/Perf.Shared.NetStandard20Net45/StandardPerformanceCollector/CounterFactory.cs similarity index 93% rename from Src/PerformanceCollector/Perf.Shared.NetStandard20/StandardPerformanceCollector/CounterFactory.cs rename to Src/PerformanceCollector/Perf.Shared.NetStandard20Net45/StandardPerformanceCollector/CounterFactory.cs index 83bdf4409..800743599 100644 --- a/Src/PerformanceCollector/Perf.Shared.NetStandard20/StandardPerformanceCollector/CounterFactory.cs +++ b/Src/PerformanceCollector/Perf.Shared.NetStandard20Net45/StandardPerformanceCollector/CounterFactory.cs @@ -1,7 +1,5 @@ -namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.StandardPerformanceCollector +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.StandardPerfCollector { - using System; - /// /// Factory to create different counters. /// diff --git a/Src/PerformanceCollector/Perf.Shared.NetStandard20/StandardPerformanceCollector/NormalizedProcessCPUPerformanceCounter.cs b/Src/PerformanceCollector/Perf.Shared.NetStandard20Net45/StandardPerformanceCollector/NormalizedProcessCPUPerformanceCounter.cs similarity index 97% rename from Src/PerformanceCollector/Perf.Shared.NetStandard20/StandardPerformanceCollector/NormalizedProcessCPUPerformanceCounter.cs rename to Src/PerformanceCollector/Perf.Shared.NetStandard20Net45/StandardPerformanceCollector/NormalizedProcessCPUPerformanceCounter.cs index 7a2c16025..db4837671 100644 --- a/Src/PerformanceCollector/Perf.Shared.NetStandard20/StandardPerformanceCollector/NormalizedProcessCPUPerformanceCounter.cs +++ b/Src/PerformanceCollector/Perf.Shared.NetStandard20Net45/StandardPerformanceCollector/NormalizedProcessCPUPerformanceCounter.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.StandardPerformanceCollector +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.StandardPerfCollector { using System; using System.Diagnostics; @@ -19,7 +19,7 @@ internal class NormalizedProcessCPUPerformanceCounter : ICounterValue, IDisposab /// The instance name. internal NormalizedProcessCPUPerformanceCounter(string instanceName) { - int? count = PerformanceCounterUtility.GetProcessorCount(false); + int? count = PerformanceCounterUtility.GetProcessorCount(); if (count.HasValue) { diff --git a/Src/PerformanceCollector/Perf.Shared.NetStandard20/StandardPerformanceCollector/StandardPerformanceCollector.cs b/Src/PerformanceCollector/Perf.Shared.NetStandard20Net45/StandardPerformanceCollector/StandardPerformanceCollector.cs similarity index 93% rename from Src/PerformanceCollector/Perf.Shared.NetStandard20/StandardPerformanceCollector/StandardPerformanceCollector.cs rename to Src/PerformanceCollector/Perf.Shared.NetStandard20Net45/StandardPerformanceCollector/StandardPerformanceCollector.cs index 5c098c6d3..5606b97b2 100644 --- a/Src/PerformanceCollector/Perf.Shared.NetStandard20/StandardPerformanceCollector/StandardPerformanceCollector.cs +++ b/Src/PerformanceCollector/Perf.Shared.NetStandard20Net45/StandardPerformanceCollector/StandardPerformanceCollector.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.StandardPerformanceCollector +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.StandardPerfCollector { using System; using System.Collections.Generic; @@ -72,13 +72,11 @@ public void RefreshCounters() /// /// Name of the performance counter. /// Report as name for the performance counter. - /// Boolean to check if the performance counter is custom defined. /// Captures the error logged. /// Boolean that controls the registry of the counter based on the availability of instance place holder. public void RegisterCounter( string perfCounterName, - string reportAs, - bool isCustomCounter, + string reportAs, out string error, bool blockCounterWithInstancePlaceHolder = false) { @@ -94,13 +92,14 @@ public void RegisterCounter( perfCounterName, this.win32Instances, this.clrInstances, + true, out usesInstanceNamePlaceholder, out error); // If blockCounterWithInstancePlaceHolder is true, then we register the counter only if usesInstanceNamePlaceHolder is true. if (pc != null && !(blockCounterWithInstancePlaceHolder && usesInstanceNamePlaceholder)) { - this.RegisterCounter(perfCounterName, reportAs, pc, isCustomCounter, usesInstanceNamePlaceholder, out error); + this.RegisterCounter(perfCounterName, reportAs, pc, usesInstanceNamePlaceholder, out error); } } @@ -149,8 +148,7 @@ private void RefreshPerformanceCounter(PerformanceCounterData pcd) pcd.PerformanceCounter.CategoryName, pcd.PerformanceCounter.CounterName, pcd.PerformanceCounter.InstanceName, - pcd.UsesInstanceNamePlaceholder, - pcd.IsCustomCounter); + pcd.UsesInstanceNamePlaceholder); } /// @@ -175,6 +173,7 @@ private void RefreshCounter(PerformanceCounterData pcd) pcd.OriginalString, this.win32Instances, this.clrInstances, + true, out usesInstanceNamePlaceholder, out dummy); @@ -199,14 +198,12 @@ private void RefreshCounter(PerformanceCounterData pcd) /// Counter original string. /// Counter report as. /// Performance counter. - /// Boolean to check if it is a custom counter. /// Uses Instance Name Place holder boolean. /// Error message. private void RegisterCounter( string originalString, string reportAs, PerformanceCounterStructure pc, - bool isCustomCounter, bool usesInstanceNamePlaceholder, out string error) { @@ -220,8 +217,7 @@ private void RegisterCounter( pc.CategoryName, pc.CounterName, pc.InstanceName, - usesInstanceNamePlaceholder, - isCustomCounter); + usesInstanceNamePlaceholder); PerformanceCollectorEventSource.Log.CounterRegisteredEvent(PerformanceCounterUtility.FormatPerformanceCounter(pc)); } @@ -241,8 +237,7 @@ private void RegisterCounter( /// Counter name. /// Instance name. /// Indicates whether the counter uses a placeholder in the instance name. - /// Indicates whether the counter is a custom counter. - private void RegisterPerformanceCounter(string originalString, string reportAs, string categoryName, string counterName, string instanceName, bool usesInstanceNamePlaceholder, bool isCustomCounter) + private void RegisterPerformanceCounter(string originalString, string reportAs, string categoryName, string counterName, string instanceName, bool usesInstanceNamePlaceholder) { ICounterValue performanceCounter = null; @@ -292,8 +287,7 @@ private void RegisterPerformanceCounter(string originalString, string reportAs, PerformanceCounterData perfData = new PerformanceCounterData( originalString, reportAs, - usesInstanceNamePlaceholder, - isCustomCounter, + usesInstanceNamePlaceholder, !firstReadOk, categoryName, counterName, diff --git a/Src/PerformanceCollector/Perf.Shared.NetStandard20/StandardPerformanceCollector/StandardPerformanceCounter.cs b/Src/PerformanceCollector/Perf.Shared.NetStandard20Net45/StandardPerformanceCollector/StandardPerformanceCounter.cs similarity index 97% rename from Src/PerformanceCollector/Perf.Shared.NetStandard20/StandardPerformanceCollector/StandardPerformanceCounter.cs rename to Src/PerformanceCollector/Perf.Shared.NetStandard20Net45/StandardPerformanceCollector/StandardPerformanceCounter.cs index 39a844300..bc07308fd 100644 --- a/Src/PerformanceCollector/Perf.Shared.NetStandard20/StandardPerformanceCollector/StandardPerformanceCounter.cs +++ b/Src/PerformanceCollector/Perf.Shared.NetStandard20Net45/StandardPerformanceCollector/StandardPerformanceCounter.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.StandardPerformanceCollector +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.StandardPerfCollector { using System; using System.Diagnostics; diff --git a/Src/PerformanceCollector/Perf.Shared.Tests/Mocks/PerformanceCollectorMock.cs b/Src/PerformanceCollector/Perf.Shared.Tests/Mocks/PerformanceCollectorMock.cs index ba4969b91..e3074494f 100644 --- a/Src/PerformanceCollector/Perf.Shared.Tests/Mocks/PerformanceCollectorMock.cs +++ b/Src/PerformanceCollector/Perf.Shared.Tests/Mocks/PerformanceCollectorMock.cs @@ -54,7 +54,6 @@ public IEnumerable> Collect(Action + + diff --git a/Src/PerformanceCollector/Perf.Shared.Tests/PerformanceCollectorModuleTests.cs b/Src/PerformanceCollector/Perf.Shared.Tests/PerformanceCollectorModuleTests.cs new file mode 100644 index 000000000..9c0bd0225 --- /dev/null +++ b/Src/PerformanceCollector/Perf.Shared.Tests/PerformanceCollectorModuleTests.cs @@ -0,0 +1,140 @@ +namespace Microsoft.ApplicationInsights.Tests +{ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + using Microsoft.ApplicationInsights.Extensibility; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + /// + /// PerformanceCollectorModuleTests tests. + /// The goal is to test that the default list contains only those counters which are supported. + /// Adding any unsupported counter by default will add noisy traces to user ikey. + /// + [TestClass] + public class PerformanceCollectorModuleTests + { + [TestMethod] + public void PerformanceCollectorModuleDefaultContainsExpectedCountersNonWindows() + { +#if NETCOREAPP2_0 + PerformanceCounterUtility.isAzureWebApp = null; + var original = PerformanceCounterUtility.IsWindows; + PerformanceCounterUtility.IsWindows = false; + var module = new PerformanceCollectorModule(); + + try + { + module.Initialize(new TelemetryConfiguration()); + + Assert.IsTrue(ContainsPerfCounter(module.DefaultCounters, @"\Process(??APP_WIN32_PROC??)\% Processor Time")); + Assert.IsTrue(ContainsPerfCounter(module.DefaultCounters, @"\Process(??APP_WIN32_PROC??)\% Processor Time Normalized")); + Assert.IsTrue(ContainsPerfCounter(module.DefaultCounters, @"\Process(??APP_WIN32_PROC??)\Private Bytes")); + Assert.AreEqual(3, module.DefaultCounters.Count); + } + finally + { + PerformanceCounterUtility.IsWindows = original; + module.Dispose(); + } +#endif + } + + [TestMethod] + public void PerformanceCollectorModuleDefaultContainsExpectedCountersWebApps() + { + PerformanceCounterUtility.isAzureWebApp = null; + Environment.SetEnvironmentVariable("WEBSITE_SITE_NAME", "something"); + var module = new PerformanceCollectorModule(); + try + { + module.Initialize(new TelemetryConfiguration()); + + Assert.IsTrue(ContainsPerfCounter(module.DefaultCounters, @"\Process(??APP_WIN32_PROC??)\% Processor Time")); + Assert.IsTrue(ContainsPerfCounter(module.DefaultCounters, @"\Process(??APP_WIN32_PROC??)\% Processor Time Normalized")); + Assert.IsTrue(ContainsPerfCounter(module.DefaultCounters, @"\Process(??APP_WIN32_PROC??)\Private Bytes")); + + Assert.IsTrue(ContainsPerfCounter(module.DefaultCounters, @"\Memory\Available Bytes")); + Assert.IsTrue(ContainsPerfCounter(module.DefaultCounters, @"\Process(??APP_WIN32_PROC??)\IO Data Bytes/sec")); + +#if NET45 + Assert.IsTrue(ContainsPerfCounter(module.DefaultCounters, @"\ASP.NET Applications(??APP_W3SVC_PROC??)\Requests/Sec")); + Assert.IsTrue(ContainsPerfCounter(module.DefaultCounters, @"\.NET CLR Exceptions(??APP_CLR_PROC??)\# of Exceps Thrown / sec")); + Assert.IsTrue(ContainsPerfCounter(module.DefaultCounters, @"\ASP.NET Applications(??APP_W3SVC_PROC??)\Request Execution Time")); + Assert.IsTrue(ContainsPerfCounter(module.DefaultCounters, @"\ASP.NET Applications(??APP_W3SVC_PROC??)\Requests In Application Queue")); + Assert.AreEqual(9, module.DefaultCounters.Count); +#else + Assert.AreEqual(5, module.DefaultCounters.Count); +#endif + } + finally + { + PerformanceCounterUtility.isAzureWebApp = null; + module.Dispose(); + Environment.SetEnvironmentVariable("WEBSITE_SITE_NAME", string.Empty); + Task.Delay(1000).Wait(); + } + } + + [TestMethod] + public void PerformanceCollectorModuleDefaultContainsExpectedCountersWindows() + { + PerformanceCounterUtility.isAzureWebApp = null; + var module = new PerformanceCollectorModule(); +#if NETCOREAPP2_0 + var original = PerformanceCounterUtility.IsWindows; + PerformanceCounterUtility.IsWindows = true; +#endif + try + { + module.Initialize(new TelemetryConfiguration()); +#if !NETCOREAPP1_0 + Assert.IsTrue(ContainsPerfCounter(module.DefaultCounters, @"\Process(??APP_WIN32_PROC??)\% Processor Time")); + Assert.IsTrue(ContainsPerfCounter(module.DefaultCounters, @"\Process(??APP_WIN32_PROC??)\% Processor Time Normalized")); + Assert.IsTrue(ContainsPerfCounter(module.DefaultCounters, @"\Process(??APP_WIN32_PROC??)\Private Bytes")); + + Assert.IsTrue(ContainsPerfCounter(module.DefaultCounters, @"\Memory\Available Bytes")); + Assert.IsTrue(ContainsPerfCounter(module.DefaultCounters, @"\Process(??APP_WIN32_PROC??)\IO Data Bytes/sec")); + +#if NET45 + Assert.IsTrue(ContainsPerfCounter(module.DefaultCounters, @"\ASP.NET Applications(??APP_W3SVC_PROC??)\Requests/Sec")); + Assert.IsTrue(ContainsPerfCounter(module.DefaultCounters, @"\.NET CLR Exceptions(??APP_CLR_PROC??)\# of Exceps Thrown / sec")); + Assert.IsTrue(ContainsPerfCounter(module.DefaultCounters, @"\ASP.NET Applications(??APP_W3SVC_PROC??)\Request Execution Time")); + Assert.IsTrue(ContainsPerfCounter(module.DefaultCounters, @"\ASP.NET Applications(??APP_W3SVC_PROC??)\Requests In Application Queue")); +#endif + + Assert.IsTrue(ContainsPerfCounter(module.DefaultCounters, @"\Processor(_Total)\% Processor Time")); +#if NET45 + Assert.AreEqual(10, module.DefaultCounters.Count); +#else + Assert.AreEqual(6, module.DefaultCounters.Count); +#endif + +#endif + + } + finally + { + module.Dispose(); +#if NETCOREAPP2_0 + PerformanceCounterUtility.IsWindows = original; +#endif + } + } + + private bool ContainsPerfCounter(IList counters, string name) + { + foreach (var counter in counters) + { + if (counter.PerformanceCounter.Equals(name)) + { + return true; + } + } + + return false; + } + } +} \ No newline at end of file diff --git a/Src/PerformanceCollector/Perf.Shared.Tests/PerformanceCollectorWebAppTestBase.cs b/Src/PerformanceCollector/Perf.Shared.Tests/PerformanceCollectorWebAppTestBase.cs index 99ae6b73c..52b661931 100644 --- a/Src/PerformanceCollector/Perf.Shared.Tests/PerformanceCollectorWebAppTestBase.cs +++ b/Src/PerformanceCollector/Perf.Shared.Tests/PerformanceCollectorWebAppTestBase.cs @@ -6,8 +6,7 @@ using System.Linq; using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector; using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation; - using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.StandardPerformanceCollector; - using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector; using Microsoft.VisualStudio.TestTools.UnitTesting; /// @@ -24,8 +23,7 @@ internal void PerformanceCollectorSanityTest(IPerformanceCollector collector, st string error; collector.RegisterCounter( counter, - null, - true, + null, out error, false); } @@ -64,7 +62,6 @@ internal void PerformanceCollectorAddRemoveCountersForWebAppTest(WebAppPerforman collector.RegisterCounter( counterRequest.PerformanceCounter, counterRequest.ReportAs, - true, out error, false); } diff --git a/Src/PerformanceCollector/Perf.Shared.Tests/PerformanceCounterUtilityTestsCommon.cs b/Src/PerformanceCollector/Perf.Shared.Tests/PerformanceCounterUtilityTestsCommon.cs new file mode 100644 index 000000000..3f4ea5d1a --- /dev/null +++ b/Src/PerformanceCollector/Perf.Shared.Tests/PerformanceCounterUtilityTestsCommon.cs @@ -0,0 +1,93 @@ +namespace Microsoft.ApplicationInsights.Tests +{ + using System; + using System.Threading.Tasks; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + /// + /// PerformanceCounterUtilityTests + /// + [TestClass] + public class PerformanceCounterUtilityTestsCommon + { + // TODO enable Non windows test when CI is configured to run in linux. + [TestMethod] + public void GetCollectorReturnsCorrectCollector() + { + try + { + var actual = PerformanceCounterUtility.GetPerformanceCollector(); +#if NETCOREAPP1_0 + Assert.AreEqual("StandardPerformanceCollectorStub", actual.GetType().Name); +#elif NETCOREAPP2_0 + Assert.AreEqual("StandardPerformanceCollector", actual.GetType().Name); +#else // NET45 + Assert.AreEqual("StandardPerformanceCollector", actual.GetType().Name); +#endif + } + finally + { + PerformanceCounterUtility.isAzureWebApp = null; + } + } + + [TestMethod] + public void GetCollectorReturnsWebAppCollector() + { + try + { + Environment.SetEnvironmentVariable("WEBSITE_SITE_NAME", "something"); + var actual = PerformanceCounterUtility.GetPerformanceCollector(); + Assert.AreEqual("WebAppPerformanceCollector", actual.GetType().Name); + } + finally + { + PerformanceCounterUtility.isAzureWebApp = null; + Environment.SetEnvironmentVariable("WEBSITE_SITE_NAME", string.Empty); + Task.Delay(1000).Wait(); + } + } + + [TestMethod] + public void GetCollectorReturnsXPlatformCollectorForWebAppForLinux() + { +#if NETCOREAPP2_0 + var original = PerformanceCounterUtility.IsWindows; + try + { + Environment.SetEnvironmentVariable("WEBSITE_SITE_NAME", "something"); + PerformanceCounterUtility.IsWindows = false; + var actual = PerformanceCounterUtility.GetPerformanceCollector(); + Assert.AreEqual("PerformanceCollectorXPlatform", actual.GetType().Name); + } + finally + { + PerformanceCounterUtility.IsWindows = original; + PerformanceCounterUtility.isAzureWebApp = null; + Environment.SetEnvironmentVariable("WEBSITE_SITE_NAME", string.Empty); + Task.Delay(1000).Wait(); + } +#endif + } + + [TestMethod] + public void GetCollectorReturnsXPlatformCollectorForNonWindows() + { +#if NETCOREAPP2_0 + var original = PerformanceCounterUtility.IsWindows; + try + { + PerformanceCounterUtility.IsWindows = false; + var actual = PerformanceCounterUtility.GetPerformanceCollector(); + Assert.AreEqual("PerformanceCollectorXPlatform", actual.GetType().Name); + } + finally + { + PerformanceCounterUtility.IsWindows = original; + PerformanceCounterUtility.isAzureWebApp = null; + } +#endif + } + } +} \ No newline at end of file diff --git a/Src/PerformanceCollector/Perf.Shared.Tests/QuickPulse/QuickPulseServiceClientTests.cs b/Src/PerformanceCollector/Perf.Shared.Tests/QuickPulse/QuickPulseServiceClientTests.cs index 9f6e8711c..f87cf301d 100644 --- a/Src/PerformanceCollector/Perf.Shared.Tests/QuickPulse/QuickPulseServiceClientTests.cs +++ b/Src/PerformanceCollector/Perf.Shared.Tests/QuickPulse/QuickPulseServiceClientTests.cs @@ -2032,18 +2032,21 @@ private void ProcessRequest(HttpListener listener, AutoResetEvent ev) this.pingResponse(context.Response); - var dataPoint = (MonitoringDataPoint)serializerDataPoint.ReadObject(context.Request.InputStream); + var dataPoint = + (MonitoringDataPoint) serializerDataPoint.ReadObject(context.Request.InputStream); var transmissionTime = long.Parse( context.Request.Headers[QuickPulseConstants.XMsQpsTransmissionTimeHeaderName], CultureInfo.InvariantCulture); - var instanceName = context.Request.Headers[QuickPulseConstants.XMsQpsInstanceNameHeaderName]; + var instanceName = + context.Request.Headers[QuickPulseConstants.XMsQpsInstanceNameHeaderName]; var machineName = context.Request.Headers[QuickPulseConstants.XMsQpsMachineNameHeaderName]; var invariantVersion = context.Request.Headers[QuickPulseConstants.XMsQpsInvariantVersionHeaderName]; var streamId = context.Request.Headers[QuickPulseConstants.XMsQpsStreamIdHeaderName]; - var collectionConfigurationETag = context.Request.Headers[QuickPulseConstants.XMsQpsConfigurationETagHeaderName]; + var collectionConfigurationETag = + context.Request.Headers[QuickPulseConstants.XMsQpsConfigurationETagHeaderName]; - this.pings.Add( + this.pings.Add( Tuple.Create( new PingHeaders() { @@ -2068,15 +2071,19 @@ private void ProcessRequest(HttpListener listener, AutoResetEvent ev) this.submitResponse(context.Response); - var dataPoints = serializerDataPointArray.ReadObject(context.Request.InputStream) as MonitoringDataPoint[]; + var dataPoints = + serializerDataPointArray.ReadObject(context.Request.InputStream) as MonitoringDataPoint + []; var transmissionTime = long.Parse( context.Request.Headers[QuickPulseConstants.XMsQpsTransmissionTimeHeaderName], CultureInfo.InvariantCulture); - var collectionConfigurationETag = context.Request.Headers[QuickPulseConstants.XMsQpsConfigurationETagHeaderName]; + var collectionConfigurationETag = + context.Request.Headers[QuickPulseConstants.XMsQpsConfigurationETagHeaderName]; this.samples.AddRange( dataPoints.Select( - dp => Tuple.Create(new DateTimeOffset(transmissionTime, TimeSpan.Zero), collectionConfigurationETag, dp))); + dp => Tuple.Create(new DateTimeOffset(transmissionTime, TimeSpan.Zero), + collectionConfigurationETag, dp))); } break; @@ -2089,9 +2096,13 @@ private void ProcessRequest(HttpListener listener, AutoResetEvent ev) context.Response.Close(); } } + catch (Exception e) + { + System.Diagnostics.Trace.WriteLine("Exception occuring in ProcessRequest. " + e.ToString()); + } finally { - this.AssertionSync.Release(); + this.AssertionSync?.Release(); } } } diff --git a/Src/PerformanceCollector/Perf.Shared.Tests/QuickPulse/QuickPulseTelemetryModuleTests.cs b/Src/PerformanceCollector/Perf.Shared.Tests/QuickPulse/QuickPulseTelemetryModuleTests.cs index f9df8a00f..f730c058f 100644 --- a/Src/PerformanceCollector/Perf.Shared.Tests/QuickPulse/QuickPulseTelemetryModuleTests.cs +++ b/Src/PerformanceCollector/Perf.Shared.Tests/QuickPulse/QuickPulseTelemetryModuleTests.cs @@ -45,7 +45,9 @@ public void QuickPulseTelemetryModuleIsInitializedBySdk() builder = builder.Use(current => telemetryProcessor); builder.Build(); - new QuickPulseTelemetryModule().Initialize(configuration); + var qp = new QuickPulseTelemetryModule(); + qp.Initialize(configuration); + qp.Dispose(); } [TestMethod] @@ -346,6 +348,8 @@ public void QuickPulseTelemetryModuleInteractsWithTelemetryProcessorCorrectlyWhe Assert.IsNotNull(telemetryProcessor); Assert.AreEqual(telemetryProcessor, QuickPulseTestHelper.GetTelemetryProcessors(module).SingleOrDefault()); + + newModule.Dispose(); } [TestMethod] diff --git a/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/AzureWebAppTest.cs b/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/AzureWebAppTest.cs index 41a1c3d8f..b0ea68ea1 100644 --- a/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/AzureWebAppTest.cs +++ b/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/AzureWebAppTest.cs @@ -1,6 +1,6 @@ namespace Microsoft.ApplicationInsights.Tests { - using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector; using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] @@ -10,7 +10,7 @@ public class UnitTestAzureWeb public void TestPerformanceCounterValuesAreCorrectlyRetrievedUsingRawCounterGauge() { RawCounterGauge gauge = new RawCounterGauge(@"\Process(??APP_WIN32_PROC??)\Private Bytes", "privateBytes", AzureWebApEnvironmentVariables.App, new CacheHelperTests()); - double value = gauge.GetValueAndReset(); + double value = gauge.Collect(); Assert.IsTrue(value > 0); } diff --git a/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/CPUPercenageGaugeTests.cs b/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/CPUPercenageGaugeTests.cs index 02e3d87ad..3a5a325de 100644 --- a/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/CPUPercenageGaugeTests.cs +++ b/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/CPUPercenageGaugeTests.cs @@ -4,10 +4,10 @@ using System.Diagnostics; using System.Globalization; using System.Threading; - using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector; using Microsoft.VisualStudio.TestTools.UnitTesting; - [TestClass] + [TestClass] public class CPUPercenageGaugeTests { [TestMethod] @@ -17,12 +17,12 @@ public void BasicValidation() "CPU", new RawCounterGauge(@"\Process(??APP_WIN32_PROC??)\Private Bytes * 2", "userTime", AzureWebApEnvironmentVariables.App, new CacheHelperTests())); - double value1 = gauge.GetValueAndReset(); + double value1 = gauge.Collect(); Assert.IsTrue(Math.Abs(value1) < 0.000001); Stopwatch sw = Stopwatch.StartNew(); Thread.Sleep(TimeSpan.FromSeconds(10)); long actualSleepTimeTicks = sw.Elapsed.Ticks; - double value2 = gauge.GetValueAndReset(); + double value2 = gauge.Collect(); Assert.IsTrue( Math.Abs(value2 - ((24843750 - 24062500.0) / actualSleepTimeTicks * 100.0)) < 0.005, string.Format(CultureInfo.InvariantCulture, "Actual: {0}, Expected: {1}", value2, (24843750 - 24062500.0) / actualSleepTimeTicks)); diff --git a/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/CacheHelperTests.cs b/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/CacheHelperTests.cs index 23ae365ba..c7de9eaf2 100644 --- a/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/CacheHelperTests.cs +++ b/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/CacheHelperTests.cs @@ -1,7 +1,7 @@ namespace Microsoft.ApplicationInsights.Tests { using System.IO; - using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector; internal class CacheHelperTests : ICachedEnvironmentVariableAccess { diff --git a/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/NormalizedCPUPercenageGaugeTests.cs b/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/NormalizedCPUPercenageGaugeTests.cs index 57a59b566..ad828b55a 100644 --- a/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/NormalizedCPUPercenageGaugeTests.cs +++ b/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/NormalizedCPUPercenageGaugeTests.cs @@ -4,7 +4,7 @@ using System.Diagnostics; using System.Globalization; using System.Threading; - using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector; using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] @@ -22,8 +22,8 @@ public void NormalizedCPUPercenageGaugeBasicValidation() "CPU", new RawCounterGauge(@"\Process(??APP_WIN32_PROC??)\Private Bytes", "userTime", AzureWebApEnvironmentVariables.App, new CacheHelperTests())); - double value1 = gauge.GetValueAndReset(); - double normalizedValue1 = normalizedGauge.GetValueAndReset(); + double value1 = gauge.Collect(); + double normalizedValue1 = normalizedGauge.Collect(); Assert.IsTrue(Math.Abs(value1) < 0.000001); Assert.IsTrue(Math.Abs(normalizedValue1) < 0.000001); @@ -32,8 +32,8 @@ public void NormalizedCPUPercenageGaugeBasicValidation() Thread.Sleep(TimeSpan.FromSeconds(10)); long actualSleepTimeTicks = sw.Elapsed.Ticks; - double value2 = gauge.GetValueAndReset(); - double normalizedValue2 = normalizedGauge.GetValueAndReset(); + double value2 = gauge.Collect(); + double normalizedValue2 = normalizedGauge.Collect(); Assert.IsTrue( Math.Abs(value2 - (normalizedValue2 * initialProcessorsCount)) < 0.005, diff --git a/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/RateCounterTests.cs b/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/RateCounterTests.cs index 0897a824e..d80d58a91 100644 --- a/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/RateCounterTests.cs +++ b/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/RateCounterTests.cs @@ -1,7 +1,7 @@ namespace Microsoft.ApplicationInsights.Tests { using System.Globalization; - using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector; using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] @@ -12,7 +12,7 @@ public void RateCounterGaugeGetValueAndResetGetsTheValueFromJson() { RateCounterGauge privateBytesRate = new RateCounterGauge(@"\Process(??APP_WIN32_PROC??)\Private Bytes", "privateBytes", AzureWebApEnvironmentVariables.App, null, new CacheHelperTests()); - double value = privateBytesRate.GetValueAndReset(); + double value = privateBytesRate.Collect(); // Initial read - so rate is expected to be zero. Also the actual raw value of the counter is 10000 from RemoteEnvironmentVariablesAllSampleOne.json Assert.IsTrue(value == 0); @@ -21,7 +21,7 @@ public void RateCounterGaugeGetValueAndResetGetsTheValueFromJson() // Second read, the actual raw value of the counter is 200000 from RemoteEnvironmentVariablesAllSampleTwo.json // Rate should be (200000-10000)/ 7 secs = ~14000 - value = privateBytesRate.GetValueAndReset(); + value = privateBytesRate.Collect(); Assert.IsTrue(value >= 10000 && value <= 20000, string.Format(CultureInfo.InvariantCulture, "ActualRate:{0}, is not within expected range", value)); } diff --git a/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/RatioCounterTests.cs b/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/RatioCounterTests.cs index 406795bd0..245cabb2b 100644 --- a/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/RatioCounterTests.cs +++ b/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/RatioCounterTests.cs @@ -1,7 +1,7 @@ namespace Microsoft.ApplicationInsights.Tests { using System; - using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector; using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] @@ -16,18 +16,18 @@ public void RateCounterGaugeGetValueAndResetGetsTheValueFromJson() RatioCounterGauge readIoBytesRate = new RatioCounterGauge(@"\Process(??APP_WIN32_PROC??)\Private Bytes", readIoBytes, writeIoBytes); - double value1 = readIoBytesRate.GetValueAndReset(); + double value1 = readIoBytesRate.Collect(); Assert.IsTrue(value1 != 0); SumUpCountersGauge writeAndOtherBytes = new SumUpCountersGauge("Sum Up Bytes", writeIoBytes, otherIoBytes); RatioCounterGauge totalReadIoBytesRate = new RatioCounterGauge(@"\Process(??APP_WIN32_PROC??)\Private Bytes", readIoBytes, writeAndOtherBytes); - double value2 = totalReadIoBytesRate.GetValueAndReset(); + double value2 = totalReadIoBytesRate.Collect(); Assert.IsTrue(value2 != 0); Assert.IsTrue(value1 >= value2); RatioCounterGauge totalReadIoBytesPercentage = new RatioCounterGauge(@"\Process(??APP_WIN32_PROC??)\Private Bytes", readIoBytes, writeAndOtherBytes, 100); - double percentage = totalReadIoBytesPercentage.GetValueAndReset(); + double percentage = totalReadIoBytesPercentage.Collect(); Assert.IsTrue(percentage != 0); Assert.IsTrue(Math.Abs((value2 * 100) - percentage) < 1); } @@ -36,7 +36,7 @@ public void RateCounterGaugeGetValueAndResetGetsTheValueFromJson() public void RatioCounterGaugeDoesNotThrowWithNullGauges() { RatioCounterGauge readIoBytesRate = new RatioCounterGauge(@"\Process(??APP_WIN32_PROC??)\Private Bytes", null, null); - readIoBytesRate.GetValueAndReset(); + readIoBytesRate.Collect(); } } } diff --git a/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/SumUpCountersGaugeTests.cs b/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/SumUpCountersGaugeTests.cs index 184d4762a..75cf51ff3 100644 --- a/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/SumUpCountersGaugeTests.cs +++ b/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollector/SumUpCountersGaugeTests.cs @@ -1,6 +1,6 @@ namespace Microsoft.ApplicationInsights.Tests { - using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector; using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] @@ -16,8 +16,8 @@ public void RateCounterGaugeGetValueAndResetGetsTheValueFromJson() RawCounterGauge privateBytes = new RawCounterGauge(@"\Process(??APP_WIN32_PROC??)\Private Bytes", "privateBytes", AzureWebApEnvironmentVariables.App, new CacheHelperTests()); - double expectedValue = privateBytes.GetValueAndReset(); - double actualValue = twoTimesPrivateBytes.GetValueAndReset(); + double expectedValue = privateBytes.Collect(); + double actualValue = twoTimesPrivateBytes.Collect(); // twoTimesPrivateBytes is -greater than (privateBytes * 1.85) but lower than (privateBytes * 2.15). Assert.IsTrue((expectedValue * 1.85) < actualValue && (expectedValue * 2.15) > actualValue); diff --git a/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollectorTests.cs b/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollectorTests.cs index b806d98da..add9442ce 100644 --- a/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollectorTests.cs +++ b/Src/PerformanceCollector/Perf.Shared.Tests/WebAppPerformanceCollectorTests.cs @@ -1,6 +1,7 @@ namespace Microsoft.ApplicationInsights.Tests { - using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector; using Microsoft.VisualStudio.TestTools.UnitTesting; /// diff --git a/Src/PerformanceCollector/Perf.Shared.NetStandard20/StandardPerformanceCollector/ICounterValue.cs b/Src/PerformanceCollector/Perf.Shared/Implementation/ICounterValue.cs similarity index 69% rename from Src/PerformanceCollector/Perf.Shared.NetStandard20/StandardPerformanceCollector/ICounterValue.cs rename to Src/PerformanceCollector/Perf.Shared/Implementation/ICounterValue.cs index d7d159782..b6bbce7ff 100644 --- a/Src/PerformanceCollector/Perf.Shared.NetStandard20/StandardPerformanceCollector/ICounterValue.cs +++ b/Src/PerformanceCollector/Perf.Shared/Implementation/ICounterValue.cs @@ -1,12 +1,14 @@ -namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.StandardPerformanceCollector +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation { + using Microsoft.ApplicationInsights.DataContracts; + /// /// Interface represents the counter value. /// internal interface ICounterValue { /// - /// Returns the current value of the counter as a . + /// Returns the current value of the counter. /// /// Value of the counter. double Collect(); diff --git a/Src/PerformanceCollector/Perf.Shared/Implementation/IPerformanceCollector.cs b/Src/PerformanceCollector/Perf.Shared/Implementation/IPerformanceCollector.cs index aa0e5d04d..5b83d4add 100644 --- a/Src/PerformanceCollector/Perf.Shared/Implementation/IPerformanceCollector.cs +++ b/Src/PerformanceCollector/Perf.Shared/Implementation/IPerformanceCollector.cs @@ -25,11 +25,10 @@ internal interface IPerformanceCollector /// Registers a counter using the counter name and reportAs value to the total list of counters. /// /// Name of the performance counter. - /// Report as name for the performance counter. - /// Boolean to check if the performance counter is custom defined. + /// Report as name for the performance counter. /// Captures the error logged. /// Boolean that controls the registry of the counter based on the availability of instance place holder. - void RegisterCounter(string perfCounter, string reportAs, bool isCustomCounter, out string error, bool blockCounterWithInstancePlaceHolder); + void RegisterCounter(string perfCounter, string reportAs, out string error, bool blockCounterWithInstancePlaceHolder); /// /// Removes a counter. diff --git a/Src/PerformanceCollector/Perf.Shared/Implementation/PerformanceCollectorEventSource.cs b/Src/PerformanceCollector/Perf.Shared/Implementation/PerformanceCollectorEventSource.cs index 179262ff5..aff827ce3 100644 --- a/Src/PerformanceCollector/Perf.Shared/Implementation/PerformanceCollectorEventSource.cs +++ b/Src/PerformanceCollector/Perf.Shared/Implementation/PerformanceCollectorEventSource.cs @@ -180,8 +180,24 @@ public void PerfCounterNetCoreOnlyOnAzureWebApp(string applicationName = "dummy" this.WriteEvent(21, this.applicationNameProvider.Name); } + [Event(22, Keywords = Keywords.UserActionable, Level = EventLevel.Error, Message = @"Performance counter is not available in the supported list of XPlatform counters. Counter is {0}.")] + public void CounterNotXPlatformSupported( + string counterName, + string applicationName = "dummy") + { + this.WriteEvent(22, counterName, this.applicationNameProvider.Name); + } + + [Event(23, Level = EventLevel.Informational, Message = @"PerformanceCollector is: {0}.")] + public void InitializedWithCollector( + string collectorName, + string applicationName = "dummy") + { + this.WriteEvent(23, collectorName, this.applicationNameProvider.Name); + } + #endregion - + public class Keywords { public const EventKeywords UserActionable = (EventKeywords)0x1; diff --git a/Src/PerformanceCollector/Perf.Shared/Implementation/PerformanceCounterData.cs b/Src/PerformanceCollector/Perf.Shared/Implementation/PerformanceCounterData.cs index 2487c70ee..894513ce6 100644 --- a/Src/PerformanceCollector/Perf.Shared/Implementation/PerformanceCounterData.cs +++ b/Src/PerformanceCollector/Perf.Shared/Implementation/PerformanceCounterData.cs @@ -6,7 +6,6 @@ public PerformanceCounterData( string originalString, string reportAs, bool usesInstanceNamePlaceholder, - bool isCustomCounter, bool isInBadState, string categoryName, string counterName, @@ -15,7 +14,6 @@ public PerformanceCounterData( this.OriginalString = originalString; this.ReportAs = reportAs; this.UsesInstanceNamePlaceholder = usesInstanceNamePlaceholder; - this.IsCustomCounter = isCustomCounter; this.IsInBadState = isInBadState; this.PerformanceCounter = new PerformanceCounterStructure(categoryName, counterName, instanceName); } @@ -24,14 +22,12 @@ public PerformanceCounterData( string originalString, string reportAs, bool usesInstanceNamePlaceholder, - bool isCustomCounter, bool isInBadState, PerformanceCounterStructure counter) { this.OriginalString = originalString; this.ReportAs = reportAs; this.UsesInstanceNamePlaceholder = usesInstanceNamePlaceholder; - this.IsCustomCounter = isCustomCounter; this.IsInBadState = isInBadState; this.PerformanceCounter = counter; } @@ -44,8 +40,6 @@ public PerformanceCounterData( public bool UsesInstanceNamePlaceholder { get; private set; } - public bool IsCustomCounter { get; private set; } - public bool IsInBadState { get; private set; } } } diff --git a/Src/PerformanceCollector/Perf.Shared/Implementation/PerformanceCounterUtility.cs b/Src/PerformanceCollector/Perf.Shared/Implementation/PerformanceCounterUtility.cs index 224ec335c..db92525cd 100644 --- a/Src/PerformanceCollector/Perf.Shared/Implementation/PerformanceCounterUtility.cs +++ b/Src/PerformanceCollector/Perf.Shared/Implementation/PerformanceCounterUtility.cs @@ -8,14 +8,27 @@ using System.Globalization; using System.Linq; using System.Reflection; + using System.Runtime.InteropServices; using System.Text.RegularExpressions; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.StandardPerfCollector; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector; +#if NETSTANDARD2_0 + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.XPlatform; +#endif /// /// Utility functionality for performance counter collection. /// - [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Justification = "This class has different code for Net45/NetCore")] + [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Justification = + "This class has different code for Net45/NetCore")] internal static class PerformanceCounterUtility { +#if NETSTANDARD2_0 + public static bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); +#endif + // Internal for testing + internal static bool? isAzureWebApp = null; + private const string Win32ProcessInstancePlaceholder = @"APP_WIN32_PROC"; private const string ClrProcessInstancePlaceholder = @"APP_CLR_PROC"; private const string W3SvcProcessInstancePlaceholder = @"APP_W3SVC_PROC"; @@ -23,7 +36,7 @@ internal static class PerformanceCounterUtility private const string Win32ProcessCategoryName = "Process"; private const string ClrProcessCategoryName = ".NET CLR Memory"; private const string Win32ProcessCounterName = "ID Process"; - private const string ClrProcessCounterName = "Process ID"; + private const string ClrProcessCounterName = "Process ID"; #if NETSTANDARD2_0 private const string StandardSdkVersionPrefix = "pccore:"; #else @@ -35,7 +48,8 @@ internal static class PerformanceCounterUtility private const string WebSiteEnvironmentVariable = "WEBSITE_SITE_NAME"; private const string ProcessorsCountEnvironmentVariable = "NUMBER_OF_PROCESSORS"; - private static readonly ConcurrentDictionary PlaceholderCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary PlaceholderCache = + new ConcurrentDictionary(); private static readonly Regex InstancePlaceholderRegex = new Regex( @"^\?\?(?[a-zA-Z0-9_]+)\?\?$", @@ -46,8 +60,6 @@ internal static class PerformanceCounterUtility @"^\\(?[^(]+)(\((?[^)]+)\)){0,1}\\(?[\s\S]+)$", RegexOptions.Compiled); - private static bool? isAzureWebApp = null; - #if !NETSTANDARD1_6 /// /// Formats a counter into a readable string. @@ -58,6 +70,91 @@ public static string FormatPerformanceCounter(PerformanceCounter pc) } #endif + public static bool IsPerfCounterSupported() + { +#if NETSTANDARD1_6 + // PerfCounter is limited to only when running in WebApp + return IsWebAppRunningInAzure(); +#else + return true; +#endif + } + +#if NETSTANDARD1_6 + public static IPerformanceCollector GetPerformanceCollector() + { + IPerformanceCollector collector; + + // NetStandard1.6 has perf counter only on web apps. + + if (PerformanceCounterUtility.IsWebAppRunningInAzure()) + { + collector = (IPerformanceCollector)new WebAppPerformanceCollector(); + PerformanceCollectorEventSource.Log.InitializedWithCollector(collector.GetType().Name); + } + else + { + // This will be the Stub collector which won't do anything. + collector = (IPerformanceCollector)new StandardPerformanceCollectorStub(); + PerformanceCollectorEventSource.Log.InitializedWithCollector(collector.GetType().Name); + } + + return collector; + } +#elif NET45 + public static IPerformanceCollector GetPerformanceCollector() + { + IPerformanceCollector collector; + if (PerformanceCounterUtility.IsWebAppRunningInAzure()) + { + collector = (IPerformanceCollector)new WebAppPerfCollector.WebAppPerformanceCollector(); + PerformanceCollectorEventSource.Log.InitializedWithCollector(collector.GetType().Name); + } + else + { + collector = (IPerformanceCollector)new StandardPerformanceCollector(); + PerformanceCollectorEventSource.Log.InitializedWithCollector(collector.GetType().Name); + } + + return collector; + } +#elif NETSTANDARD2_0 + public static IPerformanceCollector GetPerformanceCollector() + { + IPerformanceCollector collector; + if (PerformanceCounterUtility.IsWebAppRunningInAzure()) + { + if (PerformanceCounterUtility.IsWindows) + { + // WebApp For windows + collector = (IPerformanceCollector)new WebAppPerformanceCollector(); + PerformanceCollectorEventSource.Log.InitializedWithCollector(collector.GetType().Name); + } + else + { + // We are in WebApp, but not Windows. Use XPlatformPerfCollector. + collector = (IPerformanceCollector)new PerformanceCollectorXPlatform(); + PerformanceCollectorEventSource.Log.InitializedWithCollector(collector.GetType().Name); + } + } + else if (PerformanceCounterUtility.IsWindows) + { + // The original Windows PerformanceCounter collector which is also + // supported in NetStandard2.0 in Windows. + collector = (IPerformanceCollector)new StandardPerformanceCollector(); + PerformanceCollectorEventSource.Log.InitializedWithCollector(collector.GetType().Name); + } + else + { + // This is NetStandard2.0 and non-windows. Use XPlatformPerfCollector + collector = (IPerformanceCollector)new PerformanceCollectorXPlatform(); + PerformanceCollectorEventSource.Log.InitializedWithCollector(collector.GetType().Name); + } + + return collector; + } +#endif + /// /// Formats a counter into a readable string. /// @@ -92,34 +189,18 @@ public static bool IsWebAppRunningInAzure() /// /// Gets the processor count from the appropriate environment variable depending on whether the app is a WebApp or not. /// - /// Indicates whether the application is a WebApp or not. /// The number of processors in the system or null if failed to determine. - public static int? GetProcessorCount(bool isWebApp) + public static int? GetProcessorCount() { int count; - - if (!isWebApp) + try { count = Environment.ProcessorCount; } - else + catch (Exception ex) { - string countString; - try - { - countString = Environment.GetEnvironmentVariable(ProcessorsCountEnvironmentVariable); - } - catch (Exception ex) - { - PerformanceCollectorEventSource.Log.ProcessorsCountIncorrectValueError(ex.ToString()); - return null; - } - - if (!int.TryParse(countString, out count)) - { - PerformanceCollectorEventSource.Log.ProcessorsCountIncorrectValueError(countString); - return null; - } + PerformanceCollectorEventSource.Log.ProcessorsCountIncorrectValueError(ex.ToString()); + return null; } if (count < 1 || count > 1000) @@ -143,7 +224,7 @@ public static string SDKVersionPrefix() return AzureWebAppCoreSdkVersionPrefix; #else return AzureWebAppSdkVersionPrefix; -#endif +#endif } else { @@ -175,6 +256,7 @@ public static string FormatPerformanceCounter(string categoryName, string counte /// Performance counter name to validate. /// Windows 32 instances. /// CLR instances. + /// Boolean indicating if InstanceNames are supported. For WebApp and XPlatform counters, counters are always read from own process instance. /// Boolean to check if it is using an instance name place holder. /// Error message. /// Performance counter. @@ -182,6 +264,7 @@ public static PerformanceCounterStructure CreateAndValidateCounter( string perfCounterName, IEnumerable win32Instances, IEnumerable clrInstances, + bool supportInstanceNames, out bool usesInstanceNamePlaceholder, out string error) { @@ -193,6 +276,7 @@ public static PerformanceCounterStructure CreateAndValidateCounter( perfCounterName, win32Instances, clrInstances, + supportInstanceNames, out usesInstanceNamePlaceholder); } catch (Exception e) @@ -213,6 +297,7 @@ public static PerformanceCounterStructure ParsePerformanceCounter( string performanceCounter, IEnumerable win32Instances, IEnumerable clrInstances, + bool supportInstanceNames, out bool usesInstanceNamePlaceholder) { var match = PerformanceCounterRegex.Match(performanceCounter); @@ -235,6 +320,7 @@ public static PerformanceCounterStructure ParsePerformanceCounter( match.Groups["instanceName"].Value, win32Instances, clrInstances, + supportInstanceNames, out usesInstanceNamePlaceholder), CounterName = match.Groups["counterName"].Value, }; @@ -334,8 +420,15 @@ private static string ExpandInstanceName( string instanceName, IEnumerable win32Instances, IEnumerable clrInstances, + bool supportInstanceNames, out bool usesPlaceholder) { + if (!supportInstanceNames) + { + usesPlaceholder = false; + return instanceName; + } + var match = MatchInstancePlaceholder(instanceName); if (match == null) { @@ -346,11 +439,6 @@ private static string ExpandInstanceName( usesPlaceholder = true; - if (IsWebAppRunningInAzure()) - { - return instanceName; - } - var placeholder = match.Groups["placeholder"].Value; // use a cached value if available diff --git a/Src/PerformanceCollector/Perf.Shared/Implementation/QuickPulse/Helpers/QuickPulseDefaults.cs b/Src/PerformanceCollector/Perf.Shared/Implementation/QuickPulse/Helpers/QuickPulseDefaults.cs index 1e92fe8f9..a368eafb5 100644 --- a/Src/PerformanceCollector/Perf.Shared/Implementation/QuickPulse/Helpers/QuickPulseDefaults.cs +++ b/Src/PerformanceCollector/Perf.Shared/Implementation/QuickPulse/Helpers/QuickPulseDefaults.cs @@ -38,7 +38,26 @@ public static Dictionary DefaultCountersToCollect { get { - return PerformanceCounterUtility.IsWebAppRunningInAzure() ? WebAppDefaultPerformanceCountersToCollect : DefaultPerformanceCountersToCollect; + if (PerformanceCounterUtility.IsWebAppRunningInAzure()) + { + return WebAppDefaultPerformanceCountersToCollect; + } + else + { +#if NETSTANDARD2_0 + if (PerformanceCounterUtility.IsWindows) + { + return DefaultPerformanceCountersToCollect; + } + else + { + return WebAppDefaultPerformanceCountersToCollect; + } +#else + return DefaultPerformanceCountersToCollect; +#endif + + } } } diff --git a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/AzureWebEnvironmentVariables.cs b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/AzureWebEnvironmentVariables.cs index 98e2cef61..1888b6fa8 100644 --- a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/AzureWebEnvironmentVariables.cs +++ b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/AzureWebEnvironmentVariables.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector { using System; diff --git a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/CPUPercenageGauge.cs b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/CPUPercenageGauge.cs index 44a0250cc..a32e30273 100644 --- a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/CPUPercenageGauge.cs +++ b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/CPUPercenageGauge.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector { using System; @@ -33,19 +33,19 @@ public CPUPercenageGauge(string name, ICounterValue value) /// Returns the percentage of the CPU process utilization time with respect to the total duration. /// /// The value of the target metric. - public double GetValueAndReset() + public double Collect() { - return this.Collect(); + return this.CollectPercentage(); } /// /// Returns the percentage of the CPU process utilization time with respect to the total duration. /// /// The value of the target metric. - protected virtual double Collect() + protected virtual double CollectPercentage() { double previouslyCollectedValue = this.lastCollectedValue; - this.lastCollectedValue = this.valueProvider.GetValueAndReset(); + this.lastCollectedValue = this.valueProvider.Collect(); var previouslyCollectedTime = this.lastCollectedTime; this.lastCollectedTime = DateTimeOffset.UtcNow; diff --git a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/CacheHelper.cs b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/CacheHelper.cs index a4ede25ad..c2b87c6ff 100644 --- a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/CacheHelper.cs +++ b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/CacheHelper.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector { using System; using System.Collections.Generic; diff --git a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/CounterFactory.cs b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/CounterFactory.cs index 050f938f9..6aa0b19bc 100644 --- a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/CounterFactory.cs +++ b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/CounterFactory.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector { using System; diff --git a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/ICachedEnvironmentVariableAccess.cs b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/ICachedEnvironmentVariableAccess.cs index 7403690e6..08ad5c69e 100644 --- a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/ICachedEnvironmentVariableAccess.cs +++ b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/ICachedEnvironmentVariableAccess.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector { /// /// Interface for classes that implement a CacheHelper. diff --git a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/ICounterValue.cs b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/ICounterValue.cs deleted file mode 100644 index 164bd9645..000000000 --- a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/ICounterValue.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector -{ - using Microsoft.ApplicationInsights.DataContracts; - - /// - /// Interface represents the counter value. - /// - internal interface ICounterValue - { - /// - /// Returns the current value of the counter as a and resets the metric. - /// - /// Value of the counter. - double GetValueAndReset(); - } -} diff --git a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/NormalizedCPUPercentageGauge.cs b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/NormalizedCPUPercentageGauge.cs index 354ddf941..d0ac59d37 100644 --- a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/NormalizedCPUPercentageGauge.cs +++ b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/NormalizedCPUPercentageGauge.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector { using System; using System.Globalization; @@ -18,7 +18,7 @@ internal class NormalizedCPUPercentageGauge : CPUPercenageGauge /// Gauges to sum. public NormalizedCPUPercentageGauge(string name, ICounterValue value) : base(name, value) { - int? count = PerformanceCounterUtility.GetProcessorCount(true); + int? count = PerformanceCounterUtility.GetProcessorCount(); if (count.HasValue) { @@ -31,7 +31,7 @@ public NormalizedCPUPercentageGauge(string name, ICounterValue value) : base(nam /// Returns the normalized percentage of the CPU process utilization time divided by the number of processors with respect to the total duration. /// /// The value of the target metric. - protected override double Collect() + protected override double CollectPercentage() { if (!this.isInitialized) { @@ -41,7 +41,7 @@ protected override double Collect() double result = 0; if (this.processorsCount >= 1) { - double value = base.Collect(); + double value = base.CollectPercentage(); result = value / this.processorsCount; } diff --git a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/PerformanceCounterImplementation.cs b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/PerformanceCounterImplementation.cs index c17af3dcf..d5d507f1f 100644 --- a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/PerformanceCounterImplementation.cs +++ b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/PerformanceCounterImplementation.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector { using System; using System.Collections.Generic; diff --git a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/RateCounterGauge.cs b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/RateCounterGauge.cs index 32f896e74..341358485 100644 --- a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/RateCounterGauge.cs +++ b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/RateCounterGauge.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector { using System; using System.Globalization; @@ -71,10 +71,10 @@ internal RateCounterGauge(string name, string jsonId, AzureWebApEnvironmentVaria /// Computes the rate of a specific counter by tracking the last collected time and value. /// /// The value of the target metric. - public double GetValueAndReset() + public double Collect() { double previouslyCollectedValue = this.lastValue; - this.lastValue = (this.counter == null) ? this.cacheHelper.GetCounterValue(this.jsonId, this.environmentVariable) : this.counter.GetValueAndReset(); + this.lastValue = (this.counter == null) ? this.cacheHelper.GetCounterValue(this.jsonId, this.environmentVariable) : this.counter.Collect(); var previouslyCollectedTime = this.lastCollectedTime; this.lastCollectedTime = DateTimeOffset.UtcNow; diff --git a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/RatioCounterGauge.cs b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/RatioCounterGauge.cs index 046596707..b3215ecb2 100644 --- a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/RatioCounterGauge.cs +++ b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/RatioCounterGauge.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector { /// /// Gauge that computes the ratio of two different gauges. @@ -44,12 +44,12 @@ public RatioCounterGauge(string name, ICounterValue numeratorGauge, ICounterValu /// Returns the current value of the sum of all different gauges attached to this one and resets their values. /// /// The value of the target metric. - public double GetValueAndReset() + public double Collect() { if ((this.numeratorGauge != null) && (this.denominatorGauge != null)) { - double denominatorValue = this.denominatorGauge.GetValueAndReset(); - return (denominatorValue == 0) ? 0 : (this.numeratorGauge.GetValueAndReset() / denominatorValue) * this.scale; + double denominatorValue = this.denominatorGauge.Collect(); + return (denominatorValue == 0) ? 0 : (this.numeratorGauge.Collect() / denominatorValue) * this.scale; } return 0; diff --git a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/RawCounterGauge.cs b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/RawCounterGauge.cs index 0a59abd2c..5be945128 100644 --- a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/RawCounterGauge.cs +++ b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/RawCounterGauge.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector { using Microsoft.ApplicationInsights.DataContracts; @@ -47,7 +47,7 @@ internal RawCounterGauge(string name, string jsonId, AzureWebApEnvironmentVariab /// Returns the current value of the counter as a and resets the metric. /// /// The value of the target metric. - public double GetValueAndReset() + public double Collect() { return this.cacheHelper.GetCounterValue(this.jsonId, this.environmentVariable); } diff --git a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/SumUpCountersGauge.cs b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/SumUpCountersGauge.cs index 7f11b2540..e3e3ec670 100644 --- a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/SumUpCountersGauge.cs +++ b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/SumUpCountersGauge.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector { using System.Collections.Generic; using System.Linq; @@ -35,9 +35,9 @@ public SumUpCountersGauge(string name, params ICounterValue[] gauges) /// Returns the current value of the sum of all different gauges attached to this one and resets their values. /// /// The value of the target metric. - public double GetValueAndReset() + public double Collect() { - return this.gaugesToSum.Sum((g) => { return g.GetValueAndReset(); }); + return this.gaugesToSum.Sum((g) => { return g.Collect(); }); } } } diff --git a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/WebAppPerformanceCollector.cs b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/WebAppPerformanceCollector.cs index 4556353ef..159326ab6 100644 --- a/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/WebAppPerformanceCollector.cs +++ b/Src/PerformanceCollector/Perf.Shared/Implementation/WebAppPerformanceCollector/WebAppPerformanceCollector.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector +namespace Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector { using System; using System.Collections.Generic; @@ -64,29 +64,27 @@ public void RefreshCounters() /// /// Name of the performance counter. /// Report as name for the performance counter. - /// Boolean to check if the performance counter is custom defined. /// Captures the error logged. /// Boolean that controls the registry of the counter based on the availability of instance place holder. public void RegisterCounter( string perfCounter, string reportAs, - bool isCustomCounter, out string error, bool blockCounterWithInstancePlaceHolder) { try { bool useInstancePlaceHolder = false; - var pc = PerformanceCounterUtility.CreateAndValidateCounter(perfCounter, null, null, out useInstancePlaceHolder, out error); - + var pc = PerformanceCounterUtility.CreateAndValidateCounter(perfCounter, null, null, false, out useInstancePlaceHolder, out error); + if (pc != null) { - this.RegisterPerformanceCounter(perfCounter, GetCounterReportAsName(perfCounter, reportAs), pc.CategoryName, pc.CounterName, pc.InstanceName, useInstancePlaceHolder, false); + this.RegisterPerformanceCounter(perfCounter, GetCounterReportAsName(perfCounter, reportAs), pc.CategoryName, pc.CounterName, pc.InstanceName, useInstancePlaceHolder); } else { // Even if validation failed, we might still be able to collect perf counter in WebApp. - this.RegisterPerformanceCounter(perfCounter, GetCounterReportAsName(perfCounter, reportAs), string.Empty, perfCounter, string.Empty, useInstancePlaceHolder, false); + this.RegisterPerformanceCounter(perfCounter, GetCounterReportAsName(perfCounter, reportAs), string.Empty, perfCounter, string.Empty, useInstancePlaceHolder); } } catch (Exception e) @@ -134,8 +132,7 @@ public void RefreshPerformanceCounter(PerformanceCounterData pcd) pcd.PerformanceCounter.CategoryName, pcd.PerformanceCounter.CounterName, pcd.PerformanceCounter.InstanceName, - pcd.UsesInstanceNamePlaceholder, - pcd.IsCustomCounter); + pcd.UsesInstanceNamePlaceholder); } /// @@ -145,7 +142,7 @@ private static double CollectCounter(string coutnerOriginalString, ICounterValue { try { - return counter.GetValueAndReset(); + return counter.Collect(); } catch (Exception e) { @@ -172,7 +169,7 @@ private static string GetCounterReportAsName(string counterName, string reportAs /// /// Register a performance counter for collection. /// - private void RegisterPerformanceCounter(string originalString, string reportAs, string categoryName, string counterName, string instanceName, bool usesInstanceNamePlaceholder, bool isCustomCounter) + private void RegisterPerformanceCounter(string originalString, string reportAs, string categoryName, string counterName, string instanceName, bool usesInstanceNamePlaceholder) { ICounterValue counter = null; @@ -192,7 +189,7 @@ private void RegisterPerformanceCounter(string originalString, string reportAs, { // perform the first read. For many counters the first read will always return 0 // since a single sample is not enough to calculate a value - var value = counter.GetValueAndReset(); + var value = counter.Collect(); firstReadOk = true; } catch (Exception e) @@ -210,7 +207,6 @@ private void RegisterPerformanceCounter(string originalString, string reportAs, originalString, reportAs, usesInstanceNamePlaceholder, - isCustomCounter, !firstReadOk, categoryName, counterName, diff --git a/Src/PerformanceCollector/Perf.Shared/Perf.Shared.projitems b/Src/PerformanceCollector/Perf.Shared/Perf.Shared.projitems index 55ed4c216..c9c30f9cc 100644 --- a/Src/PerformanceCollector/Perf.Shared/Perf.Shared.projitems +++ b/Src/PerformanceCollector/Perf.Shared/Perf.Shared.projitems @@ -61,7 +61,7 @@ - + diff --git a/Src/PerformanceCollector/Perf.Shared/PerformanceCollectorModule.cs b/Src/PerformanceCollector/Perf.Shared/PerformanceCollectorModule.cs index 0da45a0ed..313a421b0 100644 --- a/Src/PerformanceCollector/Perf.Shared/PerformanceCollectorModule.cs +++ b/Src/PerformanceCollector/Perf.Shared/PerformanceCollectorModule.cs @@ -13,8 +13,8 @@ using Microsoft.ApplicationInsights.Extensibility.Implementation; using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing; using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation; - using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.StandardPerformanceCollector; - using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.StandardPerfCollector; + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerfCollector; using Timer = Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.Timer.Timer; @@ -80,8 +80,7 @@ public PerformanceCollectorModule() { this.Counters = new List(); - this.collector = this.collector ?? (PerformanceCounterUtility.IsWebAppRunningInAzure() ? - (IPerformanceCollector)new WebAppPerformanceCollector() : (IPerformanceCollector)new StandardPerformanceCollector()); + this.collector = PerformanceCounterUtility.GetPerformanceCollector(); } /// @@ -155,19 +154,28 @@ public void Initialize(TelemetryConfiguration configuration) if (!this.defaultCountersInitialized) { + // The following are the counters support in all cases. this.DefaultCounters.Add(new PerformanceCounterCollectionRequest(@"\Process(??APP_WIN32_PROC??)\% Processor Time", @"\Process(??APP_WIN32_PROC??)\% Processor Time")); this.DefaultCounters.Add(new PerformanceCounterCollectionRequest(@"\Process(??APP_WIN32_PROC??)\% Processor Time Normalized", @"\Process(??APP_WIN32_PROC??)\% Processor Time Normalized")); - this.DefaultCounters.Add(new PerformanceCounterCollectionRequest(@"\Memory\Available Bytes", @"\Memory\Available Bytes")); -#if !NETSTANDARD2_0 // Exclude those counters which don't exist for .netcore + this.DefaultCounters.Add(new PerformanceCounterCollectionRequest(@"\Process(??APP_WIN32_PROC??)\Private Bytes", @"\Process(??APP_WIN32_PROC??)\Private Bytes")); + +#if NET45 // The following are Asp.Net specific counters. this.DefaultCounters.Add(new PerformanceCounterCollectionRequest(@"\ASP.NET Applications(??APP_W3SVC_PROC??)\Requests/Sec", @"\ASP.NET Applications(??APP_W3SVC_PROC??)\Requests/Sec")); this.DefaultCounters.Add(new PerformanceCounterCollectionRequest(@"\.NET CLR Exceptions(??APP_CLR_PROC??)\# of Exceps Thrown / sec", @"\.NET CLR Exceptions(??APP_CLR_PROC??)\# of Exceps Thrown / sec")); this.DefaultCounters.Add(new PerformanceCounterCollectionRequest(@"\ASP.NET Applications(??APP_W3SVC_PROC??)\Request Execution Time", @"\ASP.NET Applications(??APP_W3SVC_PROC??)\Request Execution Time")); this.DefaultCounters.Add(new PerformanceCounterCollectionRequest(@"\ASP.NET Applications(??APP_W3SVC_PROC??)\Requests In Application Queue", @"\ASP.NET Applications(??APP_W3SVC_PROC??)\Requests In Application Queue")); #endif - this.DefaultCounters.Add(new PerformanceCounterCollectionRequest(@"\Process(??APP_WIN32_PROC??)\Private Bytes", @"\Process(??APP_WIN32_PROC??)\Private Bytes")); - this.DefaultCounters.Add(new PerformanceCounterCollectionRequest(@"\Process(??APP_WIN32_PROC??)\IO Data Bytes/sec", @"\Process(??APP_WIN32_PROC??)\IO Data Bytes/sec")); - if (!PerformanceCounterUtility.IsWebAppRunningInAzure()) + + if (this.collector.GetType().Name.Equals("WebAppPerformanceCollector", StringComparison.OrdinalIgnoreCase) || this.collector.GetType().Name.Equals("StandardPerformanceCollector", StringComparison.OrdinalIgnoreCase)) + { + // The systemwide Memory counter is enabled in WebApps. + this.DefaultCounters.Add(new PerformanceCounterCollectionRequest(@"\Memory\Available Bytes", @"\Memory\Available Bytes")); + this.DefaultCounters.Add(new PerformanceCounterCollectionRequest(@"\Process(??APP_WIN32_PROC??)\IO Data Bytes/sec", @"\Process(??APP_WIN32_PROC??)\IO Data Bytes/sec")); + } + + if (this.collector.GetType().Name.Equals("StandardPerformanceCollector", StringComparison.OrdinalIgnoreCase)) { + // Only time total CPU counter is available is if we are using StandardPerformanceCollector. this.DefaultCounters.Add(new PerformanceCounterCollectionRequest(@"\Processor(_Total)\% Processor Time", @"\Processor(_Total)\% Processor Time")); } } @@ -327,7 +335,6 @@ private void EnsurePerformanceCountersRegistered() this.collector.RegisterCounter( req.PerformanceCounter, req.ReportAs, - true, out error, false); diff --git a/Src/PerformanceCollector/Perf.Shared/QuickPulseTelemetryModule.cs b/Src/PerformanceCollector/Perf.Shared/QuickPulseTelemetryModule.cs index 95698c147..0154c3da1 100644 --- a/Src/PerformanceCollector/Perf.Shared/QuickPulseTelemetryModule.cs +++ b/Src/PerformanceCollector/Perf.Shared/QuickPulseTelemetryModule.cs @@ -17,8 +17,9 @@ using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.QuickPulse; using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.QuickPulse.Helpers; using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.QuickPulse.PerfLib; - using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.StandardPerformanceCollector; - using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.WebAppPerformanceCollector; +#if NETSTANDARD2_0 + using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.XPlatform; +#endif /// /// Telemetry module for collecting QuickPulse data. @@ -165,8 +166,9 @@ public void Initialize(TelemetryConfiguration configuration) QuickPulseEventSource.Log.TroubleshootingMessageEvent("Initializing members..."); this.collectionTimeSlotManager = this.collectionTimeSlotManager ?? new QuickPulseCollectionTimeSlotManager(); - this.performanceCollector = this.performanceCollector ?? - (PerformanceCounterUtility.IsWebAppRunningInAzure() ? new WebAppPerformanceCollector() : (IPerformanceCollector)new StandardPerformanceCollector()); + + this.performanceCollector = this.performanceCollector ?? PerformanceCounterUtility.GetPerformanceCollector(); + this.timeProvider = this.timeProvider ?? new Clock(); this.topCpuCollector = this.topCpuCollector ?? new QuickPulseTopCpuCollector(this.timeProvider, new QuickPulseProcessProvider(PerfLib.GetPerfLib())); @@ -280,7 +282,7 @@ private void UpdatePerformanceCollector(IEnumerable> perfo try { string error; - this.performanceCollector.RegisterCounter(counter.Item2, counter.Item1, true, out error, true); + this.performanceCollector.RegisterCounter(counter.Item2, counter.Item1, out error, true); if (!string.IsNullOrWhiteSpace(error)) { @@ -305,8 +307,7 @@ private void UpdatePerformanceCollector(IEnumerable> perfo string.Format(CultureInfo.InvariantCulture, "Unexpected error processing counter '{0}': {1}", counter, e.Message), e, Tuple.Create("MetricId", counter.Item1))); - - QuickPulseEventSource.Log.CounterRegistrationFailedEvent(e.Message, counter.Item2); + QuickPulseEventSource.Log.CounterRegistrationFailedEvent(e.Message, counter.Item2); } } @@ -357,7 +358,7 @@ private void InitializeServiceClient(TelemetryConfiguration configuration) string machineName = Environment.MachineName; var assemblyVersion = SdkVersionUtils.GetSdkVersion(null); bool isWebApp = PerformanceCounterUtility.IsWebAppRunningInAzure(); - int? processorCount = PerformanceCounterUtility.GetProcessorCount(isWebApp); + int? processorCount = PerformanceCounterUtility.GetProcessorCount(); this.serviceClient = new QuickPulseServiceClient( serviceEndpointUri, instanceName, diff --git a/Src/PerformanceCollector/PerformanceCollector/Perf.csproj b/Src/PerformanceCollector/PerformanceCollector/Perf.csproj index 7318a265c..e6aa03a24 100644 --- a/Src/PerformanceCollector/PerformanceCollector/Perf.csproj +++ b/Src/PerformanceCollector/PerformanceCollector/Perf.csproj @@ -71,10 +71,11 @@ - + +