From 06ff903497619a04e318356a7a0b74d96ca94640 Mon Sep 17 00:00:00 2001 From: Mauro Servienti Date: Fri, 14 Mar 2025 14:08:10 +0100 Subject: [PATCH 1/2] Do not try to parse the RavenDB dirty memory value The unit might change unexpectedly. Instead, treat it as a string. --- .../CustomChecks/CheckDirtyMemory.cs | 4 ++-- .../MemoryInformationRetriever.cs | 9 ++------- .../CustomChecks/CheckDirtyMemory.cs | 4 ++-- .../MemoryInformationRetriever.cs | 9 ++------- 4 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs b/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs index cedca079c4..ffc591ea2d 100644 --- a/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs +++ b/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs @@ -10,11 +10,11 @@ class CheckDirtyMemory(MemoryInformationRetriever memoryInformationRetriever) : { public override async Task PerformCheck(CancellationToken cancellationToken = default) { - var (isHighDirty, dirtyMemoryKb) = await memoryInformationRetriever.GetMemoryInformation(cancellationToken); + var (isHighDirty, dirtyMemory) = await memoryInformationRetriever.GetMemoryInformation(cancellationToken); if (isHighDirty) { - var message = $"There is a high level of RavenDB dirty memory ({dirtyMemoryKb}kb). See https://docs.particular.net/servicecontrol/troubleshooting#ravendb-dirty-memory for guidance on how to mitigate the issue."; + var message = $"There is a high level of RavenDB dirty memory ({dirtyMemory}). See https://docs.particular.net/servicecontrol/troubleshooting#ravendb-dirty-memory for guidance on how to mitigate the issue."; Log.Warn(message); return CheckResult.Failed(message); } diff --git a/src/ServiceControl.Audit.Persistence.RavenDB/MemoryInformationRetriever.cs b/src/ServiceControl.Audit.Persistence.RavenDB/MemoryInformationRetriever.cs index eea7d87865..452546521d 100644 --- a/src/ServiceControl.Audit.Persistence.RavenDB/MemoryInformationRetriever.cs +++ b/src/ServiceControl.Audit.Persistence.RavenDB/MemoryInformationRetriever.cs @@ -26,16 +26,11 @@ record MemoryInformation public string DirtyMemory { get; set; } } - public async Task<(bool IsHighDirty, int DirtyMemoryKb)> GetMemoryInformation(CancellationToken cancellationToken = default) + public async Task<(bool IsHighDirty, string DirtyMemory)> GetMemoryInformation(CancellationToken cancellationToken = default) { var httpResponse = await client.GetAsync("/admin/debug/memory/stats?includeThreads=false&includeMappings=false", cancellationToken); var responseDto = JsonSerializer.Deserialize(await httpResponse.Content.ReadAsStringAsync(cancellationToken)); - var values = responseDto.MemoryInformation.DirtyMemory.Split(' '); - if (!string.Equals(values[1], "KBytes", StringComparison.OrdinalIgnoreCase)) - { - throw new InvalidOperationException($"Unexpected response. Was expecting memory details in KBytes, instead received: {responseDto.MemoryInformation.DirtyMemory}"); - } - return (responseDto.MemoryInformation.IsHighDirty, int.Parse(values[0])); + return (responseDto.MemoryInformation.IsHighDirty, responseDto.MemoryInformation.DirtyMemory); } } \ No newline at end of file diff --git a/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs b/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs index fb0ec20c96..b27ac9f3e1 100644 --- a/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs +++ b/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs @@ -10,11 +10,11 @@ class CheckDirtyMemory(MemoryInformationRetriever memoryInformationRetriever) : { public override async Task PerformCheck(CancellationToken cancellationToken = default) { - var (isHighDirty, dirtyMemoryKb) = await memoryInformationRetriever.GetMemoryInformation(cancellationToken); + var (isHighDirty, dirtyMemory) = await memoryInformationRetriever.GetMemoryInformation(cancellationToken); if (isHighDirty) { - var message = $"There is a high level of RavenDB dirty memory ({dirtyMemoryKb}kb). See https://docs.particular.net/servicecontrol/troubleshooting#ravendb-dirty-memory for guidance on how to mitigate the issue."; + var message = $"There is a high level of RavenDB dirty memory ({dirtyMemory}). See https://docs.particular.net/servicecontrol/troubleshooting#ravendb-dirty-memory for guidance on how to mitigate the issue."; Log.Warn(message); return CheckResult.Failed(message); } diff --git a/src/ServiceControl.Persistence.RavenDB/MemoryInformationRetriever.cs b/src/ServiceControl.Persistence.RavenDB/MemoryInformationRetriever.cs index 485c6b6640..0b5e0d626d 100644 --- a/src/ServiceControl.Persistence.RavenDB/MemoryInformationRetriever.cs +++ b/src/ServiceControl.Persistence.RavenDB/MemoryInformationRetriever.cs @@ -25,16 +25,11 @@ record MemoryInformation public string DirtyMemory { get; set; } } - public async Task<(bool IsHighDirty, int DirtyMemoryKb)> GetMemoryInformation(CancellationToken cancellationToken = default) + public async Task<(bool IsHighDirty, string DirtyMemory)> GetMemoryInformation(CancellationToken cancellationToken = default) { var httpResponse = await client.GetAsync("/admin/debug/memory/stats?includeThreads=false&includeMappings=false", cancellationToken); var responseDto = JsonSerializer.Deserialize(await httpResponse.Content.ReadAsStringAsync(cancellationToken)); - var values = responseDto.MemoryInformation.DirtyMemory.Split(' '); - if (!string.Equals(values[1], "KBytes", StringComparison.OrdinalIgnoreCase)) - { - throw new InvalidOperationException($"Unexpected response. Was expecting memory details in KBytes, instead received: {responseDto.MemoryInformation.DirtyMemory}"); - } - return (responseDto.MemoryInformation.IsHighDirty, int.Parse(values[0])); + return (responseDto.MemoryInformation.IsHighDirty, responseDto.MemoryInformation.DirtyMemory); } } \ No newline at end of file From ac37a9f4e9f4f2f11c59ffa1c0aaa8fc196e4ee9 Mon Sep 17 00:00:00 2001 From: Mauro Servienti Date: Fri, 14 Mar 2025 14:11:37 +0100 Subject: [PATCH 2/2] Always debug log the dirty memory value --- .../CustomChecks/CheckDirtyMemory.cs | 2 ++ .../CustomChecks/CheckDirtyMemory.cs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs b/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs index ffc591ea2d..37731858d8 100644 --- a/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs +++ b/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs @@ -12,6 +12,8 @@ public override async Task PerformCheck(CancellationToken cancellat { var (isHighDirty, dirtyMemory) = await memoryInformationRetriever.GetMemoryInformation(cancellationToken); + Log.Debug($"RavenDB dirty memory value: {dirtyMemory}."); + if (isHighDirty) { var message = $"There is a high level of RavenDB dirty memory ({dirtyMemory}). See https://docs.particular.net/servicecontrol/troubleshooting#ravendb-dirty-memory for guidance on how to mitigate the issue."; diff --git a/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs b/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs index b27ac9f3e1..8eee53911a 100644 --- a/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs +++ b/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs @@ -12,6 +12,8 @@ public override async Task PerformCheck(CancellationToken cancellat { var (isHighDirty, dirtyMemory) = await memoryInformationRetriever.GetMemoryInformation(cancellationToken); + Log.Debug($"RavenDB dirty memory value: {dirtyMemory}."); + if (isHighDirty) { var message = $"There is a high level of RavenDB dirty memory ({dirtyMemory}). See https://docs.particular.net/servicecontrol/troubleshooting#ravendb-dirty-memory for guidance on how to mitigate the issue.";