Mercurial > servermonitor
diff ServerMonitor/Objects/Checks/FileCheck.cs @ 17:68d7834dc28e
More comments.
author | Brad Greco <brad@bgreco.net> |
---|---|
date | Sat, 25 May 2019 15:14:26 -0400 |
parents | a36cc5c123f4 |
children | 88ca7e4fc023 |
line wrap: on
line diff
--- a/ServerMonitor/Objects/Checks/FileCheck.cs Tue Apr 30 20:40:58 2019 -0400 +++ b/ServerMonitor/Objects/Checks/FileCheck.cs Sat May 25 15:14:26 2019 -0400 @@ -2,74 +2,96 @@ using System.Collections.Generic; using System.ComponentModel; using System.Linq; -using System.Text; using System.Text.RegularExpressions; -using System.Threading.Tasks; -using System.Xml.Serialization; namespace ServerMonitorApp { + /// <summary>Checks file metadata on a remote server.</summary> [DisplayName("File check"), Description("Check file size or modified time"), DisplayWeight(12)] public class FileCheck : SshCheck { + /// <summary>The command to execute. Must return the output format of GNU ls(1) with the long-iso time style.</summary> + /// <remarks>Would be better to not rely on the output of ls.</remarks> public override string Command => string.Format(FileCommand, Regex.Replace(File, "^~", "$HOME")); + /// <summary>The command to execute, with a placeholder of {0} for the file to check.</summary> protected string FileCommand { get { - int timeZoneOffset = TimeZoneInfo.Local.GetUtcOffset(DateTime.Now).Hours * -1; // Invert because POSIX says so. + // Invert because POSIX says so. + int timeZoneOffset = TimeZoneInfo.Local.GetUtcOffset(DateTime.Now).Hours * -1; + // Set the date format to long-iso since it's easy to parse. + // Set the time zone to the match the client time zone so comparisons are reliable. return "export TIME_STYLE=long-iso; export TZ=UTC" + timeZoneOffset + "; ls -l \"{0}\""; } } + /// <summary>The path of the file to check.</summary> public string File { get; set; } + /// <summary>Whether the file size will be checked.</summary> public bool CheckFileSize { get; set; } + /// <summary>Whether the file is expected to be less than or greater than a certain size.</summary> public bool FileSizeLessThan { get; set; } + /// <summary>The size to compare the file against in bytes.</summary> public int FileSize { get; set; } + /// <summary>The size to compare the file against in the selected size units.</summary> public double FileSizeInSelectedUnits { get => Math.Round(ConvertBytesToSelectedUnits(FileSize), 1); set => FileSize = ConvertSelectedUnitsToBytes(value); } + /// <summary>The units of the file size.</summary> public SizeUnits FileSizeUnits { get; set; } + /// <summary>Whether the file modified time will be checked.</summary> public bool CheckDateModified { get; set; } + /// <summary>Whether the file is expected to be older than or newer than a certain date.</summary> public bool DateModifiedOlderThan { get; set; } + /// <summary>The number of time units to compare then file modified time against.</summary> public double DateModified { get; set; } + /// <summary>The units of the file date modified.</summary> public TimeUnits DateModifiedUnits { get; set; } public FileCheck() { + // Set general SSH check settings for file checks. CheckExitCode = true; ExitCode = 0; } + /// <summary>Processes the output of the file check command.</summary> protected override List<CheckResult> ProcessCommandResult(string output, int exitCode) { + // Check for general SSH failures. List<CheckResult> results = base.ProcessCommandResult(output, exitCode); + // If there was an error running the command, fail immediately. if (results.Any(r => r.Failed)) return results; + // Make sure there is only a single line of output. if (output.Split('\n').Length > 1) { results.Add(Fail("ls output was more than one line: " + output)); } else { + // Split the string into tokens on whitespace. string[] tokens = output.Split(new char[0], StringSplitOptions.RemoveEmptyEntries); if (CheckFileSize) { + // Check file size. if (int.TryParse(tokens[4], out int bytes)) { + // Prepare a human-readable message with the comparison results. string message = string.Format("File size is {0} {1}", Math.Round(ConvertBytesToSelectedUnits(bytes), 1), FileSizeUnits); if ((bytes < FileSize && FileSizeLessThan) || (bytes > FileSize && !FileSizeLessThan)) results.Add(Pass(message)); @@ -83,10 +105,13 @@ } if (CheckDateModified) { + // Check date modified. + // Tokens[5] contains the date, tokens[6] contains the time. string dateString = tokens[5] + " " + tokens[6]; if (DateTime.TryParse(dateString, out DateTime modified)) { string message = string.Format("Last modified date is {0}", modified); + // Determine how old the file is. The command output is in the client time zone. TimeSpan age = DateTime.Now.Subtract(modified); double ageCompare = DateModifiedUnits == TimeUnits.Minute ? age.TotalMinutes : DateModifiedUnits == TimeUnits.Hour ? age.TotalHours : @@ -105,6 +130,7 @@ return results; } + /// <summary>Validates file check options.</summary> public override string Validate(bool saving = true) { string message = base.Validate(); @@ -119,11 +145,17 @@ return message; } + /// <summary>Converts bytes to a different size unit.</summary> + /// <param name="sizeInBytes">The size to convert in bytes.</param> + /// <returns>The size in the units used by this file check.</returns> private double ConvertBytesToSelectedUnits(int sizeInBytes) { return sizeInBytes / Math.Pow(1024, (double)FileSizeUnits); } + /// <summary>Converts a size in a different unit to bytes.</summary> + /// <param name="sizeInSelectedUnits">The size to convert in the units used by this file check.</param> + /// <returns>The size in bytes.</returns> private int ConvertSelectedUnitsToBytes(double sizeInSelectedUnits) { return (int)(sizeInSelectedUnits * Math.Pow(1024, (int)FileSizeUnits));