Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MemoryInfo to sentry event #1337

Merged
merged 29 commits into from
Dec 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
b01f17c
AddMemoryInfo
SimonCropp Nov 23, 2021
8674995
Merge branch 'main' into AddMemoryInfo
SimonCropp Nov 24, 2021
d31efab
Merge branch 'main' into AddMemoryInfo
SimonCropp Nov 25, 2021
8e08af9
Merge branch 'main' into AddMemoryInfo
SimonCropp Nov 26, 2021
28f93d4
Merge branch 'main' into AddMemoryInfo
SimonCropp Nov 28, 2021
fd8855a
Update src/Sentry/Internal/MainSentryEventProcessor.cs
SimonCropp Dec 8, 2021
17c4fae
Merge branch 'main' into AddMemoryInfo
SimonCropp Dec 8, 2021
8e7c664
Merge branch 'main' into AddMemoryInfo
SimonCropp Dec 10, 2021
dfbe02b
Merge branch 'main' into AddMemoryInfo
SimonCropp Dec 14, 2021
05462d4
Update CHANGELOG.md
SimonCropp Dec 14, 2021
dd1fa6b
Merge branch 'main' into AddMemoryInfo
SimonCropp Dec 14, 2021
c147960
.
SimonCropp Dec 14, 2021
dfe09cf
Format code
getsentry-bot Dec 14, 2021
d00ddf8
Merge branch 'main' into AddMemoryInfo
SimonCropp Dec 14, 2021
34a3074
Merge branch 'main' into AddMemoryInfo
SimonCropp Dec 14, 2021
c332a1c
Update src/Sentry/Internal/MainSentryEventProcessor.cs
SimonCropp Dec 14, 2021
e9cfa49
.
SimonCropp Dec 16, 2021
1fc5af7
Merge branch 'main' into AddMemoryInfo
SimonCropp Dec 16, 2021
f5f6d88
.
SimonCropp Dec 16, 2021
dd7827b
Format code
getsentry-bot Dec 16, 2021
46fe6b1
Update MainSentryEventProcessorTests.cs
SimonCropp Dec 16, 2021
f4b2f96
Update MainSentryEventProcessorTests.cs
SimonCropp Dec 16, 2021
a16a350
Merge branch 'AddMemoryInfo' of https://github.com/getsentry/sentry-d…
SimonCropp Dec 16, 2021
6b1e286
.
SimonCropp Dec 16, 2021
b914fbf
Format code
getsentry-bot Dec 16, 2021
5104de7
Update MainSentryEventProcessorTests.cs
SimonCropp Dec 16, 2021
aa844a9
Update MainSentryEventProcessorTests.cs
SimonCropp Dec 16, 2021
b064d72
Merge branch 'AddMemoryInfo' of https://github.com/getsentry/sentry-d…
SimonCropp Dec 16, 2021
6e234b2
Update CHANGELOG.md
SimonCropp Dec 16, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

### Fixes
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, we should've added this as feature. Rolled out as 3.12.3


