private void RunTestForLogFiltering(string testName, int n, int finalLogCode, int mainLogCode, int expectedMainLogMessages,
                                            int expectedFinalLogMessages, int expectedBulkLogMessages, EventBulkingOptions eventBulkingOptions)
        {
            Assert.True(finalLogCode != (mainLogCode - 1), "Test code constraint -1");

            TestLogConsumer logConsumer = new TestLogConsumer(output);

            var serviceProvider = new ServiceCollection().AddLogging(builder =>
                                                                     builder.AddLegacyOrleansLogging(new List <ILogConsumer>()
            {
                logConsumer
            }, null,
                                                                                                     eventBulkingOptions)
                                                                     .AddFile("Test.log"))
                                  .BuildServiceProvider();
            var logger = serviceProvider.GetService <ILoggerFactory>().CreateLogger(testName);

            var stopwatch = new Stopwatch();

            stopwatch.Start();
            int tmp = 0;

            for (int i = 0; i < n; i++)
            {
                logger.Warn(mainLogCode, "msg " + i);
                tmp = i;
            }

            // Wait until the BulkMessageInterval time interval expires before wring the final log message - should cause bulk message flush);
            TimeSpan delay = eventBulkingOptions.BulkEventInterval - stopwatch.Elapsed;

            if (delay > TimeSpan.Zero)
            {
                output.WriteLine("Sleeping for " + delay);
                Thread.Sleep(delay);
            }
            Thread.Sleep(50);

            logger.Info(finalLogCode, "Final msg");

            Assert.Equal(expectedMainLogMessages, logConsumer.GetEntryCount(mainLogCode));
            if (mainLogCode != finalLogCode)
            {
                Assert.Equal(expectedFinalLogMessages, logConsumer.GetEntryCount(finalLogCode));
            }
            Assert.Equal(expectedBulkLogMessages,
                         logConsumer.GetEntryCount(mainLogCode + BulkEventSummaryOffset));
            Assert.Equal(0, logConsumer.GetEntryCount(mainLogCode - 1));  //  "Should not see any other entries -1"
            //dispose log providers
            (serviceProvider as IDisposable)?.Dispose();
        }
        public void Logger_BulkMessageLimit_DebugNotFiltered()
        {
            const string testName         = "Logger_BulkMessageLimit_InfoNotFiltered";
            int          n                = 10000;
            var          bulkEventOptions = new EventBulkingOptions();

            bulkEventOptions.BulkEventInterval = TimeSpan.FromMilliseconds(5);

            int logCode1                 = 1;
            int expectedLogMessages1     = n + 2;
            int expectedBulkLogMessages1 = 0;

            TestLogConsumer logConsumer = new TestLogConsumer(output);
            //set minimum log level to debug
            var serviceProvider = new ServiceCollection().AddLogging(builder =>
                                                                     builder.AddLegacyOrleansLogging(new List <ILogConsumer>()
            {
                logConsumer
            }, null,
                                                                                                     bulkEventOptions)
                                                                     .AddFilter(logLevel => logLevel >= LogLevel.Debug))
                                  .BuildServiceProvider();
            var logger1 = serviceProvider.GetService <ILoggerFactory>().CreateLogger(testName);

            // Write log messages to logger #1
            for (int i = 0; i < n; i++)
            {
                logger1.Debug(logCode1, "Debug message " + (i + 1) + " to logger1");
            }

            // Wait until the BulkMessageInterval time interval expires before writing the final log message - should cause any pending message flush);
            Thread.Sleep(bulkEventOptions.BulkEventInterval);
            Thread.Sleep(50);

            logger1.Info(logCode1, "Penultimate message to logger1");
            logger1.Info(logCode1, "Final message to logger1");

            Assert.Equal(expectedBulkLogMessages1,
                         logConsumer.GetEntryCount(logCode1 + BulkEventSummaryOffset));
            Assert.Equal(expectedLogMessages1, logConsumer.GetEntryCount(logCode1));
            //dispose log providers
            (serviceProvider as IDisposable)?.Dispose();
        }
        public void Logger_BulkMessageLimit_DifferentLoggers()
        {
            int n = 10000;
            var bulkEventOptions = new EventBulkingOptions();

            bulkEventOptions.BulkEventInterval = TimeSpan.FromMilliseconds(50);

            int logCode1                 = 1;
            int logCode2                 = 2;
            int expectedLogMessages1     = bulkEventOptions.BulkEventLimit + 2 + 1;
            int expectedLogMessages2     = bulkEventOptions.BulkEventLimit + 2;
            int expectedBulkLogMessages1 = 0;
            int expectedBulkLogMessages2 = 1;

            TestLogConsumer logConsumer     = new TestLogConsumer(output);
            var             serviceProvider = new ServiceCollection().AddLogging(builder =>
                                                                                 builder.AddLegacyOrleansLogging(new List <ILogConsumer>()
            {
                logConsumer
            }, null,
                                                                                                                 bulkEventOptions))
                                              .BuildServiceProvider();
            var logger1 = serviceProvider.GetService <ILoggerFactory>().CreateLogger("logger1");
            var logger2 = serviceProvider.GetService <ILoggerFactory>().CreateLogger("logger2");

            // Write log messages to logger #1
            for (int i = 0; i < bulkEventOptions.BulkEventLimit; i++)
            {
                logger1.Warn(logCode1, "Message " + (i + 1) + " to logger1");
            }

            // Write to logger#2 using same logCode -- This should NOT trigger the bulk message for logCode1
            logger2.Warn(logCode1, "Use same logCode to logger2");

            // Wait until the BulkMessageInterval time interval expires before writing the final log message - should cause any pending message flush);
            Thread.Sleep(bulkEventOptions.BulkEventInterval);
            Thread.Sleep(50);

            // Write log messages to logger #2
            for (int i = 0; i < n; i++)
            {
                logger2.Warn(logCode2, "Message " + (i + 1) + " to logger2");
            }

            // Wait until the BulkMessageInterval time interval expires before writing the final log message - should cause any pending message flush);
            Thread.Sleep(bulkEventOptions.BulkEventInterval);
            Thread.Sleep(50);

            logger1.Info(logCode1, "Penultimate message to logger1");
            logger2.Info(logCode2, "Penultimate message to logger2");

            logger1.Info(logCode1, "Final message to logger1");
            logger2.Info(logCode2, "Final message to logger2");

            Assert.Equal(expectedBulkLogMessages1,
                         logConsumer.GetEntryCount(logCode1 + BulkEventSummaryOffset));
            Assert.Equal(expectedBulkLogMessages2,
                         logConsumer.GetEntryCount(logCode2 + BulkEventSummaryOffset));
            Assert.Equal(expectedLogMessages1, logConsumer.GetEntryCount(logCode1));
            Assert.Equal(expectedLogMessages2, logConsumer.GetEntryCount(logCode2));
            Assert.Equal(0, logConsumer.GetEntryCount(logCode1 - 1)); //  "Should not see any other entries -1"
            Assert.Equal(0, logConsumer.GetEntryCount(logCode2 + 1)); //  "Should not see any other entries +1"

            //dispose log providers
            (serviceProvider as IDisposable)?.Dispose();
        }