From 032c5b3554f95b60991d0506cd41a445d546fcef Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Mon, 26 Feb 2024 18:46:44 -0800 Subject: [PATCH 01/13] implement process counters --- .../LiveMetricsExporterEventSource.cs | 9 ++ .../src/Internals/Manager.Metrics.cs | 128 ++++++++++++++---- .../src/Internals/Manager.State.cs | 3 + 3 files changed, 116 insertions(+), 24 deletions(-) diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Diagnostics/LiveMetricsExporterEventSource.cs b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Diagnostics/LiveMetricsExporterEventSource.cs index d23b8b30ac5a..3455f9b68c98 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Diagnostics/LiveMetricsExporterEventSource.cs +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Diagnostics/LiveMetricsExporterEventSource.cs @@ -195,5 +195,14 @@ public void DroppedDocument(DocumentIngressDocumentType documentType) [Event(12, Message = "Document was dropped. DocumentType: {0}. Not user actionable.", Level = EventLevel.Warning)] public void DroppedDocument(string documentType) => WriteEvent(12, documentType); + + [Event(13, Message = "Failure to calculate CPU Counter. Unexpected negative timespan: PreviousCollectedTime: {0}. RecentCollectedTime: {0}. Not user actionable.", Level = EventLevel.Error)] + public void ProcessCountersUnexpectedNegativeTimeSpan(long previousCollectedTime, long recentCollectedTime) => WriteEvent(13, previousCollectedTime, recentCollectedTime); + + [Event(14, Message = "Failure to calculate CPU Counter. Unexpected negative value: PreviousCollectedValue: {0}. RecentCollectedValue: {0}. Not user actionable.", Level = EventLevel.Error)] + public void ProcessCountersUnexpectedNegativeValue(long previousCollectedValue, long recentCollectedValue) => WriteEvent(14, previousCollectedValue, recentCollectedValue); + + [Event(15, Message = "Calculated Cpu Counter: Period: {0}. DiffValue: {1}. CalculatedValue: {2}. ProcessorCount: {3}. NormalizedValue: {4}", Level = EventLevel.Verbose)] + public void ProcessCountersCpuCounter(long period, long diffValue, double calculatedValue, int processorCount, double normalizedValue) => WriteEvent(15, period, diffValue, calculatedValue, processorCount, normalizedValue); } } diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs index a8a0445af6da..0bfb40a37366 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs @@ -18,8 +18,8 @@ internal partial class Manager internal readonly DoubleBuffer _documentBuffer = new(); internal static bool? s_isAzureWebApp = null; - //private readonly PerformanceCounter _performanceCounter_ProcessorTime = new(categoryName: "Processor", counterName: "% Processor Time", instanceName: "_Total"); - //private readonly PerformanceCounter _performanceCounter_CommittedBytes = new(categoryName: "Memory", counterName: "Committed Bytes"); + private DateTimeOffset cachedCollectedTime = DateTimeOffset.MinValue; + private long cachedCollectedValue = 0; public MonitoringDataPoint GetDataPoint() { @@ -91,32 +91,47 @@ public MonitoringDataPoint GetDataPoint() dataPoint.Metrics.Add(metricPoint); } - // TODO: Reenable Perf Counters - //foreach (var metricPoint in CollectPerfCounters()) - //{ - // dataPoint.Metrics.Add(metricPoint); - //} + foreach (var metricPoint in CollectPerfCounters()) + { + dataPoint.Metrics.Add(metricPoint); + } return dataPoint; } - //public IEnumerable CollectPerfCounters() - //{ - // // PERFORMANCE COUNTERS - // yield return new Models.MetricPoint - // { - // Name = LiveMetricConstants.MetricId.MemoryCommittedBytesMetricIdValue, - // Value = _performanceCounter_CommittedBytes.NextValue(), - // Weight = 1 - // }; - - // yield return new Models.MetricPoint - // { - // Name = LiveMetricConstants.MetricId.ProcessorTimeMetricIdValue, - // Value = _performanceCounter_ProcessorTime.NextValue(), - // Weight = 1 - // }; - //} + /// + /// Collect Perf Counters for the current process. + /// + /// + /// For Memory: + /// . + /// "The amount of memory, in bytes, allocated for the associated process that cannot be shared with other processes.". + /// + /// For CPU: + /// . + /// "A TimeSpan that indicates the amount of time that the associated process has spent utilizing the CPU. This value is the sum of the UserProcessorTime and the PrivilegedProcessorTime.". + /// + public IEnumerable CollectPerfCounters() + { + var process = Process.GetCurrentProcess(); + + yield return new Models.MetricPoint + { + Name = LiveMetricConstants.MetricId.MemoryCommittedBytesMetricIdValue, + Value = process.WorkingSet64, + Weight = 1 + }; + + if (TryCalculateCPUCounter(process, out var processorValue)) + { + yield return new Models.MetricPoint + { + Name = LiveMetricConstants.MetricId.ProcessorTimeMetricIdValue, + Value = Convert.ToSingle(processorValue), + Weight = 1 + }; + } + } /// /// Searches for the environment variable specific to Azure Web App. @@ -149,5 +164,70 @@ public MonitoringDataPoint GetDataPoint() return s_isAzureWebApp; } + + private void ResetCachedValues() + { + this.cachedCollectedTime = DateTimeOffset.MinValue; + this.cachedCollectedValue = 0; + } + + /// + /// Calcualte the CPU usage as the diff between two ticks divided by the period of time, and then divided by the number of processors. + /// + private bool TryCalculateCPUCounter(Process process, out double normalizedValue) + { + var previousCollectedValue = this.cachedCollectedValue; + var previousCollectedTime = this.cachedCollectedTime; + + var recentCollectedValue = this.cachedCollectedValue = process.TotalProcessorTime.Ticks; + var recentCollectedTime = this.cachedCollectedTime = DateTimeOffset.UtcNow; + + var processorCount = Environment.ProcessorCount; + + double calculatedValue; + + if (previousCollectedTime == DateTimeOffset.MinValue) + { + Debug.WriteLine($"{nameof(TryCalculateCPUCounter)} DateTimeOffset.MinValue"); + normalizedValue = default; + return false; + } + + var period = recentCollectedTime.Ticks - previousCollectedTime.Ticks; + if (period < 0) + { + // Not likely to happen but being safe here incase of clock issues in multi-core. + LiveMetricsExporterEventSource.Log.ProcessCountersUnexpectedNegativeTimeSpan( + previousCollectedTime: previousCollectedTime.Ticks, + recentCollectedTime: recentCollectedTime.Ticks); + Debug.WriteLine($"{nameof(TryCalculateCPUCounter)} period less than zero"); + normalizedValue = default; + return false; + } + + var diff = recentCollectedValue - previousCollectedValue; + if (diff < 0) + { + LiveMetricsExporterEventSource.Log.ProcessCountersUnexpectedNegativeValue( + previousCollectedValue: previousCollectedValue, + recentCollectedValue: recentCollectedValue); + Debug.WriteLine($"{nameof(TryCalculateCPUCounter)} diff less than zero"); + normalizedValue = default; + return false; + } + + period = period != 0 ? period : 1; + calculatedValue = diff * 100.0 / period; + normalizedValue = calculatedValue / processorCount; + LiveMetricsExporterEventSource.Log.ProcessCountersCpuCounter( + period: previousCollectedValue, + diffValue: recentCollectedValue, + calculatedValue: calculatedValue, + processorCount: processorCount, + normalizedValue: normalizedValue); + // TryCalculateCPUCounter period: 10313304 diff: 64062500 calculatedValue: 621.1636930318354 processorCount: 8 normalizedValue: 77.64546162897942 + Debug.WriteLine($"{nameof(TryCalculateCPUCounter)} period: {period} diff: {diff} calculatedValue: {calculatedValue} processorCount: {processorCount} normalizedValue: {normalizedValue}"); + return true; + } } } diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.State.cs b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.State.cs index 6dbd36ce39c1..ec0068a4d589 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.State.cs +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.State.cs @@ -71,6 +71,9 @@ private void SetPingState() // This is used in determining if we should Backoff. // If we've been in another state for X amount of time, that may exceed our maximum interval and immediately trigger a Backoff. _lastSuccessfulPing = DateTimeOffset.UtcNow; + + // Must reset the metrics cache here. + ResetCachedValues(); } private void SetPostState() From 38bf3f3a83eee996dc489643121bd2a472035cfb Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Mon, 26 Feb 2024 18:48:27 -0800 Subject: [PATCH 02/13] use Demo for testing. REVERT THIS BEFORE MERGING --- ...re.Monitor.OpenTelemetry.AspNetCore.csproj | 6 +-- .../Program.cs | 54 ++++++++++++++++++- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/src/Azure.Monitor.OpenTelemetry.AspNetCore.csproj b/sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/src/Azure.Monitor.OpenTelemetry.AspNetCore.csproj index 362958bcedd1..8578206e1adb 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/src/Azure.Monitor.OpenTelemetry.AspNetCore.csproj +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/src/Azure.Monitor.OpenTelemetry.AspNetCore.csproj @@ -1,4 +1,4 @@ - + An OpenTelemetry .NET distro that exports to Azure Monitor AzureMonitor OpenTelemetry ASP.NET Core Distro @@ -24,11 +24,11 @@ - + - + diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/tests/Azure.Monitor.OpenTelemetry.AspNetCore.Demo/Program.cs b/sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/tests/Azure.Monitor.OpenTelemetry.AspNetCore.Demo/Program.cs index 949139bc44f3..f833d52fa7a2 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/tests/Azure.Monitor.OpenTelemetry.AspNetCore.Demo/Program.cs +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/tests/Azure.Monitor.OpenTelemetry.AspNetCore.Demo/Program.cs @@ -2,16 +2,21 @@ // Licensed under the MIT License. #if NET6_0_OR_GREATER +using System; using System.Diagnostics; using System.Net.Http; +using System.Threading.Tasks; +using System.Threading; using Azure.Monitor.OpenTelemetry.AspNetCore; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); + var builder = WebApplication.CreateBuilder(args); -builder.Services.AddOpenTelemetry().UseAzureMonitor(); +//builder.Services.AddOpenTelemetry().UseAzureMonitor(); /* builder.Services.AddOpenTelemetry().UseAzureMonitor(o => @@ -33,5 +38,52 @@ return $"Hello World! OpenTelemetry Trace: {Activity.Current?.Id}"; }); +#if !NETFRAMEWORK +app.MapGet("/StressTest", () => +{ + RunStressTest(); + return "StressTest!"; +}); +#endif + app.Run(); #endif + +#if !NETFRAMEWORK +void RunStressTest() +{ + // Get the number of available processors + int numProcessors = Environment.ProcessorCount; + + Task[] tasks = new Task[numProcessors]; + + // Start each task + for (int i = 0; i < numProcessors; i++) + { + tasks[i] = Task.Run(() => Compute(cancellationTokenSource.Token)); + } + + var timeStamp = DateTime.Now.AddSeconds(20); + while (DateTime.Now < timeStamp) + { + // do nothing + } + + cancellationTokenSource.Cancel(); + + Task.WaitAll(tasks); +} + +void Compute(CancellationToken cancellationToken) +{ + while (!cancellationToken.IsCancellationRequested) + { + // Simulate intensive computation + double result = 0; + for (int i = 0; i < 1000000; i++) + { + result += Math.Sqrt(i); + } + } +} +#endif From 6d0b95040039998f2f3dffb121d41b6aed5ff6f5 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Mon, 26 Feb 2024 19:22:06 -0800 Subject: [PATCH 03/13] fix typo --- .../src/Internals/Manager.Metrics.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs index 0bfb40a37366..722f14a63198 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs @@ -118,7 +118,7 @@ public MonitoringDataPoint GetDataPoint() yield return new Models.MetricPoint { Name = LiveMetricConstants.MetricId.MemoryCommittedBytesMetricIdValue, - Value = process.WorkingSet64, + Value = process.PrivateMemorySize64, Weight = 1 }; From 3428fdd76eae80300355fcd0815fcdc87082c73d Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 28 Feb 2024 15:02:51 -0800 Subject: [PATCH 04/13] changelog --- .../Azure.Monitor.OpenTelemetry.LiveMetrics/CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/CHANGELOG.md b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/CHANGELOG.md index 9efc46dd03f0..8076349a3090 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/CHANGELOG.md +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/CHANGELOG.md @@ -4,6 +4,9 @@ ### Features Added +- Report Performance Counters "CPU Total" and "Committed Memory". + ([#42213](https://github.com/Azure/azure-sdk-for-net/pull/42213)) + ### Breaking Changes ### Bugs Fixed From e7713bc12f91ab9d67631ea37a5226703156d7fe Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 28 Feb 2024 16:46:03 -0800 Subject: [PATCH 05/13] Revert "use Demo for testing. REVERT THIS BEFORE MERGING" This reverts commit 38bf3f3a83eee996dc489643121bd2a472035cfb. --- ...re.Monitor.OpenTelemetry.AspNetCore.csproj | 6 +-- .../Program.cs | 54 +------------------ 2 files changed, 4 insertions(+), 56 deletions(-) diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/src/Azure.Monitor.OpenTelemetry.AspNetCore.csproj b/sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/src/Azure.Monitor.OpenTelemetry.AspNetCore.csproj index 8578206e1adb..362958bcedd1 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/src/Azure.Monitor.OpenTelemetry.AspNetCore.csproj +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/src/Azure.Monitor.OpenTelemetry.AspNetCore.csproj @@ -1,4 +1,4 @@ - + An OpenTelemetry .NET distro that exports to Azure Monitor AzureMonitor OpenTelemetry ASP.NET Core Distro @@ -24,11 +24,11 @@ - + - + diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/tests/Azure.Monitor.OpenTelemetry.AspNetCore.Demo/Program.cs b/sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/tests/Azure.Monitor.OpenTelemetry.AspNetCore.Demo/Program.cs index f833d52fa7a2..949139bc44f3 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/tests/Azure.Monitor.OpenTelemetry.AspNetCore.Demo/Program.cs +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/tests/Azure.Monitor.OpenTelemetry.AspNetCore.Demo/Program.cs @@ -2,21 +2,16 @@ // Licensed under the MIT License. #if NET6_0_OR_GREATER -using System; using System.Diagnostics; using System.Net.Http; -using System.Threading.Tasks; -using System.Threading; using Azure.Monitor.OpenTelemetry.AspNetCore; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); - var builder = WebApplication.CreateBuilder(args); -//builder.Services.AddOpenTelemetry().UseAzureMonitor(); +builder.Services.AddOpenTelemetry().UseAzureMonitor(); /* builder.Services.AddOpenTelemetry().UseAzureMonitor(o => @@ -38,52 +33,5 @@ return $"Hello World! OpenTelemetry Trace: {Activity.Current?.Id}"; }); -#if !NETFRAMEWORK -app.MapGet("/StressTest", () => -{ - RunStressTest(); - return "StressTest!"; -}); -#endif - app.Run(); #endif - -#if !NETFRAMEWORK -void RunStressTest() -{ - // Get the number of available processors - int numProcessors = Environment.ProcessorCount; - - Task[] tasks = new Task[numProcessors]; - - // Start each task - for (int i = 0; i < numProcessors; i++) - { - tasks[i] = Task.Run(() => Compute(cancellationTokenSource.Token)); - } - - var timeStamp = DateTime.Now.AddSeconds(20); - while (DateTime.Now < timeStamp) - { - // do nothing - } - - cancellationTokenSource.Cancel(); - - Task.WaitAll(tasks); -} - -void Compute(CancellationToken cancellationToken) -{ - while (!cancellationToken.IsCancellationRequested) - { - // Simulate intensive computation - double result = 0; - for (int i = 0; i < 1000000; i++) - { - result += Math.Sqrt(i); - } - } -} -#endif From fc19ebae7dce6b041d027349bf72aab1e5dc1033 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 28 Feb 2024 16:50:29 -0800 Subject: [PATCH 06/13] cleanup --- .../src/Internals/Manager.Metrics.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs index 722f14a63198..7ee479c5a7c2 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs @@ -173,6 +173,7 @@ private void ResetCachedValues() /// /// Calcualte the CPU usage as the diff between two ticks divided by the period of time, and then divided by the number of processors. + /// ((change in ticks / period) / number of processes) /// private bool TryCalculateCPUCounter(Process process, out double normalizedValue) { @@ -225,8 +226,6 @@ private bool TryCalculateCPUCounter(Process process, out double normalizedValue) calculatedValue: calculatedValue, processorCount: processorCount, normalizedValue: normalizedValue); - // TryCalculateCPUCounter period: 10313304 diff: 64062500 calculatedValue: 621.1636930318354 processorCount: 8 normalizedValue: 77.64546162897942 - Debug.WriteLine($"{nameof(TryCalculateCPUCounter)} period: {period} diff: {diff} calculatedValue: {calculatedValue} processorCount: {processorCount} normalizedValue: {normalizedValue}"); return true; } } From 42c6a1aea852cc7eb240de221fd214e15eb8860b Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 28 Feb 2024 16:52:23 -0800 Subject: [PATCH 07/13] update changelog --- .../Azure.Monitor.OpenTelemetry.LiveMetrics/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/CHANGELOG.md b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/CHANGELOG.md index 8076349a3090..0d34019f5f2f 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/CHANGELOG.md +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/CHANGELOG.md @@ -4,7 +4,7 @@ ### Features Added -- Report Performance Counters "CPU Total" and "Committed Memory". +- Report counters "CPU Total" and "Committed Memory". ([#42213](https://github.com/Azure/azure-sdk-for-net/pull/42213)) ### Breaking Changes From d83eb984cab9f26e998afc0c42e469d61fd9f105 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 28 Feb 2024 16:58:44 -0800 Subject: [PATCH 08/13] refactor --- .../src/Internals/Manager.Metrics.cs | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs index 7ee479c5a7c2..1f2f84d0ac7d 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs @@ -18,8 +18,9 @@ internal partial class Manager internal readonly DoubleBuffer _documentBuffer = new(); internal static bool? s_isAzureWebApp = null; - private DateTimeOffset cachedCollectedTime = DateTimeOffset.MinValue; - private long cachedCollectedValue = 0; + private readonly int _processorCount = Environment.ProcessorCount; + private DateTimeOffset _cachedCollectedTime = DateTimeOffset.MinValue; + private long _cachedCollectedValue = 0; public MonitoringDataPoint GetDataPoint() { @@ -167,8 +168,8 @@ public MonitoringDataPoint GetDataPoint() private void ResetCachedValues() { - this.cachedCollectedTime = DateTimeOffset.MinValue; - this.cachedCollectedValue = 0; + _cachedCollectedTime = DateTimeOffset.MinValue; + _cachedCollectedValue = 0; } /// @@ -177,13 +178,11 @@ private void ResetCachedValues() /// private bool TryCalculateCPUCounter(Process process, out double normalizedValue) { - var previousCollectedValue = this.cachedCollectedValue; - var previousCollectedTime = this.cachedCollectedTime; + var previousCollectedValue = _cachedCollectedValue; + var previousCollectedTime = _cachedCollectedTime; - var recentCollectedValue = this.cachedCollectedValue = process.TotalProcessorTime.Ticks; - var recentCollectedTime = this.cachedCollectedTime = DateTimeOffset.UtcNow; - - var processorCount = Environment.ProcessorCount; + var recentCollectedValue = _cachedCollectedValue = process.TotalProcessorTime.Ticks; + var recentCollectedTime = _cachedCollectedTime = DateTimeOffset.UtcNow; double calculatedValue; @@ -219,12 +218,12 @@ private bool TryCalculateCPUCounter(Process process, out double normalizedValue) period = period != 0 ? period : 1; calculatedValue = diff * 100.0 / period; - normalizedValue = calculatedValue / processorCount; + normalizedValue = calculatedValue / _processorCount; LiveMetricsExporterEventSource.Log.ProcessCountersCpuCounter( period: previousCollectedValue, diffValue: recentCollectedValue, calculatedValue: calculatedValue, - processorCount: processorCount, + processorCount: _processorCount, normalizedValue: normalizedValue); return true; } From e49fc51797b46b45f23bc0b006cd861a8829e6a4 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 28 Feb 2024 17:00:21 -0800 Subject: [PATCH 09/13] typo --- .../src/Internals/Manager.Metrics.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs index 1f2f84d0ac7d..cf2b7714e171 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs @@ -174,7 +174,7 @@ private void ResetCachedValues() /// /// Calcualte the CPU usage as the diff between two ticks divided by the period of time, and then divided by the number of processors. - /// ((change in ticks / period) / number of processes) + /// ((change in ticks / period) / number of processors) /// private bool TryCalculateCPUCounter(Process process, out double normalizedValue) { From 32138447671aae04503664cb5dd8438dfb345595 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 28 Feb 2024 17:06:02 -0800 Subject: [PATCH 10/13] rename --- .../src/Internals/Manager.Metrics.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs index cf2b7714e171..ae0c87eca8a6 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs @@ -92,7 +92,7 @@ public MonitoringDataPoint GetDataPoint() dataPoint.Metrics.Add(metricPoint); } - foreach (var metricPoint in CollectPerfCounters()) + foreach (var metricPoint in CollectProcessMetrics()) { dataPoint.Metrics.Add(metricPoint); } @@ -101,7 +101,7 @@ public MonitoringDataPoint GetDataPoint() } /// - /// Collect Perf Counters for the current process. + /// Collect metrics for the current process. /// /// /// For Memory: @@ -112,7 +112,7 @@ public MonitoringDataPoint GetDataPoint() /// . /// "A TimeSpan that indicates the amount of time that the associated process has spent utilizing the CPU. This value is the sum of the UserProcessorTime and the PrivilegedProcessorTime.". /// - public IEnumerable CollectPerfCounters() + public IEnumerable CollectProcessMetrics() { var process = Process.GetCurrentProcess(); From c15cc815f6de7cd612c87713c6eeb92dfd5ce97c Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 28 Feb 2024 17:07:02 -0800 Subject: [PATCH 11/13] changelog --- .../Azure.Monitor.OpenTelemetry.LiveMetrics/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/CHANGELOG.md b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/CHANGELOG.md index 0d34019f5f2f..b63461b97435 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/CHANGELOG.md +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/CHANGELOG.md @@ -4,7 +4,7 @@ ### Features Added -- Report counters "CPU Total" and "Committed Memory". +- Report metrics "CPU Total" and "Committed Memory". ([#42213](https://github.com/Azure/azure-sdk-for-net/pull/42213)) ### Breaking Changes From ac8bb667e06d5bfad6fcf4bfdd1c24112e7f6520 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 28 Feb 2024 17:14:45 -0800 Subject: [PATCH 12/13] rename --- .../src/Internals/LiveMetricConstants.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/LiveMetricConstants.cs b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/LiveMetricConstants.cs index 04047bf254e3..2986e08889c7 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/LiveMetricConstants.cs +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/LiveMetricConstants.cs @@ -27,7 +27,7 @@ internal static class MetricId // EXCEPTIONS internal const string ExceptionsPerSecondMetricIdValue = @"\ApplicationInsights\Exceptions/Sec"; - // PERFORMANCE COUNTERS + // PROCESS METRICS internal const string MemoryCommittedBytesMetricIdValue = @"\Memory\Committed Bytes"; internal const string ProcessorTimeMetricIdValue = @"\Processor(_Total)\% Processor Time"; } From ad7f70fe64ef0f75e5602fb6d3bd7a68a732c110 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Mon, 4 Mar 2024 14:55:52 -0800 Subject: [PATCH 13/13] pr feedback --- .../CHANGELOG.md | 4 +++- .../src/Internals/Manager.Metrics.cs | 19 +++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/CHANGELOG.md b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/CHANGELOG.md index b63461b97435..6d1c654572c9 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/CHANGELOG.md +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/CHANGELOG.md @@ -4,8 +4,10 @@ ### Features Added -- Report metrics "CPU Total" and "Committed Memory". +* Update to report Memory and CPU which are displayed in the Live Metrics UX. ([#42213](https://github.com/Azure/azure-sdk-for-net/pull/42213)) + * For "Committed Memory", we use [Process.PrivateMemorySize64](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.privatememorysize64). + * For "CPU Total (%)", we use the change in [Process.TotalProcessorTime](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.totalprocessortime) over a period of time. This value is normalized by dividing by the number of processors. The formula is `((change in ticks / period) / number of processors)`. ### Breaking Changes diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs index ae0c87eca8a6..fc8343fb6eeb 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs @@ -19,6 +19,7 @@ internal partial class Manager internal static bool? s_isAzureWebApp = null; private readonly int _processorCount = Environment.ProcessorCount; + private readonly Process _process = Process.GetCurrentProcess(); private DateTimeOffset _cachedCollectedTime = DateTimeOffset.MinValue; private long _cachedCollectedValue = 0; @@ -100,30 +101,28 @@ public MonitoringDataPoint GetDataPoint() return dataPoint; } - /// - /// Collect metrics for the current process. - /// /// + /// /// For Memory: /// . /// "The amount of memory, in bytes, allocated for the associated process that cannot be shared with other processes.". - /// + /// + /// /// For CPU: /// . /// "A TimeSpan that indicates the amount of time that the associated process has spent utilizing the CPU. This value is the sum of the UserProcessorTime and the PrivilegedProcessorTime.". + /// /// public IEnumerable CollectProcessMetrics() { - var process = Process.GetCurrentProcess(); - yield return new Models.MetricPoint { Name = LiveMetricConstants.MetricId.MemoryCommittedBytesMetricIdValue, - Value = process.PrivateMemorySize64, + Value = _process.PrivateMemorySize64, Weight = 1 }; - if (TryCalculateCPUCounter(process, out var processorValue)) + if (TryCalculateCPUCounter(out var processorValue)) { yield return new Models.MetricPoint { @@ -176,12 +175,12 @@ private void ResetCachedValues() /// Calcualte the CPU usage as the diff between two ticks divided by the period of time, and then divided by the number of processors. /// ((change in ticks / period) / number of processors) /// - private bool TryCalculateCPUCounter(Process process, out double normalizedValue) + private bool TryCalculateCPUCounter(out double normalizedValue) { var previousCollectedValue = _cachedCollectedValue; var previousCollectedTime = _cachedCollectedTime; - var recentCollectedValue = _cachedCollectedValue = process.TotalProcessorTime.Ticks; + var recentCollectedValue = _cachedCollectedValue = _process.TotalProcessorTime.Ticks; var recentCollectedTime = _cachedCollectedTime = DateTimeOffset.UtcNow; double calculatedValue;