Skip to content

Commit

Permalink
RavenDB-22947 Exposing GC info for a new cluster dashboard widget
Browse files Browse the repository at this point in the history
  • Loading branch information
arekpalinski committed Oct 7, 2024
1 parent e656ecb commit 446f953
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public enum ClusterDashboardNotificationType
ClusterOverview,
DatabaseOverview,

OngoingTasks
OngoingTasks,

GcInfo
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public async Task<AbstractClusterDashboardNotificationSender> CreateNotification
return new DatabaseOverviewNotificationSender(topicId, _databasesInfoRetriever, watcher, _shutdown);
case ClusterDashboardNotificationType.OngoingTasks:
return new OngoingTasksNotificationSender(topicId, _databasesInfoRetriever, watcher, _shutdown);
case ClusterDashboardNotificationType.GcInfo:
return new GcInfoNotificationSender(topicId, _server, watcher, _shutdown);
default:
// we don't want to throw here - it allows mixed clusters to partially show data
return null;
Expand Down
90 changes: 90 additions & 0 deletions src/Raven.Server/Dashboard/Cluster/GcInfoPayload.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using Sparrow.Json.Parsing;

namespace Raven.Server.Dashboard.Cluster;

public class GcInfoPayload : AbstractClusterDashboardNotification
{
public override ClusterDashboardNotificationType Type => ClusterDashboardNotificationType.GcInfo;

public GcMemoryInfo Ephemeral { get; set; }

public GcMemoryInfo Background { get; set; }

public GcMemoryInfo FullBlocking { get; set; }


public override DynamicJsonValue ToJson()
{
var json = base.ToJson();

json[nameof(Ephemeral)] = Ephemeral.ToJson();
json[nameof(Background)] = Background.ToJson();
json[nameof(FullBlocking)] = FullBlocking.ToJson();

return json;
}

public override DynamicJsonValue ToJsonWithFilter(CanAccessDatabase filter)
{
return ToJson();
}

public class GcMemoryInfo : IDynamicJson
{
public long Index { get; set; }

public bool Compacted { get; set; }

public bool Concurrent { get; set; }

public double PauseTimePercentage { get; set; }

public double[] PauseDurationsInMs { get; set; }

public long TotalHeapSizeAfterBytes { get; set; }

public GenerationInfoSize Gen0HeapSize { get; set; }

public GenerationInfoSize Gen1HeapSize { get; set; }

public GenerationInfoSize Gen2HeapSize { get; set; }

public GenerationInfoSize LargeObjectHeapSize { get; set; }

public GenerationInfoSize PinnedObjectHeapSize { get; set; }

public DynamicJsonValue ToJson()
{
return new DynamicJsonValue
{
[nameof(Index)] = Index,
[nameof(Compacted)] = Compacted,
[nameof(Concurrent)] = Concurrent,
[nameof(PauseTimePercentage)] = PauseTimePercentage,
[nameof(PauseDurationsInMs)] = PauseDurationsInMs,
[nameof(TotalHeapSizeAfterBytes)] = TotalHeapSizeAfterBytes,
[nameof(Gen0HeapSize)] = Gen0HeapSize.ToJson(),
[nameof(Gen1HeapSize)] = Gen1HeapSize.ToJson(),
[nameof(Gen2HeapSize)] = Gen2HeapSize.ToJson(),
[nameof(LargeObjectHeapSize)] = LargeObjectHeapSize.ToJson(),
[nameof(PinnedObjectHeapSize)] = PinnedObjectHeapSize.ToJson(),
};
}
}

public class GenerationInfoSize : IDynamicJson
{
public long SizeBeforeBytes { get; set; }

public long SizeAfterBytes { get; set; }

public DynamicJsonValue ToJson()
{
return new DynamicJsonValue
{
[nameof(SizeBeforeBytes)] = SizeBeforeBytes,
[nameof(SizeAfterBytes)] = SizeAfterBytes,
};
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System;
using System.Threading;
using Raven.Server.NotificationCenter;

namespace Raven.Server.Dashboard.Cluster.Notifications;

public class GcInfoNotificationSender : AbstractClusterDashboardNotificationSender
{
public GcInfoNotificationSender(int widgetId, RavenServer server, ConnectedWatcher watcher, CancellationToken shutdown) : base(widgetId, watcher, shutdown)
{
}

protected override TimeSpan NotificationInterval { get; } = TimeSpan.FromSeconds(5);

private GcInfoPayload.GcMemoryInfo ExtractGcMemoryInfoPayload(GCMemoryInfo info)
{
return new GcInfoPayload.GcMemoryInfo
{
Index = info.Index,
Compacted = info.Compacted,
Concurrent = info.Concurrent,
PauseTimePercentage = info.PauseTimePercentage,
PauseDurationsInMs =
[
info.PauseDurations[0].TotalMilliseconds,
info.PauseDurations[1].TotalMilliseconds
],
TotalHeapSizeAfterBytes = info.HeapSizeBytes,
Gen0HeapSize =
new GcInfoPayload.GenerationInfoSize
{
SizeBeforeBytes = info.GenerationInfo[0].SizeBeforeBytes,
SizeAfterBytes = info.GenerationInfo[0].SizeAfterBytes,
},
Gen1HeapSize =
new GcInfoPayload.GenerationInfoSize
{
SizeBeforeBytes = info.GenerationInfo[1].SizeBeforeBytes,
SizeAfterBytes = info.GenerationInfo[1].SizeAfterBytes,
},
Gen2HeapSize =
new GcInfoPayload.GenerationInfoSize
{
SizeBeforeBytes = info.GenerationInfo[2].SizeBeforeBytes,
SizeAfterBytes = info.GenerationInfo[2].SizeAfterBytes,
},
LargeObjectHeapSize =
new GcInfoPayload.GenerationInfoSize
{
SizeBeforeBytes = info.GenerationInfo[3].SizeBeforeBytes,
SizeAfterBytes = info.GenerationInfo[3].SizeAfterBytes,
},
PinnedObjectHeapSize = new GcInfoPayload.GenerationInfoSize
{
SizeBeforeBytes = info.GenerationInfo[4].SizeBeforeBytes,
SizeAfterBytes = info.GenerationInfo[4].SizeAfterBytes,
},
};
}

protected override AbstractClusterDashboardNotification CreateNotification()
{
var ephemeralGc = GC.GetGCMemoryInfo(GCKind.Ephemeral);
var backgroundGc = GC.GetGCMemoryInfo(GCKind.Background);
var fullBlockingGc = GC.GetGCMemoryInfo(GCKind.FullBlocking);

return new GcInfoPayload
{
Ephemeral = ExtractGcMemoryInfoPayload(ephemeralGc),
Background = ExtractGcMemoryInfoPayload(backgroundGc),
FullBlocking = ExtractGcMemoryInfoPayload(fullBlockingGc),
};
}
}

0 comments on commit 446f953

Please sign in to comment.