Skip to content

Commit

Permalink
[repo/Runtime] Prepare to .NET9 (#2281)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kielek authored Nov 4, 2024
1 parent 3649132 commit c732609
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 39 deletions.
53 changes: 24 additions & 29 deletions src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ internal sealed class RuntimeMetrics
#endif
private const int NumberOfGenerations = 3;

private static readonly string[] GenNames = new string[] { "gen0", "gen1", "gen2", "loh", "poh" };
private static readonly string[] GenNames = ["gen0", "gen1", "gen2", "loh", "poh"];
#if NET
private static bool isGcInfoAvailable;
#endif

static RuntimeMetrics()
{
MeterInstance.CreateObservableCounter(
"process.runtime.dotnet.gc.collections.count",
() => GetGarbageCollectionCounts(),
GetGarbageCollectionCounts,
description: "Number of garbage collections that have occurred since process start.");

MeterInstance.CreateObservableUpDownCounter(
Expand All @@ -51,19 +53,14 @@ static RuntimeMetrics()
"process.runtime.dotnet.gc.committed_memory.size",
() =>
{
if (!IsGcInfoAvailable)
{
return Array.Empty<Measurement<long>>();
}

return new Measurement<long>[] { new(GC.GetGCMemoryInfo().TotalCommittedBytes) };
return !IsGcInfoAvailable ? Array.Empty<Measurement<long>>() : [new(GC.GetGCMemoryInfo().TotalCommittedBytes)];
},
unit: "bytes",
description: "The amount of committed virtual memory for the managed GC heap, as observed during the latest garbage collection. Committed virtual memory may be larger than the heap size because it includes both memory for storing existing objects (the heap size) and some extra memory that is ready to handle newly allocated objects in the future. The value will be unavailable until at least one garbage collection has occurred.");

// GC.GetGCMemoryInfo().GenerationInfo[i].SizeAfterBytes is better but it has a bug in .NET 6. See context in https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/496
Func<int, ulong>? getGenerationSize = null;
bool isCodeRunningOnBuggyRuntimeVersion = Environment.Version.Major == 6;
var isCodeRunningOnBuggyRuntimeVersion = Environment.Version.Major == 6;
if (isCodeRunningOnBuggyRuntimeVersion)
{
var mi = typeof(GC).GetMethod("GetGenerationSize", BindingFlags.NonPublic | BindingFlags.Static);
Expand All @@ -82,22 +79,17 @@ static RuntimeMetrics()
{
if (!IsGcInfoAvailable)
{
return Array.Empty<Measurement<long>>();
return [];
}

var generationInfo = GC.GetGCMemoryInfo().GenerationInfo;
Measurement<long>[] measurements = new Measurement<long>[generationInfo.Length];
int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length);
for (int i = 0; i < maxSupportedLength; ++i)
var measurements = new Measurement<long>[generationInfo.Length];
var maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length);
for (var i = 0; i < maxSupportedLength; ++i)
{
if (isCodeRunningOnBuggyRuntimeVersion)
{
measurements[i] = new((long)getGenerationSize!(i), new KeyValuePair<string, object?>("generation", GenNames[i]));
}
else
{
measurements[i] = new(generationInfo[i].SizeAfterBytes, new KeyValuePair<string, object?>("generation", GenNames[i]));
}
measurements[i] = isCodeRunningOnBuggyRuntimeVersion
? new((long)getGenerationSize!(i), new KeyValuePair<string, object?>("generation", GenNames[i]))
: new(generationInfo[i].SizeAfterBytes, new KeyValuePair<string, object?>("generation", GenNames[i]));
}

return measurements;
Expand All @@ -115,13 +107,13 @@ static RuntimeMetrics()
{
if (!IsGcInfoAvailable)
{
return Array.Empty<Measurement<long>>();
return [];
}

var generationInfo = GC.GetGCMemoryInfo().GenerationInfo;
Measurement<long>[] measurements = new Measurement<long>[generationInfo.Length];
int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length);
for (int i = 0; i < maxSupportedLength; ++i)
var measurements = new Measurement<long>[generationInfo.Length];
var maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length);
for (var i = 0; i < maxSupportedLength; ++i)
{
measurements[i] = new(generationInfo[i].FragmentationAfterBytes, new KeyValuePair<string, object?>("generation", GenNames[i]));
}
Expand Down Expand Up @@ -201,15 +193,17 @@ static RuntimeMetrics()
exceptionCounter.Add(1);
};
}

#pragma warning disable SA1313
/// <summary>
/// Initializes a new instance of the <see cref="RuntimeMetrics"/> class.
/// </summary>
/// <param name="options">The options to define the metrics.</param>
public RuntimeMetrics(RuntimeInstrumentationOptions options)
/// <param name="_1">The options to define the metrics.</param>
public RuntimeMetrics(RuntimeInstrumentationOptions _1)
#pragma warning restore SA1313
{
}

#if NET
private static bool IsGcInfoAvailable
{
get
Expand All @@ -227,12 +221,13 @@ private static bool IsGcInfoAvailable
return isGcInfoAvailable;
}
}
#endif

private static IEnumerable<Measurement<long>> GetGarbageCollectionCounts()
{
long collectionsFromHigherGeneration = 0;

for (int gen = NumberOfGenerations - 1; gen >= 0; --gen)
for (var gen = NumberOfGenerations - 1; gen >= 0; --gen)
{
long collectionsFromThisGeneration = GC.CollectionCount(gen);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace OpenTelemetry.Instrumentation.Runtime.Tests;

public class RuntimeInstrumentationOptionsTests
internal class RuntimeInstrumentationOptionsTests
{
/*
[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ public async Task ThreadingRelatedMetricsTest()
.Build();

// Bump the count for `thread_pool.completed_items.count` metric
int taskCount = 50;
List<Task> tasks = new List<Task>();
for (int i = 0; i < taskCount; i++)
var taskCount = 50;
var tasks = new List<Task>();
for (var i = 0; i < taskCount; i++)
{
tasks.Add(Task.Run(() => { }));
}
Expand All @@ -137,15 +137,19 @@ public async Task ThreadingRelatedMetricsTest()
var queueLengthMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.thread_pool.queue.length");
Assert.NotNull(queueLengthMetric);

List<Timer> timers = new List<Timer>();
var timers = new List<Timer>();
try
{
// Create 10 timers to bump timer.count metrics.
int timerCount = 10;
TimerCallback timerCallback = _ => { };
for (int i = 0; i < timerCount; i++)
var timerCount = 10;
#pragma warning disable SA1313
static void TimerCallback(object? _)
{
Timer timer = new Timer(timerCallback, null, 1000, 250);
}
#pragma warning restore SA1313
for (var i = 0; i < timerCount; i++)
{
var timer = new Timer(TimerCallback, null, 1000, 250);
timers.Add(timer);
}

Expand All @@ -157,7 +161,7 @@ public async Task ThreadingRelatedMetricsTest()
}
finally
{
for (int i = 0; i < timers.Count; i++)
for (var i = 0; i < timers.Count; i++)
{
timers[i].Dispose();
}
Expand Down

0 comments on commit c732609

Please sign in to comment.