public void InitalizePaths()
 {
     TestHelper.InitalizePaths();
     TestHelper.PrepareLogFolder("Gzip");
     TestHelper.PrepareLogFolder("Termination");
     TestHelper.PrepareLogFolder("TerminationLost");
 }
        public void BinaryGzip_reconfiguration()
        {
            string folder = TestHelper.PrepareLogFolder(nameof(BinaryGzip_reconfiguration));
            var    h      = new Handlers.BinaryFileConfiguration()
            {
                Path = folder + @"\FirstPath",
                UseGzipCompression = false
            };
            var c = new GrandOutputConfiguration().AddHandler(h);

            var m = new ActivityMonitor(applyAutoConfigurations: false);

            using (GrandOutput g = new GrandOutput(c))
            {
                g.EnsureGrandOutputClient(m);

                m.Trace("No Compression.");
                // We must ensure that the log above will use the current configuration.
                // This is by design and is a good thing: there is no causality/ordering between log emission and sink reconfigurations.
                Thread.Sleep(100);

                h.UseGzipCompression = true;
                g.ApplyConfiguration(c, true);
                m.Trace("With Compression.");
                Thread.Sleep(100);

                h.Path = folder + @"\SecondPath";
                g.ApplyConfiguration(c, true);
                m.Trace("With Compression (in second folder).");
                Thread.Sleep(100);

                h.UseGzipCompression = false;
                g.ApplyConfiguration(c, true);
                m.Trace("No Compression (in second folder).");
            }
            // First file is NOT compressed, the second one is.
            var fileNamesFirst = Directory.EnumerateFiles(folder + @"\FirstPath").ToList();

            fileNamesFirst.Should().BeInAscendingOrder().And.HaveCount(2).And.NotContain(s => s.EndsWith(".tmp"), "Temporary files have been closed.");
            File.ReadAllText(fileNamesFirst[0]).Should().Contain("No Compression.");
            File.ReadAllText(fileNamesFirst[1]).Should().NotContain("With Compression.", "Cannot read it in clear text since it is compressed...");
            using (var reader = LogReader.Open(fileNamesFirst[1]))
            {
                reader.MoveNext().Should().BeTrue();
                reader.Current.Text.Should().Be("With Compression.");
            }
            // First file is compressed, not the second one.
            var fileNamesSecond = Directory.EnumerateFiles(folder + @"\SecondPath").ToList();

            fileNamesSecond.Should().BeInAscendingOrder().And.HaveCount(2).And.NotContain(s => s.EndsWith(".tmp"), "Temporary files have been closed.");
            File.ReadAllText(fileNamesSecond[0]).Should().NotContain("With Compression (in second folder).", "The fist file is compressed...");
            // We restrict the log entries to the one of our monitor: this filters out the logs from the DispatcherSink.
            using (var reader = LogReader.Open(fileNamesSecond[0], filter: new LogReader.MulticastFilter(m)))
            {
                reader.MoveNext().Should().BeTrue();
                reader.Current.Text.Should().Be("With Compression (in second folder).");
            }
            File.ReadAllText(fileNamesSecond[1]).Should().Contain("No Compression (in second folder).");
        }
        public void external_logs_filtering()
        {
            string folder = TestHelper.PrepareLogFolder("ExternalLogsFiltering");

            var textConf = new Handlers.TextFileConfiguration()
            {
                Path = "ExternalLogsFiltering"
            };
            var config = new GrandOutputConfiguration().AddHandler(textConf);

            ActivityMonitor.DefaultFilter.Line.Should().Be(LogLevelFilter.Trace);
            using (GrandOutput g = new GrandOutput(config))
            {
                g.ExternalLog(LogLevel.Debug, message: "NOSHOW");
                g.ExternalLog(LogLevel.Trace, message: "SHOW 0");
                g.ExternalLogLevelFilter = LogLevelFilter.Debug;
                g.ExternalLog(LogLevel.Debug, message: "SHOW 1");
                g.ExternalLogLevelFilter = LogLevelFilter.Error;
                g.ExternalLog(LogLevel.Warn, message: "NOSHOW");
                g.ExternalLog(LogLevel.Error, message: "SHOW 2");
                g.ExternalLog(LogLevel.Fatal, message: "SHOW 3");
                g.ExternalLog(LogLevel.Trace | LogLevel.IsFiltered, message: "SHOW 4");
                g.ExternalLogLevelFilter = LogLevelFilter.None;
                g.ExternalLog(LogLevel.Debug, message: "NOSHOW");
                g.ExternalLog(LogLevel.Trace, message: "SHOW 4");

                g.IsExternalLogEnabled(LogLevel.Debug).Should().BeFalse();
                g.IsExternalLogEnabled(LogLevel.Trace).Should().BeTrue();

                ActivityMonitor.Tags.AddFilter(_myTag, new LogClamper(LogFilter.Verbose, true));

                // Verbose allows Info, not Trace lines.
                g.ExternalLog(LogLevel.Info, _myTag, message: "SHOW 5");
                g.ExternalLog(LogLevel.Trace, _myTag, message: "NOSHOW");

                g.IsExternalLogEnabled(LogLevel.Info, _myTag).Should().BeTrue();
                g.IsExternalLogEnabled(LogLevel.Trace, _myTag).Should().BeFalse();

                ActivityMonitor.Tags.RemoveFilter(_myTag);

                g.IsExternalLogEnabled(LogLevel.Trace, _myTag).Should().BeTrue();
                g.ExternalLog(LogLevel.Trace, _myTag, message: "SHOW 6");
            }
            string textLogged = File.ReadAllText(Directory.EnumerateFiles(folder).Single());

            textLogged.Should()
            .Contain("SHOW 0")
            .And.Contain("SHOW 1")
            .And.Contain("SHOW 2")
            .And.Contain("SHOW 3")
            .And.Contain("SHOW 4")
            .And.Contain("SHOW 5")
            .And.Contain("SHOW 6")
            .And.NotContain("NOSHOW");
        }
        public void text_file_auto_delete_by_date()
        {
            string folder = TestHelper.PrepareLogFolder("AutoDelete_Date");

            var textConf = new Handlers.TextFileConfiguration()
            {
                Path = "AutoDelete_Date"
            };

            textConf.HousekeepingRate.Should().Be(1800, "Default HousekeepingRate configuration");
            textConf.MinimumDaysToKeep.Should().Be(60, "Default HousekeepingRate configuration");
            textConf.MinimumTimeSpanToKeep.Should().Be(TimeSpan.FromDays(60), "Default HousekeepingRate configuration");
            textConf.MaximumTotalKbToKeep.Should().Be(100_000, "Default HousekeepingRate configuration");

            // Change configuration for tests
            textConf.HousekeepingRate      = 1;                       // Run every 500ms normally (here TimerDuration is set to 100ms).
            textConf.MaximumTotalKbToKeep  = 0;                       // Always delete file beyond max size
            textConf.MinimumTimeSpanToKeep = TimeSpan.FromSeconds(3); // Delete files older than 3 seconds
            var config = new GrandOutputConfiguration().AddHandler(textConf);

            // Changes the default 500 ms to trigger OnTimerAsync more often.
            config.TimerDuration = TimeSpan.FromMilliseconds(100);

            // TEST DELETION BY DATE

            using (GrandOutput g = new GrandOutput(config))
            {
                var m = new ActivityMonitor(false);
                g.EnsureGrandOutputClient(m);
                Thread.Sleep(5);
                m.Info("Hello world");
                Thread.Sleep(30);

                string tempFile = Directory.EnumerateFiles(folder).Single();
                File.Exists(tempFile).Should().BeTrue("Log file was created and exists");

                // Wait for next flush (~100ms), and deletion threshold (3000ms)
                Thread.Sleep(3200);

                File.Exists(tempFile).Should().BeTrue("Log file wasn't deleted yet - it's still active");
            }
            string finalLogFile = Directory.EnumerateFiles(folder).Single();

            // Open another GrandOutput to trigger housekeeping
            using (GrandOutput g = new GrandOutput(config))
            {
                // Wait for next flush (~100 ms)
                Thread.Sleep(200);
            }

            File.Exists(finalLogFile).Should().BeFalse("Inactive log file was deleted");
        }
        public void text_file_auto_delete_by_size()
        {
            string folder = TestHelper.PrepareLogFolder("AutoDelete_Size");

            var textConf = new Handlers.TextFileConfiguration()
            {
                Path = "AutoDelete_Size"
            };

            // Change configuration for tests
            textConf.HousekeepingRate      = 1;             // Run every 500ms normally (here TimerDuration is set to 100ms).
            textConf.MaximumTotalKbToKeep  = 1;             // Always delete file beyond max size
            textConf.MinimumTimeSpanToKeep = TimeSpan.Zero; // Make minimum timespan
            var config = new GrandOutputConfiguration().AddHandler(textConf);

            int lineLengthToLogToGet1000bytes = 500;

            // Changes the default 500 ms to trigger OnTimerAsync more often.
            config.TimerDuration = TimeSpan.FromMilliseconds(100);

            // Create 3*1 KB log files
            for (int i = 0; i < 3; i++)
            {
                using (GrandOutput g = new GrandOutput(config))
                {
                    var m = new ActivityMonitor(false);
                    g.EnsureGrandOutputClient(m);
                    m.Info(new string( 'X', lineLengthToLogToGet1000bytes ));
                }
            }

            long GetTotalLogSize()
            {
                return(Directory.EnumerateFiles(folder).Sum(x => new FileInfo(x).Length));
            }

            var totalLogSize = GetTotalLogSize();

            totalLogSize.Should().BeGreaterThan(2500);

            // Open another GrandOutput to trigger housekeeping.
            // Note: this DOES create a file!
            using (GrandOutput g = new GrandOutput(config))
            {
                // Wait for next flush (~100 ms)
                Thread.Sleep(200);
            }
            var files = Directory.GetFiles(folder).Select(f => Path.GetFileName(f));

            files.Should().HaveCount(2, $"Only 2 files should be kept - the last log file, and 1x~1KB file: {files.Concatenate()}");
        }
