public void ConstructorWithNoParametersInitialisesDefaultsCorrectly()
        {
            LimitingTargetWrapper wrapper = new LimitingTargetWrapper();

            Assert.Equal(1000, wrapper.MessageLimit);
            Assert.Equal(TimeSpan.FromHours(1), wrapper.Interval);
        }
        public void CreatingFromConfigSetsIntervalCorrectly()
        {
            LoggingConfiguration config = CreateConfigurationFromString(@"
            <nlog>
                <targets>
                    <wrapper-target name='limiting' type='LimitingWrapper' interval='1:2:5:00'>
                        <target name='debug' type='Debug' layout='${message}' />
                    </wrapper-target>
                </targets>
                <rules>
                    <logger name='*' level='Debug' writeTo='limiting' />
                </rules>
            </nlog>");


            LimitingTargetWrapper limitingWrapper = (LimitingTargetWrapper)config.FindTargetByName("limiting");
            DebugTarget           debugTarget     = (DebugTarget)config.FindTargetByName("debug");

            Assert.NotNull(limitingWrapper);
            Assert.NotNull(debugTarget);
            Assert.Equal(1000, limitingWrapper.MessageLimit);
            Assert.Equal(TimeSpan.FromDays(1) + TimeSpan.FromHours(2) + TimeSpan.FromMinutes(5), limitingWrapper.Interval);

            LogManager.Configuration = config;
            ILogger logger = LogManager.GetLogger("A");

            logger.Debug("a");
            AssertDebugLastMessage("debug", "a");
        }
        public void WriteMessageAfterIntervalHasExpiredStartsNewInterval()
        {
            MyTarget wrappedTarget        = new MyTarget();
            LimitingTargetWrapper wrapper = new LimitingTargetWrapper(wrappedTarget, 5, TimeSpan.FromMilliseconds(100));

            InitializeTargets(wrappedTarget, wrapper);
            Exception lastException = null;

            wrapper.WriteAsyncLogEvent(
                new LogEventInfo(LogLevel.Debug, "test", "first interval").WithContinuation(ex => lastException = ex));

            //Let the interval expire.
            Thread.Sleep(100);

            //Writing a logEvent should start a new Interval. This should be written to InternalLogger.Debug.
            string internalLog = RunAndCaptureInternalLog(() =>
            {
                // We can write 5 messages again since a new interval started.
                lastException = WriteNumberAsyncLogEventsStartingAt(0, 5, wrapper);
            }, LogLevel.Trace);

            //We should have written 6 messages (1 in first interval and 5 in second interval).
            Assert.Equal(6, wrappedTarget.WriteCount);
            Assert.Contains("new interval", internalLog);
            Assert.Null(lastException);
        }
        public void ConstructorWithNameInitialisesDefaultsCorrectly()
        {
            MyTarget wrappedTarget        = new MyTarget();
            LimitingTargetWrapper wrapper = new LimitingTargetWrapper("Wrapper", wrappedTarget);

            Assert.Equal(1000, wrapper.MessageLimit);
            Assert.Equal(TimeSpan.FromHours(1), wrapper.Interval);
        }
        public void InitializeThrowsNLogConfigurationExceptionIfIntervalIsZero()
        {
            MyTarget wrappedTarget        = new MyTarget();
            LimitingTargetWrapper wrapper = new LimitingTargetWrapper(wrappedTarget)
            {
                Interval = TimeSpan.Zero
            };

            wrappedTarget.Initialize(null);
            LogManager.ThrowConfigExceptions = true;

            Assert.Throws <NLogConfigurationException>(() => wrapper.Initialize(null));
            LogManager.ThrowConfigExceptions = false;
        }
        public void InitializeThrowsNLogConfigurationExceptionIfMessageLimitIsSmallerZero()
        {
            MyTarget wrappedTarget        = new MyTarget();
            LimitingTargetWrapper wrapper = new LimitingTargetWrapper(wrappedTarget)
            {
                MessageLimit = -1
            };

            wrappedTarget.Initialize(null);
            LogManager.ThrowConfigExceptions = true;

            Assert.Throws <NLogConfigurationException>(() => wrapper.Initialize(null));
            LogManager.ThrowConfigExceptions = false;
        }
        public void TestWritingMessagesOverMultipleIntervals()
        {
            MyTarget wrappedTarget        = new MyTarget();
            LimitingTargetWrapper wrapper = new LimitingTargetWrapper(wrappedTarget, 5, TimeSpan.FromMilliseconds(100));

            InitializeTargets(wrappedTarget, wrapper);
            Exception lastException = null;

            lastException = WriteNumberAsyncLogEventsStartingAt(0, 10, wrapper);

            //Let the interval expire.
            Thread.Sleep(100);

            Assert.Equal(5, wrappedTarget.WriteCount);
            Assert.Equal("Hello 4", wrappedTarget.LastWrittenMessage);
            Assert.Null(lastException);

            lastException = WriteNumberAsyncLogEventsStartingAt(10, 10, wrapper);

            //We should have 10 messages (5 from first, 5 from second interval).
            Assert.Equal(10, wrappedTarget.WriteCount);
            Assert.Equal("Hello 14", wrappedTarget.LastWrittenMessage);
            Assert.Null(lastException);

            //Let the interval expire.
            Thread.Sleep(230);

            lastException = WriteNumberAsyncLogEventsStartingAt(20, 10, wrapper);

            //We should have 15 messages (5 from first, 5 from second, 5 from third interval).
            Assert.Equal(15, wrappedTarget.WriteCount);
            Assert.Equal("Hello 24", wrappedTarget.LastWrittenMessage);
            Assert.Null(lastException);

            //Let the interval expire.
            Thread.Sleep(20);
            lastException = WriteNumberAsyncLogEventsStartingAt(30, 10, wrapper);

            //No more messages shouldve been written, since we are still in the third interval.
            Assert.Equal(15, wrappedTarget.WriteCount);
            Assert.Equal("Hello 24", wrappedTarget.LastWrittenMessage);
            Assert.Null(lastException);
        }
        public void WriteMessagesLessThanMessageLimitWritesToWrappedTarget()
        {
            MyTarget wrappedTarget        = new MyTarget();
            LimitingTargetWrapper wrapper = new LimitingTargetWrapper(wrappedTarget, 5, TimeSpan.FromMilliseconds(100));

            InitializeTargets(wrappedTarget, wrapper);

            // Write limit number of messages should just write them to the wrappedTarget.
            WriteNumberAsyncLogEventsStartingAt(0, 5, wrapper);

            Assert.Equal(5, wrappedTarget.WriteCount);

            //Let the interval expire to start a new one.
            Thread.Sleep(100);

            // Write limit number of messages should just write them to the wrappedTarget.
            var lastException = WriteNumberAsyncLogEventsStartingAt(5, 5, wrapper);

            // We should have 10 messages (5 from first interval, 5 from second interval).
            Assert.Equal(10, wrappedTarget.WriteCount);
            Assert.Null(lastException);
        }
        public void WriteMoreMessagesThanMessageLimitDiscardsExcessMessages()
        {
            MyTarget wrappedTarget        = new MyTarget();
            LimitingTargetWrapper wrapper = new LimitingTargetWrapper(wrappedTarget, 5, TimeSpan.FromHours(1));

            InitializeTargets(wrappedTarget, wrapper);

            // Write limit number of messages should just write them to the wrappedTarget.
            var lastException = WriteNumberAsyncLogEventsStartingAt(0, 5, wrapper);

            Assert.Equal(5, wrappedTarget.WriteCount);

            //Additional messages will be discarded, but InternalLogger will write to trace.
            string internalLog = RunAndCaptureInternalLog(() =>
            {
                wrapper.WriteAsyncLogEvent(
                    new LogEventInfo(LogLevel.Debug, "test", $"Hello {5}").WithContinuation(ex => lastException = ex));
            }, LogLevel.Trace);

            Assert.Equal(5, wrappedTarget.WriteCount);
            Assert.Contains("MessageLimit", internalLog);
            Assert.Null(lastException);
        }