Exemple #1
0
    public async Task WritesToTextFile()
    {
        var mockSystemDateTime = new MockSystemDateTime
        {
            Now = _today
        };
        var path = Path.Combine(TempPath, Path.GetRandomFileName());

        try
        {
            string fileName;
            var    options = new W3CLoggerOptions()
            {
                LogDirectory = path
            };
            await using (var logger = new FileLoggerProcessor(new OptionsWrapperMonitor <W3CLoggerOptions>(options), new HostingEnvironment(), NullLoggerFactory.Instance))
            {
                logger.SystemDateTime = mockSystemDateTime;
                logger.EnqueueMessage(_messageOne);
                fileName = Path.Combine(path, FormattableString.Invariant($"{options.FileName}{_today.Year:0000}{_today.Month:00}{_today.Day:00}.0000.txt"));
                // Pause for a bit before disposing so logger can finish logging
                await WaitForFile(fileName, _messageOne.Length).DefaultTimeout();
            }
            Assert.True(File.Exists(fileName));

            Assert.Equal(_messageOne + Environment.NewLine, File.ReadAllText(fileName));
        }
        finally
        {
            Helpers.DisposeDirectory(path);
        }
    }
Exemple #2
0
    public async Task StopsLoggingAfter10000Files()
    {
        var path = Path.Combine(TempPath, Path.GetRandomFileName());

        Directory.CreateDirectory(path);
        var mockSystemDateTime = new MockSystemDateTime
        {
            Now = _today
        };

        try
        {
            string lastFileName;
            var    options = new W3CLoggerOptions()
            {
                LogDirectory           = path,
                FileSizeLimit          = 5,
                RetainedFileCountLimit = 10000
            };
            var testSink   = new TestSink();
            var testLogger = new TestLoggerFactory(testSink, enabled: true);
            await using (var logger = new FileLoggerProcessor(new OptionsWrapperMonitor <W3CLoggerOptions>(options), new HostingEnvironment(), testLogger))
            {
                logger.SystemDateTime = mockSystemDateTime;
                for (int i = 0; i < 10000; i++)
                {
                    logger.EnqueueMessage(_messageOne);
                }
                lastFileName = Path.Combine(path, FormattableString.Invariant($"{options.FileName}{_today.Year:0000}{_today.Month:00}{_today.Day:00}.9999.txt"));
                await WaitForFile(lastFileName, _messageOne.Length).DefaultTimeout();

                // directory is full, no warnings yet
                Assert.Equal(0, testSink.Writes.Count);

                logger.EnqueueMessage(_messageOne);
                await WaitForCondition(() => testSink.Writes.FirstOrDefault()?.EventId.Name == "MaxFilesReached").DefaultTimeout();
            }

            Assert.Equal(10000, new DirectoryInfo(path)
                         .GetFiles()
                         .ToArray().Length);

            // restarting the logger should do nothing since the folder is still full
            var testSink2   = new TestSink();
            var testLogger2 = new TestLoggerFactory(testSink2, enabled: true);
            await using (var logger = new FileLoggerProcessor(new OptionsWrapperMonitor <W3CLoggerOptions>(options), new HostingEnvironment(), testLogger2))
            {
                Assert.Equal(0, testSink2.Writes.Count);

                logger.SystemDateTime = mockSystemDateTime;
                logger.EnqueueMessage(_messageOne);
                await WaitForCondition(() => testSink2.Writes.FirstOrDefault()?.EventId.Name == "MaxFilesReached").DefaultTimeout();
            }
        }
        finally
        {
            Helpers.DisposeDirectory(path);
        }
    }