Beispiel #6
0
        public void sending_log_from_client()
        {
            string logPath = TestHelper.PrepareLogFolder("sending_log_from_client");
            var    c       = new GrandOutputConfiguration()
                             .AddHandler(new Handlers.TextFileConfiguration()
            {
                Path = logPath
            })
                             .AddHandler(new Handlers.BinaryFileConfiguration()
            {
                Path = logPath
            });

            using (var g = new GrandOutput(c))
            {
                var m = new ActivityMonitor(false);
                g.EnsureGrandOutputClient(m);
                var txt = new StupidStringClient();
                m.Output.RegisterClient(txt);
                using (var r = SimpleLogPipeReceiver.Start(m, interProcess: false))
                {
                    RunClient(r.PipeName);
                    r.WaitEnd(false).Should().Be(LogReceiverEndStatus.Normal);
                }
                var stupidLogs = txt.ToString();
                stupidLogs.Should().Contain("From client.")
                .And.Contain("An Exception for the fun.")
                // StupidStringClient does not dump inner exception, only the top message.
                // .And.Contain( "With an inner exception!" )
                .And.Contain("Info n°0")
                .And.Contain("Info n°19");
            }
            // All temporary files have been closed.
            var fileNames = Directory.EnumerateFiles(logPath).ToList();

            fileNames.Should().NotContain(s => s.EndsWith(".tmp"));
            // Brutallity here: opening the binary file as a text.
            // It is enough to check the serialized strings.
            var texts = fileNames.Select(n => File.ReadAllText(n));

            foreach (var logs in texts)
            {
                logs.Should().Contain("From client.")
                .And.Contain("An Exception for the fun.")
                .And.Contain("With an inner exception!")
                .And.Contain("Info n°0")
                .And.Contain("Info n°19");
            }
        }
        public async Task external_logs_quick_test_Async()
        {
            string folder = TestHelper.PrepareLogFolder("ExternalLogsQuickTest");

            var textConf = new Handlers.TextFileConfiguration()
            {
                Path = "ExternalLogsQuickTest"
            };
            var config = new GrandOutputConfiguration().AddHandler(textConf);

            using (GrandOutput g = new GrandOutput(config))
            {
                await Task.Run(() =>
                {
                    ActivityMonitor.StaticLogger.Info($"Async started from ActivityMonitor.StaticLogger.");
                    g.ExternalLog(LogLevel.Info, message: "Async started.");
                });

                var m = new ActivityMonitor(false);
                g.EnsureGrandOutputClient(m);
                m.Info("Normal monitor starts.");
                Task t = Task.Run(() =>
                {
                    for (int i = 0; i < 10; ++i)
                    {
                        ActivityMonitor.StaticLogger.Info($"Async n°{i} from ActivityMonitor.StaticLogger.");
                        g.ExternalLog(LogLevel.Info, $"Async n°{i}.");
                    }
                });
                m.MonitorEnd("This is the end.");
                await t;
            }
            string textLogged = File.ReadAllText(Directory.EnumerateFiles(folder).Single());

            textLogged.Should()
            .Contain("Normal monitor starts.")
            .And.Contain("Async started from ActivityMonitor.StaticLogger.")
            .And.Contain("Async started.")
            .And.Contain("Async n°0.")
            .And.Contain("Async n°9.")
            .And.Contain("Async n°0 from ActivityMonitor.StaticLogger.")
            .And.Contain("Async n°9 from ActivityMonitor.StaticLogger.")
            .And.Contain("This is the end.");
        }
        public async Task CKMon_binary_files_can_be_GZip_compressed_Async()
        {
            string folder = TestHelper.PrepareLogFolder("Gzip");

            var c = new GrandOutputConfiguration()
                    .AddHandler(new Handlers.BinaryFileConfiguration()
            {
                Path = folder + @"\OutputGzip",
                UseGzipCompression = true
            })
                    .AddHandler(new Handlers.BinaryFileConfiguration()
            {
                Path = folder + @"\OutputRaw",
                UseGzipCompression = false
            });

            using (GrandOutput g = new GrandOutput(c))
            {
                var taskA = Task.Factory.StartNew(() => DumpMonitor1082Entries(CreateMonitorAndRegisterGrandOutput("Task A", g), 5), default, TaskCreationOptions.LongRunning, TaskScheduler.Default);
        public void text_file_auto_flush_and_reconfiguration()
        {
            string folder = TestHelper.PrepareLogFolder("AutoFlush");

            var textConf = new Handlers.TextFileConfiguration()
            {
                Path = "AutoFlush"
            };

            textConf.AutoFlushRate.Should().Be(6, "Default AutoFlushRate configuration.");

            // Avoid relying on the internal 500ms default.
            var config = new GrandOutputConfiguration {
                TimerDuration = TimeSpan.FromMilliseconds(500)
            }
            .AddHandler(textConf);

            using (GrandOutput g = new GrandOutput(config))
            {
                var m = new ActivityMonitor(false);
                g.EnsureGrandOutputClient(m);
                Thread.Sleep(5);
                m.Info("Must wait 3 seconds...");
                Thread.Sleep(700);
                string tempFile = Directory.EnumerateFiles(folder).Single();
                TestHelper.FileReadAllText(tempFile).Should().BeEmpty();
                Thread.Sleep(3000);
                TestHelper.FileReadAllText(tempFile).Should().Contain("Must wait 3 seconds...");

                textConf.AutoFlushRate = 1;
                m.Info("Reconfiguration triggers a flush...");
                Thread.Sleep(10);
                g.ApplyConfiguration(new GrandOutputConfiguration().AddHandler(textConf), waitForApplication: true);
                TestHelper.FileReadAllText(tempFile).Should().Contain("Reconfiguration triggers a flush...");
                m.Info("Wait only approx 500ms...");
                Thread.Sleep(700);
                string final = TestHelper.FileReadAllText(tempFile);
                final.Should().Contain("Wait only approx 500ms");
            }
        }
        public void dumping_text_file_with_multiple_monitors()
        {
            string folder = TestHelper.PrepareLogFolder("TextFileMulti");
            Random r      = new Random();
            GrandOutputConfiguration config = new GrandOutputConfiguration()
                                              .AddHandler(new Handlers.TextFileConfiguration()
            {
                Path = "TextFileMulti"
            });

            using (GrandOutput g = new GrandOutput(config))
            {
                Parallel.Invoke(
                    () => DumpSampleLogs1(r, g),
                    () => DumpSampleLogs1(r, g),
                    () => DumpSampleLogs1(r, g),
                    () => DumpSampleLogs1(r, g),
                    () => DumpSampleLogs1(r, g),
                    () => DumpSampleLogs1(r, g),
                    () => DumpSampleLogs1(r, g),
                    () => DumpSampleLogs1(r, g),
                    () => DumpSampleLogs2(r, g),
                    () => DumpSampleLogs1(r, g),
                    () => DumpSampleLogs1(r, g),
                    () => DumpSampleLogs1(r, g),
                    () => DumpSampleLogs1(r, g),
                    () => DumpSampleLogs1(r, g),
                    () => DumpSampleLogs2(r, g),
                    () => DumpSampleLogs1(r, g),
                    () => DumpSampleLogs1(r, g),
                    () => DumpSampleLogs1(r, g),
                    () => DumpSampleLogs2(r, g)
                    );
            }
            FileInfo f    = new DirectoryInfo(LogFile.RootLogPath + "TextFileMulti").EnumerateFiles().Single();
            string   text = File.ReadAllText(f.FullName);

            Console.WriteLine(text);
        }