Skip to content

Commit

Permalink
[Instrumentation.Runtime] Add a metric for total paused duration in G…
Browse files Browse the repository at this point in the history
…C for .NET 7 and greater versions (#1239)
  • Loading branch information
xiang17 committed Jun 16, 2023
1 parent 7dcd698 commit 326d071
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

* Add a metric `process.runtime.dotnet.gc.duration` for total paused duration in
GC for .NET 7 and greater versions
([#1239](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1239))

## 1.5.0

Released 2023-Jun-06
Expand Down
16 changes: 16 additions & 0 deletions src/OpenTelemetry.Instrumentation.Runtime/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,22 @@ The API used to retrieve the value is:
* [GCGenerationInfo.FragmentationAfterBytes Property](https://docs.microsoft.com/dotnet/api/system.gcgenerationinfo.fragmentationafterbytes)
Gets the fragmentation in bytes on exit from the reported collection.

#### process.runtime.dotnet.**gc.duration**

The total amount of time paused in GC since the process start.

> **Note**
> This metric is only available when targeting .NET 7 or later.
| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values |
|-------|-------------------|------------|------------------|------------------|
| `ns` | ObservableCounter | `Int64` | No Attributes | N/A |

The API used to retrieve the value is:

* [GC.GetTotalPauseDuration](https://learn.microsoft.com/dotnet/api/system.gc.gettotalpauseduration)
Gets the total amount of time paused in GC since the beginning of the process.

### JIT Compiler related metrics

These metrics are only available when targeting .NET6 or later.
Expand Down
14 changes: 13 additions & 1 deletion src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,9 @@ static RuntimeMetrics()
description: "The heap size (including fragmentation), as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred.");
}

// Not valid until .NET 7 where the bug in the API is fixed. See context in https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/496
if (Environment.Version.Major >= 7)
{
// Not valid until .NET 7 where the bug in the API is fixed. See context in https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/496
MeterInstance.CreateObservableUpDownCounter(
"process.runtime.dotnet.gc.heap.fragmentation.size",
() =>
Expand All @@ -144,6 +144,18 @@ static RuntimeMetrics()
},
unit: "bytes",
description: "The heap fragmentation, as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred.");

// GC.GetTotalPauseDuration() is not available until .NET 7. See context in https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1163
var mi = typeof(GC).GetMethod("GetTotalPauseDuration", BindingFlags.Public | BindingFlags.Static);
var getTotalPauseDuration = mi?.CreateDelegate<Func<TimeSpan>>();
if (getTotalPauseDuration != null)
{
MeterInstance.CreateObservableCounter(
"process.runtime.dotnet.gc.duration",
() => getTotalPauseDuration().Ticks * NanosecondsPerTick,
unit: "ns",
description: "The total amount of time paused in GC since the process start.");
}
}

MeterInstance.CreateObservableCounter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ public void GcMetricsTest()
{
var gcHeapFragmentationSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.heap.fragmentation.size");
Assert.NotNull(gcHeapFragmentationSizeMetric);

var gcDurationMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.duration");
Assert.NotNull(gcDurationMetric);
}
#endif
}
Expand Down

0 comments on commit 326d071

Please sign in to comment.