public async Task LoggingSource_WhileLogging_ShouldNotLoseLogFile(bool compressing) { var name = GetTestName(); var path = NewDataPath(forceCreateDir: true); var retentionTime = TimeSpan.MaxValue; var retentionSize = long.MaxValue; var loggingSource = new LoggingSource( LogMode.Information, path, "LoggingSource" + name, retentionTime, retentionSize, compressing); loggingSource.MaxFileSizeInBytes = 1024; //This is just to make sure the MaxFileSizeInBytes is get action for the first file loggingSource.SetupLogMode(LogMode.Operations, path, retentionTime, retentionSize, compressing); var logger = new Logger(loggingSource, "Source" + name, "Logger" + name); for (var i = 0; i < 1000; i++) { await logger.OperationsAsync("Some message"); } var beforeEndFiles = Directory.GetFiles(path); loggingSource.EndLogging(); var afterEndFiles = Directory.GetFiles(path); AssertNoFileMissing(beforeEndFiles); AssertNoFileMissing(afterEndFiles); }
public async Task LoggingSource_WhileRetentionBySizeOn_ShouldKeepRetentionPolicy(bool compressing) { const int fileSize = Constants.Size.Kilobyte; const int retentionSize = 5 * Constants.Size.Kilobyte; var name = GetTestName(); var path = NewDataPath(forceCreateDir: true); var retentionTime = TimeSpan.MaxValue; var loggingSource = new LoggingSource( LogMode.Information, path, "LoggingSource" + name, retentionTime, retentionSize, compressing); loggingSource.MaxFileSizeInBytes = fileSize; //This is just to make sure the MaxFileSizeInBytes is get action for the first file loggingSource.SetupLogMode(LogMode.Operations, path, retentionTime, retentionSize, compressing); var logger = new Logger(loggingSource, "Source" + name, "Logger" + name); for (var i = 0; i < 100; i++) { for (var j = 0; j < 5; j++) { await logger.OperationsAsync("Some message"); } Thread.Sleep(10); } const int threshold = 2 * fileSize; long size = 0; string[] afterEndFiles = null; var isRetentionPolicyApplied = WaitForValue(() => { Task.Delay(TimeSpan.FromSeconds(1)); afterEndFiles = Directory.GetFiles(path); AssertNoFileMissing(afterEndFiles); size = afterEndFiles.Select(f => new FileInfo(f)).Sum(f => f.Length); return(Math.Abs(size - retentionSize) <= threshold); }, true, 10_000, 1_000); Assert.True(isRetentionPolicyApplied, $"ActualSize({size}), retentionSize({retentionSize}), threshold({threshold})" + Environment.NewLine + JustFileNamesAsString(afterEndFiles)); loggingSource.EndLogging(); }
public async Task LoggingSource_WhenExistFileFromToday_ShouldIncrementNumberByOne(string extension) { const int fileSize = Constants.Size.Kilobyte; var testName = GetTestName(); var path = NewDataPath(forceCreateDir: true); path = Path.Combine(path, Guid.NewGuid().ToString("N")); Directory.CreateDirectory(path); const long retentionSize = long.MaxValue; var retentionTimeConfiguration = TimeSpan.FromDays(3); var now = DateTime.Now; var existLog = Path.Combine(path, $"{LoggingSource.LogInfo.DateToLogFormat(now)}.010.{extension}"); await using (var file = File.Create(existLog)) { file.SetLength(fileSize); } var loggingSource = new LoggingSource( LogMode.Information, path, "LoggingSource" + testName, retentionTimeConfiguration, retentionSize) { MaxFileSizeInBytes = fileSize }; //This is just to make sure the MaxFileSizeInBytes is get action for the first file loggingSource.SetupLogMode(LogMode.Operations, path, retentionTimeConfiguration, retentionSize, false); var logger = new Logger(loggingSource, "Source" + testName, "Logger" + testName); await logger.OperationsAsync("Some message"); var result = WaitForValue(() => { var strings = Directory.GetFiles(path); return(strings.Any(f => { if (LoggingSource.LogInfo.TryGetDate(f, out var d) == false || d.Date.Equals(DateTime.Today) == false) { return false; } return LoggingSource.LogInfo.TryGetNumber(f, out var n) && n == 11; })); }, true, 10_000, 1_000); Assert.True(result); loggingSource.EndLogging(); }
public async Task LoggingSource_WhileRetentionByTimeOn_ShouldKeepRetentionPolicy(bool compressing) { const int fileSize = Constants.Size.Kilobyte; var name = GetTestName(); var path = NewDataPath(forceCreateDir: true); path = Path.Combine(path, Guid.NewGuid().ToString()); Directory.CreateDirectory(path); var retentionTime = TimeSpan.FromDays(3); var retentionDate = DateTime.Now.Date - retentionTime; var toCheckLogFiles = new List <(string, bool)>(); for (var date = retentionDate - TimeSpan.FromDays(1); date <= retentionDate + TimeSpan.FromDays(1); date += TimeSpan.FromDays(1)) { var fileName = Path.Combine(path, LoggingSource.LogInfo.GetFileName(date) + ".001.log"); toCheckLogFiles.Add((fileName, date >= retentionDate)); var file = File.Create(fileName); file.Dispose(); } var retentionSize = long.MaxValue; var loggingSource = new LoggingSource( LogMode.Information, path, "LoggingSource" + name, retentionTime, retentionSize, compressing); loggingSource.MaxFileSizeInBytes = fileSize; //This is just to make sure the MaxFileSizeInBytes is get action for the first file loggingSource.SetupLogMode(LogMode.Operations, path, retentionTime, retentionSize, compressing); var logger = new Logger(loggingSource, "Source" + name, "Logger" + name); for (var j = 0; j < 50; j++) { for (var i = 0; i < 5; i++) { await logger.OperationsAsync("Some message"); } Thread.Sleep(10); } loggingSource.EndLogging(); var afterEndFiles = Directory.GetFiles(path); AssertNoFileMissing(afterEndFiles); try { foreach (var(fileName, shouldExist) in toCheckLogFiles) { var compressedFileName = fileName + ".gz"; if (shouldExist) { Assert.True(afterEndFiles.Contains(fileName) || afterEndFiles.Contains(compressedFileName), $"The log file \"{Path.GetFileNameWithoutExtension(fileName)}\" and all log files from and after {retentionDate} " + "should be deleted due to time retention"); } else { Assert.False(afterEndFiles.Contains(fileName), $"The file \"{fileName}\" and all log files from before {retentionDate} should be deleted due to time retention"); Assert.False(afterEndFiles.Contains(compressedFileName), $"The file \"{compressedFileName}\" and all log files from before {retentionDate} should be deleted due to time retention"); } } } catch (Exception e) { throw new InvalidOperationException($"Logs after end - {JustFileNamesAsString(afterEndFiles)}", e); } }
public async Task LoggingSource_WhileStopAndStartAgain_ShouldNotOverrideOld(bool compressing) { const int taskTimeout = 10000; var name = GetTestName(); var path = NewDataPath(forceCreateDir: true); var retentionTime = TimeSpan.MaxValue; var retentionSize = long.MaxValue; var firstLoggingSource = new LoggingSource( LogMode.Information, path, "FirstLoggingSource" + name, retentionTime, retentionSize, compressing); firstLoggingSource.MaxFileSizeInBytes = 1024; //This is just to make sure the MaxFileSizeInBytes is get action for the first file firstLoggingSource.SetupLogMode(LogMode.Operations, path, retentionTime, retentionSize, compressing); try { var logger = new Logger(firstLoggingSource, "Source" + name, "Logger" + name); for (var i = 0; i < 100; i++) { var task = logger.OperationsAsync("Some message"); await Task.WhenAny(task, Task.Delay(taskTimeout)); if (task.IsCompleted == false) { throw new TimeoutException($"The log task took more then one second"); } } } finally { firstLoggingSource.EndLogging(); } var beforeRestartFiles = Directory.GetFiles(path); var restartDateTime = DateTime.Now; Exception anotherThreadException = null; //To start new LoggingSource the object need to be construct on another thread var anotherThread = new Thread(() => { var secondLoggingSource = new LoggingSource( LogMode.Information, path, "SecondLoggingSource" + name, retentionTime, retentionSize); try { secondLoggingSource.MaxFileSizeInBytes = 1024; var secondLogger = new Logger(secondLoggingSource, "Source" + name, "Logger" + name); for (var i = 0; i < 100; i++) { var task = secondLogger.OperationsAsync("Some message"); Task.WhenAny(task, Task.Delay(taskTimeout)).GetAwaiter().GetResult(); if (task.IsCompleted == false) { throw new TimeoutException($"The log task took more then one second"); } } } catch (Exception e) { anotherThreadException = e; } finally { secondLoggingSource.EndLogging(); } }); anotherThread.Start(); anotherThread.Join(); if (anotherThreadException != null) { throw anotherThreadException; } foreach (var file in beforeRestartFiles.OrderBy(f => f).SkipLast(1)) //The last is skipped because it is still written { var lastWriteTime = File.GetLastWriteTime(file); Assert.True( restartDateTime > lastWriteTime, $"{file} was changed (time:" + $"{lastWriteTime.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture)}) after the restart (time:" + $"{restartDateTime.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture)})" + Environment.NewLine + JustFileNamesAsString(beforeRestartFiles)); } }
public async Task LoggingSource_WhileRetentionByTimeInHours_ShouldKeepRetentionPolicy(bool compressing) { const int fileSize = Constants.Size.Kilobyte; var name = GetTestName(); var path = NewDataPath(forceCreateDir: true); path = Path.Combine(path, Guid.NewGuid().ToString()); Directory.CreateDirectory(path); var retentionTimeConfiguration = TimeSpan.FromHours(3); var now = DateTime.Now; var retentionTime = now - retentionTimeConfiguration; var toCheckLogFiles = new List <(string fileName, bool shouldExist)>(); const int artificialLogsCount = 9; for (int i = 0; i < artificialLogsCount; i++) { var lastModified = now - TimeSpan.FromHours(i); var fileName = Path.Combine(path, $"{LoggingSource.LogInfo.DateToLogFormat(lastModified)}.00{artificialLogsCount - i}.log"); toCheckLogFiles.Add((fileName, lastModified > retentionTime)); await using (File.Create(fileName)) { } File.SetLastWriteTime(fileName, lastModified); } const long retentionSize = long.MaxValue; var loggingSource = new LoggingSource( LogMode.Information, path, "LoggingSource" + name, retentionTimeConfiguration, retentionSize, compressing) { MaxFileSizeInBytes = fileSize }; //This is just to make sure the MaxFileSizeInBytes is get action for the first file loggingSource.SetupLogMode(LogMode.Operations, path, retentionTimeConfiguration, retentionSize, compressing); var logger = new Logger(loggingSource, "Source" + name, "Logger" + name); for (var j = 0; j < 50; j++) { for (var i = 0; i < 5; i++) { await logger.OperationsWithWait("Some message"); } Thread.Sleep(10); } string[] afterEndFiles = null; await WaitForValueAsync(async() => { for (var i = 0; i < 10; i++) { await logger.OperationsWithWait("Some message"); } afterEndFiles = Directory.GetFiles(path); return(DoesContainFilesThatShouldNotBeFound(afterEndFiles, toCheckLogFiles, compressing)); }, false, 10_000, 1_000); loggingSource.EndLogging(); AssertNoFileMissing(afterEndFiles); try { Assert.All(toCheckLogFiles, toCheck => { (string fileName, bool shouldExist) = toCheck; fileName = $"{fileName}{(compressing ? ".gz" : string.Empty)}"; var fileInfo = new FileInfo(fileName); if (shouldExist) { Assert.True(fileInfo.Exists, $"The log file \"{fileInfo.Name}\" should be exist"); } else { Assert.False(fileInfo.Exists, $"The log file \"{fileInfo.Name}\" last modified {fileInfo.LastWriteTime} should not be exist. retentionTime({retentionTime})"); } }); } catch (Exception e) { throw new InvalidOperationException($"Logs after end - {JustFileNamesAsString(afterEndFiles)}", e); } }
public async Task LoggingSource_WhileRetentionBySizeOn_ShouldKeepRetentionPolicy(bool compressing) { const int fileSize = Constants.Size.Kilobyte; const int retentionSize = 5 * Constants.Size.Kilobyte; var name = GetTestName(); var path = NewDataPath(forceCreateDir: true); var retentionTime = TimeSpan.MaxValue; var loggingSource = new LoggingSource( LogMode.Information, path, "LoggingSource" + name, retentionTime, retentionSize, compressing); loggingSource.MaxFileSizeInBytes = fileSize; //This is just to make sure the MaxFileSizeInBytes is get action for the first file loggingSource.SetupLogMode(LogMode.Operations, path, retentionTime, retentionSize, compressing); var logger = new Logger(loggingSource, "Source" + name, "Logger" + name); for (var i = 0; i < 100; i++) { for (var j = 0; j < 5; j++) { await logger.OperationsAsync("Some message"); } Thread.Sleep(10); } var sw = Stopwatch.StartNew(); while (true) { await Task.Delay(TimeSpan.FromSeconds(1)); var afterEndFiles = Directory.GetFiles(path); AssertNoFileMissing(afterEndFiles); var size = afterEndFiles.Select(f => new FileInfo(f)).Sum(f => f.Length); const int threshold = 2 * fileSize; if (Math.Abs(size - retentionSize) <= threshold) { break; } if (sw.Elapsed < TimeSpan.FromSeconds(10)) { continue; } Assert.True(false, $"ActualSize({size}), retentionSize({retentionSize}), threshold({threshold})" + Environment.NewLine + JustFileNamesAsString(afterEndFiles)); } loggingSource.EndLogging(); }