- Add MemoryInfo to sentry event ([#1337](https://github.com/getsentry/sentry-dotnet/pull/1337))

## 3.12.2

### Fixes
Expand Down
38 changes: 38 additions & 0 deletions src/Sentry/Internal/MainSentryEventProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ internal class MainSentryEventProcessor : ISentryEventProcessor
{
internal const string CultureInfoKey = "Current Culture";
internal const string CurrentUiCultureKey = "Current UI Culture";
internal const string MemoryInfoKey = "Memory Info";

private readonly Enricher _enricher;

Expand Down Expand Up @@ -54,6 +55,7 @@ public SentryEvent Process(SentryEvent @event)
@event.Contexts[CurrentUiCultureKey] = currentUiCultureMap;
}

AddMemoryInfo(@event.Contexts);
if (@event.ServerName == null)
{
// Value set on the options take precedence over device name.
Expand Down Expand Up @@ -133,6 +135,41 @@ public SentryEvent Process(SentryEvent @event)
return @event;
}

private void AddMemoryInfo(Contexts contexts)
{
#if NETCOREAPP3_0_OR_GREATER
var memory = GC.GetGCMemoryInfo();
var allocatedBytes = GC.GetTotalAllocatedBytes();
#if NET5_0_OR_GREATER
contexts[MemoryInfoKey] = new MemoryInfo(
allocatedBytes,
memory.FragmentedBytes,
memory.HeapSizeBytes,
memory.HighMemoryLoadThresholdBytes,
memory.TotalAvailableMemoryBytes,
memory.MemoryLoadBytes,
memory.TotalCommittedBytes,
memory.PromotedBytes,
memory.PinnedObjectsCount,
memory.PauseTimePercentage,
memory.Index,
memory.Generation,
memory.FinalizationPendingCount,
memory.Compacted,
memory.Concurrent,
memory.PauseDurations.ToArray());
#else
contexts[MemoryInfoKey] = new MemoryInfo(
allocatedBytes,
memory.FragmentedBytes,
memory.HeapSizeBytes,
memory.HighMemoryLoadThresholdBytes,
memory.TotalAvailableMemoryBytes,
memory.MemoryLoadBytes);
#endif
#endif
}

private static IDictionary<string, string>? CultureInfoToDictionary(CultureInfo cultureInfo)
{
var dic = new Dictionary<string, string>();
Expand All @@ -153,4 +190,5 @@ public SentryEvent Process(SentryEvent @event)
return dic.Count > 0 ? dic : null;
}
}

}
116 changes: 116 additions & 0 deletions src/Sentry/Internal/MemoryInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#if NETCOREAPP3_0_OR_GREATER

using System;
using System.Text.Json;
using Sentry.Extensibility;

namespace Sentry
{
internal sealed class MemoryInfo : IJsonSerializable
{
public long AllocatedBytes { get; }
public long FragmentedBytes { get; }
public long HeapSizeBytes { get; }
public long HighMemoryLoadThresholdBytes { get; }
public long TotalAvailableMemoryBytes { get; }
public long MemoryLoadBytes { get; }

#if NET5_0_OR_GREATER
public long TotalCommittedBytes { get; }
public long PromotedBytes { get; }
public long PinnedObjectsCount { get; }
public double PauseTimePercentage { get; }
public TimeSpan[] PauseDurations { get; }
public long Index { get; }
public int Generation { get; }
public long FinalizationPendingCount { get; }
public bool Compacted { get; }
public bool Concurrent { get; }

public MemoryInfo(
long allocatedBytes,
long fragmentedBytes,
long heapSizeBytes,
long highMemoryLoadThresholdBytes,
long totalAvailableMemoryBytes,
long memoryLoadBytes,
long totalCommittedBytes,
long promotedBytes,
long pinnedObjectsCount,
double pauseTimePercentage,
long index,
int generation,
long finalizationPendingCount,
bool compacted,
bool concurrent,
TimeSpan[] pauseDurations)
{
AllocatedBytes = allocatedBytes;
FragmentedBytes = fragmentedBytes;
HeapSizeBytes = heapSizeBytes;
HighMemoryLoadThresholdBytes = highMemoryLoadThresholdBytes;
TotalAvailableMemoryBytes = totalAvailableMemoryBytes;
MemoryLoadBytes = memoryLoadBytes;
TotalCommittedBytes = totalCommittedBytes;
PromotedBytes = promotedBytes;
PinnedObjectsCount = pinnedObjectsCount;
PauseTimePercentage = pauseTimePercentage;
PauseDurations = pauseDurations;
Index = index;
Generation = generation;
FinalizationPendingCount = finalizationPendingCount;
Compacted = compacted;
Concurrent = concurrent;
}
#else
public MemoryInfo(
long allocatedBytes,
long fragmentedBytes,
long heapSizeBytes,
long highMemoryLoadThresholdBytes,
long totalAvailableMemoryBytes,
long memoryLoadBytes)
{
AllocatedBytes = allocatedBytes;
FragmentedBytes = fragmentedBytes;
HeapSizeBytes = heapSizeBytes;
HighMemoryLoadThresholdBytes = highMemoryLoadThresholdBytes;
TotalAvailableMemoryBytes = totalAvailableMemoryBytes;
MemoryLoadBytes = memoryLoadBytes;
}
#endif
public void WriteTo(Utf8JsonWriter writer, IDiagnosticLogger? logger)
{
writer.WriteStartObject();

writer.WriteNumber("allocatedBytes", AllocatedBytes);
writer.WriteNumber("fragmentedBytes", FragmentedBytes);
writer.WriteNumber("heapSizeBytes", HeapSizeBytes);
writer.WriteNumber("highMemoryLoadThresholdBytes", HighMemoryLoadThresholdBytes);
writer.WriteNumber("totalAvailableMemoryBytes", TotalAvailableMemoryBytes);
writer.WriteNumber("memoryLoadBytes", MemoryLoadBytes);

#if NET5_0_OR_GREATER
writer.WriteNumber("totalCommittedBytes", TotalCommittedBytes);
writer.WriteNumber("promotedBytes", PromotedBytes);
writer.WriteNumber("pinnedObjectsCount", PinnedObjectsCount);
writer.WriteNumber("pauseTimePercentage", PauseTimePercentage);
writer.WriteNumber("index", Index);
writer.WriteNumber("generation", Generation);
writer.WriteNumber("finalizationPendingCount", FinalizationPendingCount);
writer.WriteBoolean("compacted", Compacted);
writer.WriteBoolean("concurrent", Concurrent);
writer.WritePropertyName("pauseDurations");
writer.WriteStartArray();
foreach (var duration in PauseDurations)
{
writer.WriteNumberValue(duration.TotalMilliseconds);
}
writer.WriteEndArray();
#endif
writer.WriteEndObject();
}
}
}