Exemple #3
0
    public async Task RespectsMaxFileCount()
    {
        var path = Path.Combine(TempPath, Path.GetRandomFileName());

        Directory.CreateDirectory(path);
        File.WriteAllText(Path.Combine(path, "randomFile.txt"), "Text");
        var mockSystemDateTime = new MockSystemDateTime
        {
            Now = _today
        };

        try
        {
            string lastFileName;
            var    options = new W3CLoggerOptions()
            {
                LogDirectory           = path,
                RetainedFileCountLimit = 3,
                FileSizeLimit          = 5
            };
            await using (var logger = new FileLoggerProcessor(new OptionsWrapperMonitor <W3CLoggerOptions>(options), new HostingEnvironment(), NullLoggerFactory.Instance))
            {
                logger.SystemDateTime = mockSystemDateTime;
                for (int i = 0; i < 10; i++)
                {
                    logger.EnqueueMessage(_messageOne);
                }
                lastFileName = Path.Combine(path, FormattableString.Invariant($"{options.FileName}{_today.Year:0000}{_today.Month:00}{_today.Day:00}.0009.txt"));
                // Pause for a bit before disposing so logger can finish logging
                await WaitForFile(lastFileName, _messageOne.Length).DefaultTimeout();

                for (int i = 0; i < 6; i++)
                {
                    await WaitForRoll(Path.Combine(path, FormattableString.Invariant($"{options.FileName}{_today.Year:0000}{_today.Month:00}{_today.Day:00}.{i:0000}.txt"))).DefaultTimeout();
                }
            }

            var actualFiles = new DirectoryInfo(path)
                              .GetFiles()
                              .Select(f => f.Name)
                              .OrderBy(f => f)
                              .ToArray();

            Assert.Equal(4, actualFiles.Length);
            Assert.Equal("randomFile.txt", actualFiles[0]);
            for (int i = 1; i < 4; i++)
            {
                Assert.True((actualFiles[i].StartsWith($"{options.FileName}{_today.Year:0000}{_today.Month:00}{_today.Day:00}", StringComparison.InvariantCulture)));
            }
        }
        finally
        {
            Helpers.DisposeDirectory(path);
        }
    }
    public async Task WritesToNewFileOnOptionsChange()
    {
        var mockSystemDateTime = new MockSystemDateTime
        {
            Now = _today
        };

        var path = Path.Combine(TempPath, Path.GetRandomFileName());

        Directory.CreateDirectory(path);

        try
        {
            var options = new W3CLoggerOptions()
            {
                LogDirectory  = path,
                LoggingFields = W3CLoggingFields.Time,
                FileSizeLimit = 10000
            };
            var fileName1 = Path.Combine(path, FormattableString.Invariant($"{options.FileName}{_today.Year:0000}{_today.Month:00}{_today.Day:00}.0000.txt"));
            var fileName2 = Path.Combine(path, FormattableString.Invariant($"{options.FileName}{_today.Year:0000}{_today.Month:00}{_today.Day:00}.0001.txt"));
            var monitor   = new OptionsWrapperMonitor <W3CLoggerOptions>(options);

            await using (var logger = new FileLoggerProcessor(monitor, new HostingEnvironment(), NullLoggerFactory.Instance))
            {
                logger.SystemDateTime = mockSystemDateTime;
                logger.EnqueueMessage(_messageOne);
                await WaitForFile(fileName1, _messageOne.Length).DefaultTimeout();

                options.LoggingFields = W3CLoggingFields.Date;
                monitor.InvokeChanged();
                logger.EnqueueMessage(_messageTwo);
                // Pause for a bit before disposing so logger can finish logging
                await WaitForFile(fileName2, _messageTwo.Length).DefaultTimeout();
            }

            var actualFiles = new DirectoryInfo(path)
                              .GetFiles()
                              .Select(f => f.Name)
                              .OrderBy(f => f)
                              .ToArray();

            Assert.Equal(2, actualFiles.Length);

            Assert.True(File.Exists(fileName1));
            Assert.True(File.Exists(fileName2));

            Assert.Equal(_messageOne + Environment.NewLine, File.ReadAllText(fileName1));
            Assert.Equal(_messageTwo + Environment.NewLine, File.ReadAllText(fileName2));
        }
        finally
        {
            Helpers.DisposeDirectory(path);
        }
    }
Exemple #5
0
    public async Task RollsTextFilesBasedOnDate()
    {
        var mockSystemDateTime = new MockSystemDateTime
        {
            Now = _today
        };
        var tomorrow = _today.AddDays(1);

        var path    = Path.Combine(TempPath, Path.GetRandomFileName());
        var options = new W3CLoggerOptions()
        {
            LogDirectory = path
        };

        try
        {
            string fileNameToday;
            string fileNameTomorrow;

            await using (var logger = new FileLoggerProcessor(new OptionsWrapperMonitor <W3CLoggerOptions>(options), new HostingEnvironment(), NullLoggerFactory.Instance))
            {
                logger.SystemDateTime = mockSystemDateTime;
                logger.EnqueueMessage(_messageOne);

                fileNameToday = Path.Combine(path, FormattableString.Invariant($"{options.FileName}{_today.Year:0000}{_today.Month:00}{_today.Day:00}.0000.txt"));

                await WaitForFile(fileNameToday, _messageOne.Length).DefaultTimeout();

                mockSystemDateTime.Now = tomorrow;
                logger.EnqueueMessage(_messageTwo);

                fileNameTomorrow = Path.Combine(path, FormattableString.Invariant($"{options.FileName}{tomorrow.Year:0000}{tomorrow.Month:00}{tomorrow.Day:00}.0000.txt"));

                await WaitForFile(fileNameTomorrow, _messageTwo.Length).DefaultTimeout();
            }

            Assert.True(File.Exists(fileNameToday));
            Assert.Equal(_messageOne + Environment.NewLine, File.ReadAllText(fileNameToday));
            Assert.True(File.Exists(fileNameTomorrow));
            Assert.Equal(_messageTwo + Environment.NewLine, File.ReadAllText(fileNameTomorrow));
        }
        finally
        {
            Helpers.DisposeDirectory(path);
        }
    }
