From f99a56752be5b8196a644af0d6758ff98b8604be Mon Sep 17 00:00:00 2001 From: xiang17 Date: Fri, 15 Jul 2022 14:33:42 -0700 Subject: [PATCH 01/14] Add unit tests --- .../RuntimeMetricsTests.cs | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 6a9b73f107..8a44b4e590 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -15,6 +15,7 @@ // using System.Collections.Generic; +using System.Linq; using OpenTelemetry.Metrics; using Xunit; @@ -37,6 +38,90 @@ public void RuntimeMetricsAreCaptured() meterProvider.ForceFlush(MaxTimeToAllowForFlush); Assert.True(exportedItems.Count > 1); Assert.StartsWith(MetricPrefix, exportedItems[0].Name); + + var gcCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.gc.collections.count"); + var sumReceived = GetLongSum(gcCountMetric); + Assert.True(sumReceived == 0); + +#if NETCOREAPP3_1_OR_GREATER + var gcAllocationSizeMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.gc.allocations.size"); + Assert.True(GetLongSum(gcAllocationSizeMetric) > 0); +#endif + +#if NET6_0_OR_GREATER + Assert.False(exportedItems.Exists(i => i.Name == "process.runtime.dotnet.gc.committed_memory.size")); + Assert.False(exportedItems.Exists(i => i.Name == "process.runtime.dotnet.gc.heap.size")); + + var jitCompiledSizeMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.jit.il_compiled.size"); + Assert.True(GetLongSum(jitCompiledSizeMetric) > 0); + + var jitMethodsCompiledCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.jit.methods_compiled.count"); + Assert.True(GetLongSum(jitMethodsCompiledCountMetric) > 0); + + var jitCompilationTimeMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.jit.compilation_time"); + Assert.True(GetLongSum(jitCompilationTimeMetric) > 0); +#endif + +#if NETCOREAPP3_1_OR_GREATER + var lockContentionCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.monitor.lock_contention.count"); + Assert.True(GetLongSum(lockContentionCountMetric) == 0); + + var threadCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.thread_pool.threads.count"); + Assert.True(GetLongSum(threadCountMetric) > 0); + + var completedItemsCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.thread_pool.completed_items.count"); + Assert.True(GetLongSum(completedItemsCountMetric) > 0); + + var queueLengthMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.thread_pool.queue.length"); + Assert.True(GetLongSum(queueLengthMetric) == 0); + + var timerCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.timer.count"); + Assert.True(GetLongSum(timerCountMetric) > 0); +#endif + + var assembliesCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.assemblies.count"); + Assert.True(GetLongSum(assembliesCountMetric) > 0); + } + +#if NET6_0_OR_GREATER + [Fact] + public void RuntimeMetrics_GcOnlyAvailableAfterFirst() + { + var exportedItems = new List(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddRuntimeInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + + System.GC.Collect(1); + + var gcCommittedMemorySizeMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.gc.committed_memory.size"); + Assert.True(GetLongSum(gcCommittedMemorySizeMetric) > 0); + + var gcHeapSizeMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.gc.heap.size"); + Assert.True(GetLongSum(gcHeapSizeMetric) > 0); + } +#endif + + private static double GetLongSum(Metric metric) + { + double sum = 0; + + foreach (ref readonly var metricPoint in metric.GetMetricPoints()) + { + if (metric.MetricType.IsSum()) + { + sum += metricPoint.GetSumLong(); + } + else + { + sum += metricPoint.GetGaugeLastValueLong(); + } + } + + return sum; } } } From a28050c8a003c10934619fdeae860b6c3d11f02f Mon Sep 17 00:00:00 2001 From: xiang17 Date: Fri, 15 Jul 2022 14:50:02 -0700 Subject: [PATCH 02/14] `monitor.lock_contention.count` can be more than 0 in some tests --- .../RuntimeMetricsTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 8a44b4e590..08ce155383 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -64,7 +64,7 @@ public void RuntimeMetricsAreCaptured() #if NETCOREAPP3_1_OR_GREATER var lockContentionCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.monitor.lock_contention.count"); - Assert.True(GetLongSum(lockContentionCountMetric) == 0); + Assert.True(GetLongSum(lockContentionCountMetric) >= 0); var threadCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.thread_pool.threads.count"); Assert.True(GetLongSum(threadCountMetric) > 0); From 13f4a44d95fe8edbedf853d909709b63279be173 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Mon, 18 Jul 2022 18:36:10 -0700 Subject: [PATCH 03/14] Split into multiple test cases --- .../RuntimeMetricsTests.cs | 87 +++++++++++++------ 1 file changed, 59 insertions(+), 28 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 08ce155383..7da05238b4 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -41,7 +41,7 @@ public void RuntimeMetricsAreCaptured() var gcCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.gc.collections.count"); var sumReceived = GetLongSum(gcCountMetric); - Assert.True(sumReceived == 0); + Assert.True(sumReceived >= 0); #if NETCOREAPP3_1_OR_GREATER var gcAllocationSizeMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.gc.allocations.size"); @@ -49,8 +49,50 @@ public void RuntimeMetricsAreCaptured() #endif #if NET6_0_OR_GREATER - Assert.False(exportedItems.Exists(i => i.Name == "process.runtime.dotnet.gc.committed_memory.size")); - Assert.False(exportedItems.Exists(i => i.Name == "process.runtime.dotnet.gc.heap.size")); + // Supposedly to pass if no garbage collection occurred before. However it did, which is out of control of the code. + //Assert.False(exportedItems.Exists(i => i.Name == "process.runtime.dotnet.gc.committed_memory.size")); + //Assert.False(exportedItems.Exists(i => i.Name == "process.runtime.dotnet.gc.heap.size")); +#endif + + var assembliesCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.assemblies.count"); + Assert.True(GetLongSum(assembliesCountMetric) > 0); + } + +#if NET6_0_OR_GREATER + [Fact] + public void RuntimeMetrics_GcAvailableAfterFirst() + { + var exportedItems = new List(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddRuntimeInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + + System.GC.Collect(1); + + var gcCommittedMemorySizeMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.gc.committed_memory.size"); + Assert.True(GetLongSum(gcCommittedMemorySizeMetric) > 0); + + var gcHeapSizeMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.gc.heap.size"); + Assert.True(GetLongSum(gcHeapSizeMetric) > 0); + } +#endif + +#if NET6_0_OR_GREATER + [Fact] + public void RuntimeMetrics_JitRelatedMetrics() + { + var exportedItems = new List(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddRuntimeInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + Assert.True(exportedItems.Count > 1); + Assert.StartsWith(MetricPrefix, exportedItems[0].Name); var jitCompiledSizeMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.jit.il_compiled.size"); Assert.True(GetLongSum(jitCompiledSizeMetric) > 0); @@ -60,9 +102,23 @@ public void RuntimeMetricsAreCaptured() var jitCompilationTimeMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.jit.compilation_time"); Assert.True(GetLongSum(jitCompilationTimeMetric) > 0); + } #endif #if NETCOREAPP3_1_OR_GREATER + [Fact] + public void RuntimeMetrics_ThreadingRelatedMetrics() + { + var exportedItems = new List(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddRuntimeInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + Assert.True(exportedItems.Count > 1); + Assert.StartsWith(MetricPrefix, exportedItems[0].Name); + var lockContentionCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.monitor.lock_contention.count"); Assert.True(GetLongSum(lockContentionCountMetric) >= 0); @@ -77,31 +133,6 @@ public void RuntimeMetricsAreCaptured() var timerCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.timer.count"); Assert.True(GetLongSum(timerCountMetric) > 0); -#endif - - var assembliesCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.assemblies.count"); - Assert.True(GetLongSum(assembliesCountMetric) > 0); - } - -#if NET6_0_OR_GREATER - [Fact] - public void RuntimeMetrics_GcOnlyAvailableAfterFirst() - { - var exportedItems = new List(); - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddRuntimeInstrumentation() - .AddInMemoryExporter(exportedItems) - .Build(); - - meterProvider.ForceFlush(MaxTimeToAllowForFlush); - - System.GC.Collect(1); - - var gcCommittedMemorySizeMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.gc.committed_memory.size"); - Assert.True(GetLongSum(gcCommittedMemorySizeMetric) > 0); - - var gcHeapSizeMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.gc.heap.size"); - Assert.True(GetLongSum(gcHeapSizeMetric) > 0); } #endif From d69c5c8db399ecc176b6d5377ef51403f0142fb3 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Mon, 18 Jul 2022 18:41:18 -0700 Subject: [PATCH 04/14] Create some timers to validate `timer.count` --- .../RuntimeMetricsTests.cs | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 7da05238b4..746c029b9b 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -16,6 +16,7 @@ using System.Collections.Generic; using System.Linq; +using System.Threading; using OpenTelemetry.Metrics; using Xunit; @@ -49,7 +50,7 @@ public void RuntimeMetricsAreCaptured() #endif #if NET6_0_OR_GREATER - // Supposedly to pass if no garbage collection occurred before. However it did, which is out of control of the code. + // Supposedly to pass if no garbage collection occurred before. However one occurred, which is out of control of the code. //Assert.False(exportedItems.Exists(i => i.Name == "process.runtime.dotnet.gc.committed_memory.size")); //Assert.False(exportedItems.Exists(i => i.Name == "process.runtime.dotnet.gc.heap.size")); #endif @@ -91,8 +92,6 @@ public void RuntimeMetrics_JitRelatedMetrics() .Build(); meterProvider.ForceFlush(MaxTimeToAllowForFlush); - Assert.True(exportedItems.Count > 1); - Assert.StartsWith(MetricPrefix, exportedItems[0].Name); var jitCompiledSizeMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.jit.il_compiled.size"); Assert.True(GetLongSum(jitCompiledSizeMetric) > 0); @@ -116,8 +115,6 @@ public void RuntimeMetrics_ThreadingRelatedMetrics() .Build(); meterProvider.ForceFlush(MaxTimeToAllowForFlush); - Assert.True(exportedItems.Count > 1); - Assert.StartsWith(MetricPrefix, exportedItems[0].Name); var lockContentionCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.monitor.lock_contention.count"); Assert.True(GetLongSum(lockContentionCountMetric) >= 0); @@ -131,8 +128,23 @@ public void RuntimeMetrics_ThreadingRelatedMetrics() var queueLengthMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.thread_pool.queue.length"); Assert.True(GetLongSum(queueLengthMetric) == 0); + // Create 10 timers to bump timer.count metrics. + int timerCount = 10; + TimerCallback timerCallback = _ => { }; + List timers = new List(); + for (int i = 0; i < timerCount; i++) + { + Timer timer = new Timer(timerCallback, null, 1000, 250); + timers.Add(timer); + } + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + var timerCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.timer.count"); - Assert.True(GetLongSum(timerCountMetric) > 0); + Assert.True(GetLongSum(timerCountMetric) >= timerCount); + for (int i = 0; i < timers.Count; i++) + { + timers[i].Dispose(); + } } #endif From fda9b2ea2b9f591ecc60e3519b96c800fcd826de Mon Sep 17 00:00:00 2001 From: xiang17 Date: Mon, 18 Jul 2022 18:45:39 -0700 Subject: [PATCH 05/14] minor change for formatting --- .../RuntimeMetricsTests.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 746c029b9b..7c3dc24b7d 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -51,8 +51,8 @@ public void RuntimeMetricsAreCaptured() #if NET6_0_OR_GREATER // Supposedly to pass if no garbage collection occurred before. However one occurred, which is out of control of the code. - //Assert.False(exportedItems.Exists(i => i.Name == "process.runtime.dotnet.gc.committed_memory.size")); - //Assert.False(exportedItems.Exists(i => i.Name == "process.runtime.dotnet.gc.heap.size")); + // Assert.False(exportedItems.Exists(i => i.Name == "process.runtime.dotnet.gc.committed_memory.size")); + // Assert.False(exportedItems.Exists(i => i.Name == "process.runtime.dotnet.gc.heap.size")); #endif var assembliesCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.assemblies.count"); @@ -137,6 +137,7 @@ public void RuntimeMetrics_ThreadingRelatedMetrics() Timer timer = new Timer(timerCallback, null, 1000, 250); timers.Add(timer); } + meterProvider.ForceFlush(MaxTimeToAllowForFlush); var timerCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.timer.count"); From cde7ec6577ded3e18167859b69ed867849605ed0 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 20 Jul 2022 17:13:56 -0700 Subject: [PATCH 06/14] Remove commented out code for scenario of "before GC occurs" --- .../RuntimeMetricsTests.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 7c3dc24b7d..f426afe813 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -49,12 +49,6 @@ public void RuntimeMetricsAreCaptured() Assert.True(GetLongSum(gcAllocationSizeMetric) > 0); #endif -#if NET6_0_OR_GREATER - // Supposedly to pass if no garbage collection occurred before. However one occurred, which is out of control of the code. - // Assert.False(exportedItems.Exists(i => i.Name == "process.runtime.dotnet.gc.committed_memory.size")); - // Assert.False(exportedItems.Exists(i => i.Name == "process.runtime.dotnet.gc.heap.size")); -#endif - var assembliesCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.assemblies.count"); Assert.True(GetLongSum(assembliesCountMetric) > 0); } From 144297ab6c15190303f7fe114d8a56ed1f7590cb Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 20 Jul 2022 17:14:51 -0700 Subject: [PATCH 07/14] Rename test cases --- .../RuntimeMetricsTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index f426afe813..ec79eb6e26 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -55,7 +55,7 @@ public void RuntimeMetricsAreCaptured() #if NET6_0_OR_GREATER [Fact] - public void RuntimeMetrics_GcAvailableAfterFirst() + public void GcMetricsTest() { var exportedItems = new List(); using var meterProvider = Sdk.CreateMeterProviderBuilder() @@ -77,7 +77,7 @@ public void RuntimeMetrics_GcAvailableAfterFirst() #if NET6_0_OR_GREATER [Fact] - public void RuntimeMetrics_JitRelatedMetrics() + public void JitRelatedMetricsTest() { var exportedItems = new List(); using var meterProvider = Sdk.CreateMeterProviderBuilder() @@ -100,7 +100,7 @@ public void RuntimeMetrics_JitRelatedMetrics() #if NETCOREAPP3_1_OR_GREATER [Fact] - public void RuntimeMetrics_ThreadingRelatedMetrics() + public void ThreadingRelatedMetricsTest() { var exportedItems = new List(); using var meterProvider = Sdk.CreateMeterProviderBuilder() From a15f1abad6f5b70638e8a4b4b681018d818ddb8a Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 20 Jul 2022 17:20:44 -0700 Subject: [PATCH 08/14] Put Timer.Dispose in finally block --- .../RuntimeMetricsTests.cs | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index ec79eb6e26..ba8a1ec1df 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -122,23 +122,29 @@ public void ThreadingRelatedMetricsTest() var queueLengthMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.thread_pool.queue.length"); Assert.True(GetLongSum(queueLengthMetric) == 0); - // Create 10 timers to bump timer.count metrics. - int timerCount = 10; - TimerCallback timerCallback = _ => { }; List timers = new List(); - for (int i = 0; i < timerCount; i++) + try { - Timer timer = new Timer(timerCallback, null, 1000, 250); - timers.Add(timer); - } + // Create 10 timers to bump timer.count metrics. + int timerCount = 10; + TimerCallback timerCallback = _ => { }; + for (int i = 0; i < timerCount; i++) + { + Timer timer = new Timer(timerCallback, null, 1000, 250); + timers.Add(timer); + } - meterProvider.ForceFlush(MaxTimeToAllowForFlush); + meterProvider.ForceFlush(MaxTimeToAllowForFlush); - var timerCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.timer.count"); - Assert.True(GetLongSum(timerCountMetric) >= timerCount); - for (int i = 0; i < timers.Count; i++) + var timerCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.timer.count"); + Assert.True(GetLongSum(timerCountMetric) >= timerCount); + } + finally { - timers[i].Dispose(); + for (int i = 0; i < timers.Count; i++) + { + timers[i].Dispose(); + } } } #endif From e04cd76bc54680b09cf6de193b8668acf161812a Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 20 Jul 2022 18:36:25 -0700 Subject: [PATCH 09/14] Change assert to only check existence of the metrics --- .../RuntimeMetricsTests.cs | 63 ++++++++++--------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index ba8a1ec1df..5fab617d41 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -14,6 +14,7 @@ // limitations under the License. // +using System; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -40,17 +41,8 @@ public void RuntimeMetricsAreCaptured() Assert.True(exportedItems.Count > 1); Assert.StartsWith(MetricPrefix, exportedItems[0].Name); - var gcCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.gc.collections.count"); - var sumReceived = GetLongSum(gcCountMetric); - Assert.True(sumReceived >= 0); - -#if NETCOREAPP3_1_OR_GREATER - var gcAllocationSizeMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.gc.allocations.size"); - Assert.True(GetLongSum(gcAllocationSizeMetric) > 0); -#endif - - var assembliesCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.assemblies.count"); - Assert.True(GetLongSum(assembliesCountMetric) > 0); + var assembliesCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.assemblies.count"); + Assert.NotNull(assembliesCountMetric); } #if NET6_0_OR_GREATER @@ -67,11 +59,19 @@ public void GcMetricsTest() System.GC.Collect(1); - var gcCommittedMemorySizeMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.gc.committed_memory.size"); - Assert.True(GetLongSum(gcCommittedMemorySizeMetric) > 0); + var gcCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.collections.count"); + Assert.NotNull(gcCountMetric); + +#if NETCOREAPP3_1_OR_GREATER + var gcAllocationSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.allocations.size"); + Assert.NotNull(gcAllocationSizeMetric); +#endif + + var gcCommittedMemorySizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.committed_memory.size"); + Assert.NotNull(gcCommittedMemorySizeMetric); - var gcHeapSizeMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.gc.heap.size"); - Assert.True(GetLongSum(gcHeapSizeMetric) > 0); + var gcHeapSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.heap.size"); + Assert.NotNull(gcHeapSizeMetric); } #endif @@ -87,14 +87,14 @@ public void JitRelatedMetricsTest() meterProvider.ForceFlush(MaxTimeToAllowForFlush); - var jitCompiledSizeMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.jit.il_compiled.size"); - Assert.True(GetLongSum(jitCompiledSizeMetric) > 0); + var jitCompiledSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.jit.il_compiled.size"); + Assert.NotNull(jitCompiledSizeMetric); - var jitMethodsCompiledCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.jit.methods_compiled.count"); - Assert.True(GetLongSum(jitMethodsCompiledCountMetric) > 0); + var jitMethodsCompiledCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.jit.methods_compiled.count"); + Assert.NotNull(jitMethodsCompiledCountMetric); - var jitCompilationTimeMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.jit.compilation_time"); - Assert.True(GetLongSum(jitCompilationTimeMetric) > 0); + var jitCompilationTimeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.jit.compilation_time"); + Assert.NotNull(jitCompilationTimeMetric); } #endif @@ -110,17 +110,17 @@ public void ThreadingRelatedMetricsTest() meterProvider.ForceFlush(MaxTimeToAllowForFlush); - var lockContentionCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.monitor.lock_contention.count"); - Assert.True(GetLongSum(lockContentionCountMetric) >= 0); + var lockContentionCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.monitor.lock_contention.count"); + Assert.NotNull(lockContentionCountMetric); - var threadCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.thread_pool.threads.count"); - Assert.True(GetLongSum(threadCountMetric) > 0); + var threadCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.thread_pool.threads.count"); + Assert.NotNull(threadCountMetric); - var completedItemsCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.thread_pool.completed_items.count"); - Assert.True(GetLongSum(completedItemsCountMetric) > 0); + var completedItemsCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.thread_pool.completed_items.count"); + Assert.NotNull(completedItemsCountMetric); - var queueLengthMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.thread_pool.queue.length"); - Assert.True(GetLongSum(queueLengthMetric) == 0); + var queueLengthMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.thread_pool.queue.length"); + Assert.NotNull(queueLengthMetric); List timers = new List(); try @@ -137,7 +137,7 @@ public void ThreadingRelatedMetricsTest() meterProvider.ForceFlush(MaxTimeToAllowForFlush); var timerCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.timer.count"); - Assert.True(GetLongSum(timerCountMetric) >= timerCount); + Assert.True(GetValue(timerCountMetric) >= timerCount); } finally { @@ -149,7 +149,7 @@ public void ThreadingRelatedMetricsTest() } #endif - private static double GetLongSum(Metric metric) + private static double GetValue(Metric metric) { double sum = 0; @@ -162,6 +162,7 @@ private static double GetLongSum(Metric metric) else { sum += metricPoint.GetGaugeLastValueLong(); + break; } } From 93cdbf2a35c225d4f0a35f2b9ad9b77c539a2740 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 20 Jul 2022 18:40:39 -0700 Subject: [PATCH 10/14] Add test for `exceptions.count` --- .../RuntimeMetricsTests.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 5fab617d41..78e8fbd869 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -37,12 +37,25 @@ public void RuntimeMetricsAreCaptured() .AddInMemoryExporter(exportedItems) .Build(); + // The process.runtime.dotnet.exception.count metrics are only available after an exception has been thrown post OpenTelemetry.Instrumentation.Runtime initialization. + try + { + throw new Exception("Oops!"); + } + catch (Exception) + { + // swallow the exception + } + meterProvider.ForceFlush(MaxTimeToAllowForFlush); Assert.True(exportedItems.Count > 1); Assert.StartsWith(MetricPrefix, exportedItems[0].Name); var assembliesCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.assemblies.count"); Assert.NotNull(assembliesCountMetric); + + var exceptionsCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.exceptions.count"); + Assert.True(GetValue(exceptionsCountMetric) >= 1); } #if NET6_0_OR_GREATER From ccbeba91f9e8d77d955b8e967c93ab93abb0a9e6 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 20 Jul 2022 18:40:57 -0700 Subject: [PATCH 11/14] minor change --- .../RuntimeMetricsTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 78e8fbd869..fa7b3a1002 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -149,7 +149,7 @@ public void ThreadingRelatedMetricsTest() meterProvider.ForceFlush(MaxTimeToAllowForFlush); - var timerCountMetric = exportedItems.First(i => i.Name == "process.runtime.dotnet.timer.count"); + var timerCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.timer.count"); Assert.True(GetValue(timerCountMetric) >= timerCount); } finally @@ -164,6 +164,7 @@ public void ThreadingRelatedMetricsTest() private static double GetValue(Metric metric) { + Assert.NotNull(metric); double sum = 0; foreach (ref readonly var metricPoint in metric.GetMetricPoints()) From 81225ac6e7fd96be35dee145b9b603c0ada8406f Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 20 Jul 2022 18:50:31 -0700 Subject: [PATCH 12/14] Run GC before flushing --- .../RuntimeMetricsTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index fa7b3a1002..1089cd95a3 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -68,9 +68,9 @@ public void GcMetricsTest() .AddInMemoryExporter(exportedItems) .Build(); - meterProvider.ForceFlush(MaxTimeToAllowForFlush); + GC.Collect(1); - System.GC.Collect(1); + meterProvider.ForceFlush(MaxTimeToAllowForFlush); var gcCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.collections.count"); Assert.NotNull(gcCountMetric); From e41a15ef9ef2ca4b29164b7e672dcdc9932b3425 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 20 Jul 2022 21:44:03 -0700 Subject: [PATCH 13/14] Adjust NET6_0_OR_GREATER to cover only the applicable metrics entries --- .../RuntimeMetricsTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 1089cd95a3..37954b3554 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -58,7 +58,6 @@ public void RuntimeMetricsAreCaptured() Assert.True(GetValue(exceptionsCountMetric) >= 1); } -#if NET6_0_OR_GREATER [Fact] public void GcMetricsTest() { @@ -80,13 +79,14 @@ public void GcMetricsTest() Assert.NotNull(gcAllocationSizeMetric); #endif +#if NET6_0_OR_GREATER var gcCommittedMemorySizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.committed_memory.size"); Assert.NotNull(gcCommittedMemorySizeMetric); var gcHeapSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.heap.size"); Assert.NotNull(gcHeapSizeMetric); - } #endif + } #if NET6_0_OR_GREATER [Fact] From 7fc56336fcb2e690503a02a16957e1bb5474ff45 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 20 Jul 2022 21:44:35 -0700 Subject: [PATCH 14/14] Add test for `gc.heap.fragmentation.size` for .NET 7 or greater --- .../RuntimeMetricsTests.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 37954b3554..fb205860bd 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -85,6 +85,12 @@ public void GcMetricsTest() var gcHeapSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.heap.size"); Assert.NotNull(gcHeapSizeMetric); + + if (Environment.Version.Major >= 7) + { + var gcHeapFragmentationSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.heap.fragmentation.size"); + Assert.NotNull(gcHeapFragmentationSizeMetric); + } #endif }