view ServerMonitor/Objects/Logger.cs @ 6:c1dffaac66fa

- Don't show multiple password dialogs for the same key if the first one was cancelled. - Add option to trim log files.
author Brad Greco <brad@bgreco.net>
date Fri, 01 Mar 2019 21:38:22 -0500
parents 3e1a2131f897
children 7127d5b5ac75
line wrap: on
line source

using ServerMonitorApp.Properties;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ServerMonitorApp
{
    public class Logger
    {
        private const int logVersion = 1;
        private readonly string logFile;
        
        public Logger(string file)
        {
            logFile = file;
        }

        public async void Log(string logString)
        {
            if (!File.Exists(logFile))
                logString = "Server Monitor log version " + logVersion + Environment.NewLine + logString;
            using (FileStream stream = new FileStream(logFile, FileMode.Append, FileAccess.Write, FileShare.Read, 4096, true))
            using (StreamWriter writer = new StreamWriter(stream, Encoding.UTF8))
            {
                await writer.WriteLineAsync(logString);
            }
        }

        public void Log(CheckResult result)
        {
            Log(result.ToLogString());
        }

        public IList<CheckResult> Read(Server server)
        {
            Dictionary<int, Check> checks = server.Checks.ToDictionary(c => c.Id);
            List<CheckResult> results = new List<CheckResult>();
            using (FileStream stream = new FileStream(logFile, FileMode.Open, FileAccess.Read, FileShare.Read))
            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                while (true)
                {
                    try
                    {
                        string line = reader.ReadLine();
                        if (line == null)
                            break;
                        if (int.TryParse(line.Substring(0, 5), out int id) && checks.TryGetValue(id, out Check check))
                        {
                            results.Add(CheckResult.FromLogString(check, line));
                        }
                    }
                    catch (Exception) { }
                }
            }
            results.Reverse();
            return results;
        }

        public async void TrimLog()
        {
            DateTime maxAge = DateTime.Now.AddDays(-1 * Settings.Default.KeepLogDays);
            string tempFile = logFile + ".tmp";
            using (FileStream stream = new FileStream(logFile, FileMode.Open, FileAccess.Read, FileShare.Read))
            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            using (FileStream outStream = new FileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.None))
            using (StreamWriter writer = new StreamWriter(outStream, Encoding.UTF8))
            {
                while (true)
                {
                    try
                    {
                        string line = reader.ReadLine();
                        if (line == null)
                            break;
                        if (DateTime.TryParse(line.Substring(6, 10), out DateTime date) && date > maxAge)
                        {
                            await writer.WriteLineAsync(line);
                        }
                    }
                    catch (Exception) { }
                }
            }
            File.Delete(logFile);
            File.Move(tempFile, logFile);
        }
    }
}