Skip to content

Commit

Permalink
[Instrumentation.Process] Exposed required metric process.cpu.count
Browse files Browse the repository at this point in the history
… for computing CPU utilization in the backend. (#981)
  • Loading branch information
Yun-Ting committed Feb 15, 2023
1 parent f88afdb commit c686047
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 7 deletions.
3 changes: 2 additions & 1 deletion src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

## Unreleased

TBD
* Added `process.cpu.count` metric.
([#981](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/981))

## 1.0.0-alpha.6

Expand Down
10 changes: 10 additions & 0 deletions src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#nullable enable

using System;
using System.Collections.Generic;
using System.Diagnostics.Metrics;
using System.Reflection;
Expand Down Expand Up @@ -64,6 +65,15 @@ static ProcessMetrics()
unit: "s",
description: "Total CPU seconds broken down by different states.");

MeterInstance.CreateObservableUpDownCounter(
"process.cpu.count",
() =>
{
return Environment.ProcessorCount;
},
unit: "{processors}",
description: "The number of processors (CPU cores) available to the current process.");

MeterInstance.CreateObservableUpDownCounter(
"process.threads",
() =>
Expand Down
17 changes: 17 additions & 0 deletions src/OpenTelemetry.Instrumentation.Process/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,23 @@ Gets the user processor time for this process.
* [Process.PrivilegedProcessorTime](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.privilegedprocessortime):
Gets the privileged processor time for this process.

### process.cpu.count

The number of processors (CPU cores) available to the current process.

| Units | Instrument Type | Value Type |
|---------------|-------------------------|------------|
| `{processors}`| ObservableUpDownCounter | `Int32` |

The API used to retrieve the value is [System.Environment.ProcessorCount](https://learn.microsoft.com/dotnet/api/system.environment.processorcount).

> **Note**
> This metric is under [discussion][1] and not part of the
[Process Metrics Spec][2] at this time.

[1]: https://github.com/open-telemetry/opentelemetry-specification/issues/3200
[2]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/process-metrics.md

### process.threads

Process threads count.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,16 @@ public void ProcessMetricsAreCaptured()

meterProviderA.ForceFlush(MaxTimeToAllowForFlush);

Assert.True(exportedItemsA.Count == 4);
Assert.True(exportedItemsA.Count == 5);
var physicalMemoryMetric = exportedItemsA.FirstOrDefault(i => i.Name == "process.memory.usage");
Assert.NotNull(physicalMemoryMetric);
var virtualMemoryMetric = exportedItemsA.FirstOrDefault(i => i.Name == "process.memory.virtual");
Assert.NotNull(virtualMemoryMetric);
var cpuTimeMetric = exportedItemsA.FirstOrDefault(i => i.Name == "process.cpu.time");
Assert.NotNull(cpuTimeMetric);
var threadMetric = exportedItemsA.FirstOrDefault(i => i.Name == "process.threads");
var processorCountMetric = exportedItemsA.FirstOrDefault(i => i.Name == "process.cpu.count");
Assert.NotNull(processorCountMetric);
var threadMetric = exportedItemsA.FirstOrDefault(i => i.Name == "process.cpu.count");
Assert.NotNull(threadMetric);

exportedItemsA.Clear();
Expand All @@ -66,8 +68,8 @@ public void ProcessMetricsAreCaptured()

meterProviderB.ForceFlush(MaxTimeToAllowForFlush);

Assert.True(exportedItemsA.Count == 4);
Assert.True(exportedItemsB.Count == 4);
Assert.True(exportedItemsA.Count == 5);
Assert.True(exportedItemsB.Count == 5);
}

[Fact]
Expand Down Expand Up @@ -142,23 +144,27 @@ public void ProcessMetricsAreCapturedWhenTasksOverlap()

Task.WaitAll(tasks.ToArray());

Assert.True(exportedItemsA.Count == 4);
Assert.True(exportedItemsA.Count == 5);
var physicalMemoryMetricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.memory.usage");
Assert.NotNull(physicalMemoryMetricA);
var virtualMemoryMetricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.memory.virtual");
Assert.NotNull(virtualMemoryMetricA);
var cpuTimeMetricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.cpu.time");
Assert.NotNull(cpuTimeMetricA);
var processorCountMetricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.cpu.count");
Assert.NotNull(processorCountMetricA);
var threadMetricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.threads");
Assert.NotNull(threadMetricA);

Assert.True(exportedItemsB.Count == 4);
Assert.True(exportedItemsB.Count == 5);
var physicalMemoryMetricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.memory.usage");
Assert.NotNull(physicalMemoryMetricB);
var virtualMemoryMetricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.memory.virtual");
Assert.NotNull(virtualMemoryMetricB);
var cpuTimeMetricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.cpu.time");
Assert.NotNull(cpuTimeMetricB);
var processorCountMetricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.cpu.count");
Assert.NotNull(processorCountMetricB);
var threadMetricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.threads");
Assert.NotNull(threadMetricB);
}
Expand Down

0 comments on commit c686047

Please sign in to comment.