Exemple #6
0
    public async Task RollsTextFilesBasedOnSize()
    {
        var path = Path.Combine(TempPath, Path.GetRandomFileName());

        try
        {
            string filePath1;
            string filePath2;
            var    mockSystemDateTime = new MockSystemDateTime
            {
                Now = _today
            };
            var options = new W3CLoggerOptions()
            {
                LogDirectory  = path,
                FileSizeLimit = 5
            };
            await using (var logger = new FileLoggerProcessor(new OptionsWrapperMonitor <W3CLoggerOptions>(options), new HostingEnvironment(), NullLoggerFactory.Instance))
            {
                logger.SystemDateTime = mockSystemDateTime;
                logger.EnqueueMessage(_messageOne);
                logger.EnqueueMessage(_messageTwo);
                filePath1 = GetLogFilePath(path, options.FileName, _today, 0);
                filePath2 = GetLogFilePath(path, options.FileName, _today, 1);
                // Pause for a bit before disposing so logger can finish logging
                await WaitForFile(filePath2, _messageTwo.Length).DefaultTimeout();
            }
            Assert.True(File.Exists(filePath1));
            Assert.True(File.Exists(filePath2));

            Assert.Equal(_messageOne + Environment.NewLine, File.ReadAllText(filePath1));
            Assert.Equal(_messageTwo + Environment.NewLine, File.ReadAllText(filePath2));
        }
        finally
        {
            Helpers.DisposeDirectory(path);
        }
    }
Exemple #7
0
    public async Task RollsTextFilesWhenFirstLogOfDayIsMissing()
    {
        var mockSystemDateTime = new MockSystemDateTime
        {
            Now = _today
        };

        var path = Path.Combine(TempPath, Path.GetRandomFileName());

        Directory.CreateDirectory(path);

        try
        {
            var options = new W3CLoggerOptions()
            {
                LogDirectory           = path,
                FileSizeLimit          = 5,
                RetainedFileCountLimit = 2,
            };
            var fileName1 = Path.Combine(path, FormattableString.Invariant($"{options.FileName}{_today.Year:0000}{_today.Month:00}{_today.Day:00}.0000.txt"));
            var fileName2 = Path.Combine(path, FormattableString.Invariant($"{options.FileName}{_today.Year:0000}{_today.Month:00}{_today.Day:00}.0001.txt"));
            var fileName3 = Path.Combine(path, FormattableString.Invariant($"{options.FileName}{_today.Year:0000}{_today.Month:00}{_today.Day:00}.0002.txt"));
            var fileName4 = Path.Combine(path, FormattableString.Invariant($"{options.FileName}{_today.Year:0000}{_today.Month:00}{_today.Day:00}.0003.txt"));

            await using (var logger = new FileLoggerProcessor(new OptionsWrapperMonitor <W3CLoggerOptions>(options), new HostingEnvironment(), NullLoggerFactory.Instance))
            {
                logger.SystemDateTime = mockSystemDateTime;
                logger.EnqueueMessage(_messageOne);
                logger.EnqueueMessage(_messageTwo);
                logger.EnqueueMessage(_messageThree);
                // Pause for a bit before disposing so logger can finish logging
                await WaitForFile(fileName3, _messageThree.Length).DefaultTimeout();
            }

            // Even with a big enough FileSizeLimit, we still won't try to write to files from a previous instance.
            options.FileSizeLimit = 10000;

            await using (var logger = new FileLoggerProcessor(new OptionsWrapperMonitor <W3CLoggerOptions>(options), new HostingEnvironment(), NullLoggerFactory.Instance))
            {
                logger.SystemDateTime = mockSystemDateTime;
                logger.EnqueueMessage(_messageFour);
                // Pause for a bit before disposing so logger can finish logging
                await WaitForFile(fileName4, _messageFour.Length).DefaultTimeout();
            }

            var actualFiles = new DirectoryInfo(path)
                              .GetFiles()
                              .Select(f => f.Name)
                              .OrderBy(f => f)
                              .ToArray();

            Assert.Equal(2, actualFiles.Length);

            Assert.False(File.Exists(fileName1));
            Assert.False(File.Exists(fileName2));
            Assert.True(File.Exists(fileName3));
            Assert.True(File.Exists(fileName4));

            Assert.Equal(_messageThree + Environment.NewLine, File.ReadAllText(fileName3));
            Assert.Equal(_messageFour + Environment.NewLine, File.ReadAllText(fileName4));
        }
        finally
        {
            Helpers.DisposeDirectory(path);
        }
    }
