Mercurial > servermonitor
annotate ServerMonitor/Objects/Checks/DiskSpaceCheck.cs @ 23:3866c19535fd
Fix NullReferenceException when checks are executed on a brand new server.
author | Brad Greco <brad@bgreco.net> |
---|---|
date | Thu, 30 May 2019 21:40:27 -0400 |
parents | 68d7834dc28e |
children |
rev | line source |
---|---|
2 | 1 using System; |
2 using System.Collections.Generic; | |
3 using System.ComponentModel; | |
4 using System.Linq; | |
5 | |
6 namespace ServerMonitorApp | |
7 { | |
17 | 8 /// <summary>Checks the available disk space on a remote server.</summary> |
2 | 9 [DisplayName("Disk space check"), Description("Check the remaining free disk space"), DisplayWeight(11)] |
10 public class DiskSpaceCheck : SshCheck | |
11 { | |
17 | 12 /// <summary>The command to execute. Must return the POSIX output format of df(1).</summary> |
13
a36cc5c123f4
Fix SSH command sublclasses holding on to old command strings after a program update.
Brad Greco <brad@bgreco.net>
parents:
4
diff
changeset
|
13 public override string Command => string.Format(DiskSpaceCommand, Device); |
a36cc5c123f4
Fix SSH command sublclasses holding on to old command strings after a program update.
Brad Greco <brad@bgreco.net>
parents:
4
diff
changeset
|
14 |
17 | 15 /// <summary>The command to execute, with a placeholder of {0} for the device to check.</summary> |
13
a36cc5c123f4
Fix SSH command sublclasses holding on to old command strings after a program update.
Brad Greco <brad@bgreco.net>
parents:
4
diff
changeset
|
16 protected string DiskSpaceCommand => "df -P -k {0}"; |
3 | 17 |
17 | 18 /// <summary>The device or file on the device to check.</summary> |
2 | 19 public string Device { get; set; } |
20 | |
17 | 21 /// <summary>The minimum free space allowed for the check to pass.</summary> |
2 | 22 public double MinFreeSpace { get; set; } |
23 | |
17 | 24 /// <summary>The storage units or percentage for MinFreeSpace.</summary> |
2 | 25 public FreeSpaceUnits FreeSpaceUnits { get; set; } |
26 | |
27 public DiskSpaceCheck() | |
28 { | |
17 | 29 // Set general SSH check settings for disk space checks. |
2 | 30 CheckExitCode = true; |
31 ExitCode = 0; | |
32 } | |
33 | |
17 | 34 /// <summary>Processes the output of the disk space check command.</summary> |
2 | 35 protected override List<CheckResult> ProcessCommandResult(string output, int exitCode) |
36 { | |
17 | 37 // Check for general SSH failures. |
2 | 38 List<CheckResult> results = base.ProcessCommandResult(output, exitCode); |
17 | 39 // If there was an error running the command, fail immediately. |
4 | 40 if (results.Any(r => r.Failed)) |
3 | 41 return results; |
42 | |
17 | 43 /* Parse the command results, expected in the POSIX output format of df(1): |
44 Filesystem 1024-blocks Used Available Capacity Mounted on | |
45 <file system name> <total space> <space used> <space free> <percentage used> <file system root> | |
46 */ | |
47 // Split the output into lines and remove the header row. | |
3 | 48 List<string> lines = output.Split('\n').ToList(); |
49 lines.RemoveAt(0); | |
17 | 50 // Make sure there is only a single line of output remaining. |
3 | 51 if (lines.Count > 1) |
2 | 52 { |
3 | 53 results.Add(Fail("df output was more than one line: " + string.Join("\n", lines))); |
2 | 54 } |
55 else | |
56 { | |
17 | 57 // Split the string into tokens on whitespace. |
3 | 58 string[] tokens = lines[0].Split(new char[0], StringSplitOptions.RemoveEmptyEntries); |
2 | 59 if (FreeSpaceUnits == FreeSpaceUnits.percent) |
60 { | |
17 | 61 // Test on percentage: calculate the capacity free percent from the capacity used percent reported. |
3 | 62 if (int.TryParse(tokens[4].Replace("%", ""), out int percent)) |
2 | 63 { |
64 percent = 100 - percent; | |
65 string message = string.Format("Free disk space is {0}%", percent); | |
66 if (percent < MinFreeSpace) | |
67 results.Add(Fail(message)); | |
68 else | |
69 results.Add(Pass(message)); | |
70 } | |
71 else | |
72 { | |
3 | 73 results.Add(Fail("Unable to parse df output as integer: " + tokens[4].Replace("%", ""))); |
2 | 74 } |
75 } | |
76 else | |
77 { | |
17 | 78 // Test on bytes: calculate the remaining available space from the reported available space. |
3 | 79 if (int.TryParse(tokens[3], out int freeSpace)) |
2 | 80 { |
17 | 81 // Available space is returned in KB. Convert to MB (our default unit). |
2 | 82 freeSpace /= 1024; |
17 | 83 // If the unit is GB, convert MB to GB. |
2 | 84 if (FreeSpaceUnits == FreeSpaceUnits.GB) |
85 freeSpace /= 1024; | |
86 string message = string.Format("Free disk space is {0} {1}", freeSpace, FreeSpaceUnits); | |
87 if (freeSpace < MinFreeSpace) | |
88 results.Add(Fail(message)); | |
89 else | |
90 results.Add(Pass(message)); | |
91 } | |
92 else | |
93 { | |
3 | 94 results.Add(Fail("Unable to parse df output as integer: " + tokens[3])); |
2 | 95 } |
96 } | |
97 } | |
98 return results; | |
99 } | |
100 | |
17 | 101 /// <summary>Validates disk space check options.</summary> |
2 | 102 public override string Validate(bool saving = true) |
103 { | |
104 string message = base.Validate(); | |
105 if (Device.IsNullOrEmpty()) | |
106 message += "Device is required." + Environment.NewLine; | |
107 if (MinFreeSpace <= 0) | |
108 message += "Free space must be greater than 0." + Environment.NewLine; | |
109 else if (FreeSpaceUnits == FreeSpaceUnits.percent && MinFreeSpace > 100) | |
110 message += "Free space percent must be between 0 and 100." + Environment.NewLine; | |
111 return message; | |
112 } | |
113 } | |
114 | |
17 | 115 /// <summary>The units to use when testing available disk space.</summary> |
116 public enum FreeSpaceUnits | |
117 { | |
118 /// <summary>Tests available disk space in megabytes.</summary> | |
119 MB = 0, | |
120 /// <summary>Tests available disk space in gigabytes.</summary> | |
121 GB = 1, | |
122 /// <summary>Tests available disk space as a percentage of the total space.</summary> | |
123 percent = 2 | |
124 } | |
3 | 125 } |