3
|
1 using System;
|
|
2 using System.Collections.Generic;
|
|
3 using System.ComponentModel;
|
|
4 using System.Linq;
|
|
5 using System.Text;
|
|
6 using System.Text.RegularExpressions;
|
|
7 using System.Threading.Tasks;
|
|
8
|
|
9 namespace ServerMonitorApp
|
|
10 {
|
|
11 [DisplayName("File check"), Description("Check file size or modified time"), DisplayWeight(12)]
|
|
12 public class FileCheck : SshCheck
|
|
13 {
|
4
|
14 public override string Command => string.Format(base.Command, Regex.Replace(File, "^~", "$HOME"));
|
3
|
15
|
|
16 public string File { get; set; }
|
|
17
|
|
18 public bool CheckFileSize { get; set; }
|
|
19
|
|
20 public bool FileSizeLessThan { get; set; }
|
|
21
|
4
|
22 public int FileSize { get; set; }
|
3
|
23
|
|
24 public double FileSizeInSelectedUnits
|
|
25 {
|
4
|
26 get => Math.Round(ConvertBytesToSelectedUnits(FileSize), 1);
|
|
27 set => FileSize = ConvertSelectedUnitsToBytes(value);
|
3
|
28 }
|
|
29
|
|
30 public SizeUnits FileSizeUnits { get; set; }
|
|
31
|
|
32 public bool CheckDateModified { get; set; }
|
|
33
|
|
34 public bool DateModifiedOlderThan { get; set; }
|
|
35
|
|
36 public double DateModified { get; set; }
|
|
37
|
|
38 public TimeUnits DateModifiedUnits { get; set; }
|
|
39
|
|
40 public FileCheck()
|
|
41 {
|
|
42 Command = "export TIME_STYLE=long-iso; ls -l \"{0}\"";
|
|
43 //Command = "export TIME_STYLE=long-iso; ls -l \"{0}\" | tr -s ' ' | cut -d ' ' -f 5,6,7";
|
|
44 CheckExitCode = true;
|
|
45 ExitCode = 0;
|
|
46 }
|
|
47
|
|
48 protected override List<CheckResult> ProcessCommandResult(string output, int exitCode)
|
|
49 {
|
|
50 List<CheckResult> results = base.ProcessCommandResult(output, exitCode);
|
4
|
51 if (results.Any(r => r.Failed))
|
3
|
52 return results;
|
|
53
|
|
54 if (output.Split('\n').Length > 1)
|
|
55 {
|
|
56 results.Add(Fail("ls output was more than one line: " + output));
|
|
57 }
|
|
58 else
|
|
59 {
|
|
60 string[] tokens = output.Split(new char[0], StringSplitOptions.RemoveEmptyEntries);
|
|
61 if (CheckFileSize)
|
|
62 {
|
|
63 if (int.TryParse(tokens[4], out int bytes))
|
|
64 {
|
4
|
65 string message = string.Format("File size is {0} {1}", Math.Round(ConvertBytesToSelectedUnits(bytes), 1), FileSizeUnits);
|
3
|
66 if ((bytes < FileSize && FileSizeLessThan) || (bytes > FileSize && !FileSizeLessThan))
|
|
67 results.Add(Pass(message));
|
|
68 else
|
|
69 results.Add(Fail(message));
|
|
70 }
|
|
71 else
|
|
72 {
|
|
73 results.Add(Fail("Unable to parse ls output as integer: " + tokens[4]));
|
|
74 }
|
|
75 }
|
|
76 if (CheckDateModified)
|
|
77 {
|
9
|
78 // TODO use the server time instead
|
3
|
79 string dateString = tokens[5] + " " + tokens[6];
|
|
80 if (DateTime.TryParse(dateString, out DateTime modified))
|
|
81 {
|
|
82 string message = string.Format("Last modified date is {0}", modified);
|
|
83 TimeSpan age = DateTime.Now.Subtract(modified);
|
|
84 double ageCompare = DateModifiedUnits == TimeUnits.Minute ? age.TotalMinutes :
|
|
85 DateModifiedUnits == TimeUnits.Hour ? age.TotalHours :
|
|
86 age.TotalDays;
|
|
87 if ((ageCompare > DateModified && DateModifiedOlderThan) || (ageCompare < DateModified && !DateModifiedOlderThan))
|
|
88 results.Add(Pass(message));
|
|
89 else
|
|
90 results.Add(Fail(message));
|
|
91 }
|
|
92 else
|
|
93 {
|
|
94 results.Add(Fail("Unable to parse ls output as date: " + dateString));
|
|
95 }
|
|
96 }
|
|
97 }
|
|
98 return results;
|
|
99 }
|
|
100
|
|
101 public override string Validate(bool saving = true)
|
|
102 {
|
|
103 string message = base.Validate();
|
|
104 if (File.IsNullOrEmpty())
|
|
105 message += "File is required." + Environment.NewLine;
|
|
106 if (!CheckFileSize && !CheckDateModified)
|
|
107 message += "At least one check must be enabled." + Environment.NewLine;
|
9
|
108 if (CheckFileSize && FileSize < 0)
|
|
109 message += "File size must be at least 0." + Environment.NewLine;
|
3
|
110 if (CheckDateModified && DateModified <= 0)
|
|
111 message += "Date modified must be greater than 0." + Environment.NewLine;
|
|
112 return message;
|
|
113 }
|
4
|
114
|
|
115 private double ConvertBytesToSelectedUnits(int sizeInBytes)
|
|
116 {
|
|
117 return sizeInBytes / Math.Pow(1024, (double)FileSizeUnits);
|
|
118 }
|
|
119
|
|
120 private int ConvertSelectedUnitsToBytes(double sizeInSelectedUnits)
|
|
121 {
|
|
122 return (int)(sizeInSelectedUnits * Math.Pow(1024, (int)FileSizeUnits));
|
|
123 }
|
3
|
124 }
|
|
125 } |