using System.Diagnostics.CodeAnalysis; using System.Text; using InABox.Core; namespace InABox.Logging; public class LogFileLogger : LoggerBase { private static readonly object logfileLock = new(); private string _folder; public string Folder { get => _folder; [MemberNotNull(nameof(_folder))] private set { _folder = value; } } private bool _trackSessions; private DateTime _sessionDay; private string? _sessionLogFileName; private string? _sessionJournalFileName; public LogFileLogger(string folder, bool trackSessions) { Folder = folder; _trackSessions = trackSessions; if (trackSessions) { if (!Directory.Exists(Folder)) { Directory.CreateDirectory(Folder); } } } private enum LogFileType { Log, Journal } private string SessionFileName(LogFileType logFile) { if (_trackSessions) { var date = DateTime.Today; if(_sessionLogFileName is not null && _sessionJournalFileName is not null && _sessionDay == date) { return logFile == LogFileType.Log ? _sessionLogFileName : _sessionJournalFileName; } _sessionLogFileName = Path.Combine(Folder, $"{date:yyyy-MM-dd}.log"); _sessionJournalFileName = Path.Combine(Folder, $"{date:yyyy-MM-dd}.sql"); if (File.Exists(_sessionLogFileName) || File.Exists(_sessionJournalFileName)) { var i = 1; do { _sessionLogFileName = Path.Combine(Folder, $"{date:yyyy-MM-dd}_{i:d3}.log"); _sessionJournalFileName = Path.Combine(Folder, $"{date:yyyy-MM-dd}_{i:d3}.sql"); ++i; } while (File.Exists(_sessionLogFileName) || File.Exists(_sessionJournalFileName)); } _sessionDay = date; return logFile == LogFileType.Log ? _sessionLogFileName : _sessionJournalFileName; } else { return logFile == LogFileType.Log ? Path.Combine(Folder, $"{DateTime.Today:yyyy-MM-dd}.log") : Path.Combine(Folder, $"{DateTime.Today:yyyy-MM-dd}.sql"); } } public override void Send(LogType logtype, string user, string message, Guid transaction) { if (logtype == LogType.Update) UpdateJournal(message); else base.Send(logtype, user, message, transaction); } protected override void DoSend(string message) { if (!string.IsNullOrEmpty(Folder)) { UpdateLogFile(message); } } private void UpdateLogFile(string msg) { if (!Directory.Exists(Folder)) Directory.CreateDirectory(Folder); var filename = SessionFileName(LogFileType.Log); try { lock (logfileLock) { using (var sw = new StreamWriter(filename, true, Encoding.UTF8, 65536)) { sw.WriteLine(msg); sw.Close(); } } } catch (Exception e) { Console.WriteLine("*** Failed to Update Log: " + e.Message); Console.WriteLine("*** Message: " + msg); } } private void UpdateJournal(string sql) { var filename = SessionFileName(LogFileType.Journal); try { lock (logfileLock) { using (var sw = new StreamWriter(filename, true, Encoding.UTF8, 65536)) { sw.WriteLine(sql); sw.Close(); } } } catch (Exception e) { Console.WriteLine("*** Failed to Update SQL Journal: " + e.Message); Console.WriteLine("*** Message: " + sql); } } }