#endif
26 changes: 26 additions & 0 deletions test/Sentry.Tests/Internals/MainSentryEventProcessorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,32 @@ public void Process_SendDefaultPiiTrueIdEnvironmentDefault_UserNameSet()
Assert.Equal(Environment.UserName, evt.User.Username);
}

#if NETCOREAPP3_1_OR_GREATER
[Fact]
public void EnsureMemoryInfoExists()
{
var evt = new SentryEvent();

_fixture.SentryOptions.SendDefaultPii = true;
var sut = _fixture.GetSut();

_ = sut.Process(evt);
var memory = (MemoryInfo)evt.Contexts[MainSentryEventProcessor.MemoryInfoKey];
Assert.NotEqual(0, memory.TotalAvailableMemoryBytes);
Assert.NotEqual(0, memory.FragmentedBytes);
Assert.NotEqual(0, memory.HeapSizeBytes);
Assert.NotEqual(0, memory.HighMemoryLoadThresholdBytes);
Assert.NotEqual(0, memory.TotalAvailableMemoryBytes);
Assert.NotEqual(0, memory.MemoryLoadBytes);
#if NET5_0_OR_GREATER
Assert.NotEqual(0, memory.TotalCommittedBytes);
Assert.NotEqual(0, memory.PromotedBytes);
Assert.NotEqual(0, memory.PauseTimePercentage);
Assert.NotEmpty(memory.PauseDurations);
#endif
}
#endif

[Fact]
public void Process_SendDefaultPiiTrueIdEnvironmentTrue_UserNameSet()
{
Expand Down
27 changes: 27 additions & 0 deletions test/Sentry.Tests/Internals/MemoryInfoTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#if NETCOREAPP3_1_OR_GREATER
using System.Text.Json;

public class MemoryInfoTests
{
[Fact]
public void WriteTo()
{
#if NET5_0_OR_GREATER
var info = new MemoryInfo(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, true, false, new[] { TimeSpan.FromSeconds(1) });
#else
var info = new MemoryInfo(1, 2, 3, 4, 5, 6);
#endif

var stream = new MemoryStream();
var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true });
info.WriteTo(writer, null);
writer.Flush();
var json = Encoding.UTF8.GetString(stream.ToArray());
Assert.NotNull(json);
Assert.NotEmpty(json);
//Validate json
var serializer = new Newtonsoft.Json.JsonSerializer();
serializer.Deserialize(new Newtonsoft.Json.JsonTextReader(new StringReader(json)));
}
}
#endif