comparison ServerMonitor/Objects/Logger.cs @ 17:68d7834dc28e

More comments.
author Brad Greco <brad@bgreco.net>
date Sat, 25 May 2019 15:14:26 -0400
parents 7127d5b5ac75
children
comparison
equal deleted inserted replaced
16:7626b099aefd 17:68d7834dc28e
1 using ServerMonitorApp.Properties; 1 using ServerMonitorApp.Properties;
2 using System; 2 using System;
3 using System.Collections.Generic; 3 using System.Collections.Generic;
4 using System.IO; 4 using System.IO;
5 using System.Linq; 5 using System.Linq;
6 using System.Reflection;
7 using System.Text; 6 using System.Text;
8 using System.Threading.Tasks;
9 7
10 namespace ServerMonitorApp 8 namespace ServerMonitorApp
11 { 9 {
10 /// <summary>Manages reading and writing check results to a log file.</summary>
12 public class Logger 11 public class Logger
13 { 12 {
14 private const int logVersion = 1; 13 private const int logVersion = 1;
15 private readonly string logFile; 14 private readonly string logFile;
16 15
16 /// <summary>Logger constructor.</summary>
17 /// <param name="file">The path of the log file to use.</param>
17 public Logger(string file) 18 public Logger(string file)
18 { 19 {
19 logFile = file; 20 logFile = file;
20 } 21 }
21 22
23 /// <summary>Appends a string to the log file, creating the log file if it does not exist.</summary>
24 /// <param name="logString">The string to log.</param>
22 public async void Log(string logString) 25 public async void Log(string logString)
23 { 26 {
27 // Create the file if it does not exist.
28 // Write the current version at the beginning in case we ever change the format.
24 if (!File.Exists(logFile)) 29 if (!File.Exists(logFile))
25 logString = "Server Monitor log version " + logVersion + Environment.NewLine + logString; 30 logString = "Server Monitor log version " + logVersion + Environment.NewLine + logString;
31 // Write the message.
26 using (FileStream stream = new FileStream(logFile, FileMode.Append, FileAccess.Write, FileShare.Read, 4096, true)) 32 using (FileStream stream = new FileStream(logFile, FileMode.Append, FileAccess.Write, FileShare.Read, 4096, true))
27 using (StreamWriter writer = new StreamWriter(stream, Encoding.UTF8)) 33 using (StreamWriter writer = new StreamWriter(stream, Encoding.UTF8))
28 { 34 {
29 await writer.WriteLineAsync(logString); 35 await writer.WriteLineAsync(logString);
30 } 36 }
31 } 37 }
32 38
39 /// <summary>Appends a check result to the log file, creating the log file if it does not exist.</summary>
40 /// <param name="result">The check result to log.</param>
33 public void Log(CheckResult result) 41 public void Log(CheckResult result)
34 { 42 {
35 Log(result.ToLogString()); 43 Log(result.ToLogString());
36 } 44 }
37 45
46 /// <summary>Reads all check results from the log for a server.</summary>
47 /// <param name="server">The server whose check results should be read.</param>
48 /// <returns>A list of all check results found in the log file for the given server.</returns>
38 public IList<CheckResult> Read(Server server) 49 public IList<CheckResult> Read(Server server)
39 { 50 {
51 // Store the checks by ID.
40 Dictionary<int, Check> checks = server.Checks.ToDictionary(c => c.Id); 52 Dictionary<int, Check> checks = server.Checks.ToDictionary(c => c.Id);
41 List<CheckResult> results = new List<CheckResult>(); 53 List<CheckResult> results = new List<CheckResult>();
42 using (FileStream stream = new FileStream(logFile, FileMode.Open, FileAccess.Read, FileShare.Read)) 54 using (FileStream stream = new FileStream(logFile, FileMode.Open, FileAccess.Read, FileShare.Read))
43 using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) 55 using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
44 { 56 {
57 // Read through the whole file, searching for results belonging to the server.
45 while (true) 58 while (true)
46 { 59 {
47 try 60 try
48 { 61 {
49 string line = reader.ReadLine(); 62 string line = reader.ReadLine();
63 // Exit the loop when we reach the end.
50 if (line == null) 64 if (line == null)
51 break; 65 break;
66 // The check ID is a fixed length.
67 // Parse it and see if it matches any of the checks we are interested in.
52 if (int.TryParse(line.Substring(0, 5), out int id) && checks.TryGetValue(id, out Check check)) 68 if (int.TryParse(line.Substring(0, 5), out int id) && checks.TryGetValue(id, out Check check))
53 { 69 {
70 // If it is, add it to our results list.
54 results.Add(CheckResult.FromLogString(check, line)); 71 results.Add(CheckResult.FromLogString(check, line));
55 } 72 }
56 } 73 }
74 // Don't know why this catch block is empty.
75 // Maybe to ignore errors if the file does not exist?
57 catch (Exception) { } 76 catch (Exception) { }
58 } 77 }
59 } 78 }
79 // Return the newest results first since that's how they are displayed.
60 results.Reverse(); 80 results.Reverse();
61 return results; 81 return results;
62 } 82 }
63 83
84 /// <summary>Removes old entries from the log.</summary>
64 public async void TrimLog() 85 public async void TrimLog()
65 { 86 {
87 // Delete entries older than this date.
66 DateTime maxAge = DateTime.Now.AddDays(-1 * Settings.Default.KeepLogDays); 88 DateTime maxAge = DateTime.Now.AddDays(-1 * Settings.Default.KeepLogDays);
67 string tempFile = logFile + ".tmp"; 89 string tempFile = logFile + ".tmp";
68 try 90 try
69 { 91 {
92 // Read through the log file and check the date of each entry.
93 // If it is newer than the max age, copy it to a temporary file.
70 using (FileStream stream = new FileStream(logFile, FileMode.Open, FileAccess.Read, FileShare.Read)) 94 using (FileStream stream = new FileStream(logFile, FileMode.Open, FileAccess.Read, FileShare.Read))
71 using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) 95 using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
72 using (FileStream outStream = new FileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.None)) 96 using (FileStream outStream = new FileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.None))
73 using (StreamWriter writer = new StreamWriter(outStream, Encoding.UTF8)) 97 using (StreamWriter writer = new StreamWriter(outStream, Encoding.UTF8))
74 { 98 {
85 } 109 }
86 } 110 }
87 catch (Exception) { } 111 catch (Exception) { }
88 } 112 }
89 } 113 }
114 // Delete the original file and rename the temporary file that contains only recent entries.
90 File.Delete(logFile); 115 File.Delete(logFile);
91 File.Move(tempFile, logFile); 116 File.Move(tempFile, logFile);
92 } 117 }
93 catch (FileNotFoundException) 118 catch (FileNotFoundException)
94 { 119 {