-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5 from Steveiwonder/develop
Add free memory healthcheck
- Loading branch information
Showing
5 changed files
with
170 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
WSM.HealthChecks/FreeMemoryHealthCheck/FreeMemoryHealthCheckConfiguration.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
using WSM.Client.Models; | ||
|
||
namespace WSM.PluginExample | ||
{ | ||
public class FreeMemoryHealthCheckConfiguration: HealthCheckConfigurationBase | ||
{ | ||
public long MinimumFreeMemory { get; set; } | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
WSM.HealthChecks/FreeMemoryHealthCheck/FreeMemoryHealthCheckDefinition.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using WSM.Client.Models; | ||
using WSM.HealthChecks.FreeMemoryHealthCheck; | ||
|
||
namespace WSM.PluginExample | ||
{ | ||
public class FreeMemoryHealthCheckDefinition : HealthCheckDefinitionBase<FreeMemoryHealthCheckJob, FreeMemoryHealthCheckConfiguration> | ||
{ | ||
public override string Type => "FreeMemory"; | ||
} | ||
} |
129 changes: 129 additions & 0 deletions
129
WSM.HealthChecks/FreeMemoryHealthCheck/FreeMemoryHealthCheckJob.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
using Microsoft.Extensions.Logging; | ||
using Quartz; | ||
using WSM.Client.Jobs; | ||
using WSM.Shared; | ||
using WSM.PluginExample; | ||
using System.Diagnostics; | ||
using System.Runtime.InteropServices; | ||
|
||
namespace WSM.HealthChecks.FreeMemoryHealthCheck | ||
{ | ||
[DisallowConcurrentExecution] | ||
public class FreeMemoryHealthCheckJob : HealthCheckJobBase | ||
{ | ||
private readonly ILogger<FreeMemoryHealthCheckJob> _logger; | ||
private const string MemoryLowStatus = "Free memory low"; | ||
public FreeMemoryHealthCheckJob(ILogger<FreeMemoryHealthCheckJob> logger, WSMApiClient apiClient) : base(apiClient) | ||
{ | ||
_logger = logger; | ||
} | ||
public override async Task Execute(IJobExecutionContext context) | ||
{ | ||
var healthCheckConfiguration = GetConfiguration<FreeMemoryHealthCheckConfiguration>(context); | ||
try | ||
{ | ||
var freeSystemMemory = GetFreeSystemMemory(); | ||
|
||
if (freeSystemMemory < healthCheckConfiguration.MinimumFreeMemory) | ||
{ | ||
string mbAvailable = FormatUtils.SizeSuffix(freeSystemMemory); | ||
await CheckIn(healthCheckConfiguration, $"{MemoryLowStatus}, {mbAvailable} available"); | ||
return; | ||
} | ||
|
||
await CheckIn(healthCheckConfiguration, Constants.AvailableStatus); | ||
} | ||
catch (Exception ex) | ||
{ | ||
_logger.LogError(ex, ""); | ||
} | ||
} | ||
|
||
private long GetFreeSystemMemory() | ||
{ | ||
|
||
MemoryMetricsClient client = new MemoryMetricsClient(); | ||
return client.GetMetrics().Free; | ||
} | ||
|
||
public class MemoryMetrics | ||
{ | ||
public long Total; | ||
public long Used; | ||
public long Free; | ||
} | ||
|
||
public class MemoryMetricsClient | ||
{ | ||
public MemoryMetrics GetMetrics() | ||
{ | ||
if (IsUnix()) | ||
{ | ||
return GetUnixMetrics(); | ||
} | ||
|
||
return GetWindowsMetrics(); | ||
} | ||
|
||
private bool IsUnix() | ||
{ | ||
var isUnix = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || | ||
RuntimeInformation.IsOSPlatform(OSPlatform.Linux); | ||
|
||
return isUnix; | ||
} | ||
|
||
private MemoryMetrics GetWindowsMetrics() | ||
{ | ||
var output = ""; | ||
|
||
var info = new ProcessStartInfo(); | ||
info.FileName = "wmic"; | ||
info.Arguments = "OS get FreePhysicalMemory,TotalVisibleMemorySize /Value"; | ||
info.RedirectStandardOutput = true; | ||
|
||
using (var process = Process.Start(info)) | ||
{ | ||
output = process.StandardOutput.ReadToEnd(); | ||
} | ||
|
||
var lines = output.Trim().Split("\n"); | ||
var freeMemoryParts = lines[0].Split("=", StringSplitOptions.RemoveEmptyEntries); | ||
var totalMemoryParts = lines[1].Split("=", StringSplitOptions.RemoveEmptyEntries); | ||
|
||
var metrics = new MemoryMetrics(); | ||
metrics.Total = long.Parse(totalMemoryParts[1]) * 1000; | ||
metrics.Free =long.Parse(freeMemoryParts[1]) * 1000; | ||
metrics.Used = metrics.Total - metrics.Free; | ||
|
||
return metrics; | ||
} | ||
|
||
private MemoryMetrics GetUnixMetrics() | ||
{ | ||
var output = ""; | ||
|
||
var info = new ProcessStartInfo("free -m"); | ||
info.FileName = "/bin/bash"; | ||
info.Arguments = "-c \"free -m\""; | ||
info.RedirectStandardOutput = true; | ||
|
||
using (var process = Process.Start(info)) | ||
{ | ||
output = process.StandardOutput.ReadToEnd(); | ||
Console.WriteLine(output); | ||
} | ||
|
||
var lines = output.Split("\n"); | ||
var memory = lines[1].Split(" ", StringSplitOptions.RemoveEmptyEntries); | ||
|
||
var metrics = new MemoryMetrics(); | ||
metrics.Total = long.Parse(memory[1]); | ||
metrics.Used = long.Parse(memory[2]); | ||
metrics.Free = long.Parse(memory[3]); | ||
|
||
return metrics; | ||
} | ||
} | ||
} | ||
} |