Exemple #8
0
    public async Task InstancesWriteToSameDirectory()
    {
        var mockSystemDateTime = new MockSystemDateTime
        {
            Now = _today
        };

        var path = Path.Combine(TempPath, Path.GetRandomFileName());

        Directory.CreateDirectory(path);

        try
        {
            var options = new W3CLoggerOptions()
            {
                LogDirectory           = path,
                RetainedFileCountLimit = 10,
                FileSizeLimit          = 5
            };
            await using (var logger = new FileLoggerProcessor(new OptionsWrapperMonitor <W3CLoggerOptions>(options), new HostingEnvironment(), NullLoggerFactory.Instance))
            {
                logger.SystemDateTime = mockSystemDateTime;
                for (int i = 0; i < 3; i++)
                {
                    logger.EnqueueMessage(_messageOne);
                }
                var filePath = Path.Combine(path, FormattableString.Invariant($"{options.FileName}{_today.Year:0000}{_today.Month:00}{_today.Day:00}.0002.txt"));
                // Pause for a bit before disposing so logger can finish logging
                await WaitForFile(filePath, _messageOne.Length).DefaultTimeout();
            }

            // Second instance should pick up where first one left off
            await using (var logger = new FileLoggerProcessor(new OptionsWrapperMonitor <W3CLoggerOptions>(options), new HostingEnvironment(), NullLoggerFactory.Instance))
            {
                logger.SystemDateTime = mockSystemDateTime;
                for (int i = 0; i < 3; i++)
                {
                    logger.EnqueueMessage(_messageOne);
                }
                var filePath = Path.Combine(path, FormattableString.Invariant($"{options.FileName}{_today.Year:0000}{_today.Month:00}{_today.Day:00}.0005.txt"));
                // Pause for a bit before disposing so logger can finish logging
                await WaitForFile(filePath, _messageOne.Length).DefaultTimeout();
            }

            var actualFiles1 = new DirectoryInfo(path)
                               .GetFiles()
                               .Select(f => f.Name)
                               .OrderBy(f => f)
                               .ToArray();

            Assert.Equal(6, actualFiles1.Length);
            for (int i = 0; i < 6; i++)
            {
                Assert.Contains($"{options.FileName}{_today.Year:0000}{_today.Month:00}{_today.Day:00}.{i:0000}.txt", actualFiles1[i]);
            }

            // Third instance should roll to 5 most recent files
            options.RetainedFileCountLimit = 5;
            await using (var logger = new FileLoggerProcessor(new OptionsWrapperMonitor <W3CLoggerOptions>(options), new HostingEnvironment(), NullLoggerFactory.Instance))
            {
                logger.SystemDateTime = mockSystemDateTime;
                logger.EnqueueMessage(_messageOne);
                // Pause for a bit before disposing so logger can finish logging
                await WaitForFile(Path.Combine(path, FormattableString.Invariant($"{options.FileName}{_today.Year:0000}{_today.Month:00}{_today.Day:00}.0006.txt")), _messageOne.Length).DefaultTimeout();
                await WaitForRoll(Path.Combine(path, FormattableString.Invariant($"{options.FileName}{_today.Year:0000}{_today.Month:00}{_today.Day:00}.0000.txt"))).DefaultTimeout();
                await WaitForRoll(Path.Combine(path, FormattableString.Invariant($"{options.FileName}{_today.Year:0000}{_today.Month:00}{_today.Day:00}.0001.txt"))).DefaultTimeout();
            }

            var actualFiles2 = new DirectoryInfo(path)
                               .GetFiles()
                               .Select(f => f.Name)
                               .OrderBy(f => f)
                               .ToArray();

            Assert.Equal(5, actualFiles2.Length);
            for (int i = 0; i < 5; i++)
            {
                Assert.Equal($"{options.FileName}{_today.Year:0000}{_today.Month:00}{_today.Day:00}.{i + 2:0000}.txt", actualFiles2[i]);
            }
        }
        finally
        {
            Helpers.DisposeDirectory(path);
        }
    }
Exemple #9
0
    public async Task WritesToNewFileOnOptionsChange(bool fieldsChanged, bool headersChanged)
    {
        var mockSystemDateTime = new MockSystemDateTime
        {
            Now = _today
        };

        var path = Path.Combine(TempPath, Path.GetRandomFileName());

        Directory.CreateDirectory(path);

        try
        {
            var options = new W3CLoggerOptions()
            {
                LogDirectory  = path,
                LoggingFields = W3CLoggingFields.Time,
                FileSizeLimit = 10000,
            };
            options.AdditionalRequestHeaders.Add("one");
            var filePath1 = GetLogFilePath(path, options.FileName, _today, 0);
            var filePath2 = GetLogFilePath(path, options.FileName, _today, 1);
            var monitor   = new OptionsWrapperMonitor <W3CLoggerOptions>(options);

            await using (var logger = new FileLoggerProcessor(monitor, new HostingEnvironment(), NullLoggerFactory.Instance))
            {
                logger.SystemDateTime = mockSystemDateTime;
                logger.EnqueueMessage(_messageOne);
                await WaitForFile(filePath1, _messageOne.Length).DefaultTimeout();

                if (fieldsChanged)
                {
                    options.LoggingFields = W3CLoggingFields.Date;
                }

                if (headersChanged)
                {
                    options.AdditionalRequestHeaders.Remove("one");
                    options.AdditionalRequestHeaders.Add("two");
                }
                monitor.InvokeChanged();
                logger.EnqueueMessage(_messageTwo);
                // Pause for a bit before disposing so logger can finish logging
                await WaitForFile(filePath2, _messageTwo.Length).DefaultTimeout();
            }

            var actualFiles = new DirectoryInfo(path)
                              .GetFiles()
                              .Select(f => f.Name)
                              .OrderBy(f => f)
                              .ToArray();

            Assert.Equal(2, actualFiles.Length);

            Assert.True(File.Exists(filePath1));
            Assert.True(File.Exists(filePath2));

            Assert.Equal(_messageOne + Environment.NewLine, File.ReadAllText(filePath1));
            Assert.Equal(_messageTwo + Environment.NewLine, File.ReadAllText(filePath2));
        }
        finally
        {
            Helpers.DisposeDirectory(path);
        }
    }
Exemple #10
0
    public async Task WritesToNewFileOnNewInstance()
    {
        var mockSystemDateTime = new MockSystemDateTime
        {
            Now = _today
        };

        var path = Path.Combine(TempPath, Path.GetRandomFileName());

        Directory.CreateDirectory(path);

        try
        {
            var options = new W3CLoggerOptions()
            {
                LogDirectory  = path,
                FileSizeLimit = 5
            };
            var filePath1 = GetLogFilePath(path, options.FileName, _today, 0);
            var filePath2 = GetLogFilePath(path, options.FileName, _today, 1);
            var filePath3 = GetLogFilePath(path, options.FileName, _today, 2);

            await using (var logger = new FileLoggerProcessor(new OptionsWrapperMonitor <W3CLoggerOptions>(options), new HostingEnvironment(), NullLoggerFactory.Instance))
            {
                logger.SystemDateTime = mockSystemDateTime;
                logger.EnqueueMessage(_messageOne);
                logger.EnqueueMessage(_messageTwo);
                // Pause for a bit before disposing so logger can finish logging
                await WaitForFile(filePath2, _messageTwo.Length).DefaultTimeout();
            }

            // Even with a big enough FileSizeLimit, we still won't try to write to files from a previous instance.
            options.FileSizeLimit = 10000;

            await using (var logger = new FileLoggerProcessor(new OptionsWrapperMonitor <W3CLoggerOptions>(options), new HostingEnvironment(), NullLoggerFactory.Instance))
            {
                logger.SystemDateTime = mockSystemDateTime;
                logger.EnqueueMessage(_messageThree);
                // Pause for a bit before disposing so logger can finish logging
                await WaitForFile(filePath3, _messageThree.Length).DefaultTimeout();
            }

            var actualFiles = new DirectoryInfo(path)
                              .GetFiles()
                              .Select(f => f.Name)
                              .OrderBy(f => f)
                              .ToArray();

            Assert.Equal(3, actualFiles.Length);

            Assert.True(File.Exists(filePath1));
            Assert.True(File.Exists(filePath2));
            Assert.True(File.Exists(filePath3));

            Assert.Equal(_messageOne + Environment.NewLine, File.ReadAllText(filePath1));
            Assert.Equal(_messageTwo + Environment.NewLine, File.ReadAllText(filePath2));
            Assert.Equal(_messageThree + Environment.NewLine, File.ReadAllText(filePath3));
        }
        finally
        {
            Helpers.DisposeDirectory(path);
        }
    }