예제 #1
0
        public SingleFileMuxer(
            [NotNull] IEventsWriterProviderFactory writerProviderFactory,
            [NotNull] ISingleFileWorker worker,
            [NotNull] FileLogSettings settings)
        {
            this.settings = settings;
            this.worker   = worker;

            writerProvider = writerProviderFactory.CreateProvider(settings.FilePath, () => this.settings);

            eventsQueue = new Lazy <ConcurrentBoundedQueue <LogEventInfo> >(
                () => new ConcurrentBoundedQueue <LogEventInfo>(settings.EventsQueueCapacity),
                LazyThreadSafetyMode.ExecutionAndPublication);

            eventsBuffer = new Lazy <LogEventInfo[]>(
                () => new LogEventInfo[settings.EventsBufferCapacity],
                LazyThreadSafetyMode.ExecutionAndPublication);

            eventsLostCurrently          = new AtomicLong(0);
            eventsLostSinceLastIteration = new AtomicLong(0);

            flushSignal  = new AsyncManualResetEvent(true);
            flushWaiters = new List <Waiter>();

            workerInitLock           = new object();
            workerCancellationWaiter = new Waiter(TaskCreationOptions.RunContinuationsAsynchronously);
            workerCancellation       = new CancellationTokenSource();
            workerCancellation.Token.Register(() => workerCancellationWaiter.TrySetResult(true));
        }
        public SynchronousSingleFileMuxer(
            [NotNull] IEventsWriterProviderFactory writerProviderFactory,
            [NotNull] FileLogSettings settings)
        {
            this.settings = settings;

            buffer             = new LogEventInfo[1];
            workerCancellation = new CancellationTokenSource();
            writerProvider     = writerProviderFactory.CreateProvider(settings.FilePath, () => this.settings);
        }
        public void TestSetup()
        {
            eventsWriter = Substitute.For <IEventsWriter>();

            eventsWriterProvider = Substitute.For <IEventsWriterProvider>();
            eventsWriterProvider.ObtainWriterAsync(Arg.Any <CancellationToken>()).Returns(Task.FromResult(eventsWriter));

            writerProviderFactory = Substitute.For <IEventsWriterProviderFactory>();
            writerProviderFactory.CreateProvider(Arg.Any <FilePath>(), Arg.Any <Func <FileLogSettings> >()).Returns(eventsWriterProvider);

            muxer = new SynchronousSingleFileMuxer(writerProviderFactory, new FileLogSettings());
        }
예제 #4
0
        public void TestSetup()
        {
            writer = Substitute.For <IEventsWriter>();

            writerProvider = Substitute.For <IEventsWriterProvider>();
            writerProvider.ObtainWriterAsync(Arg.Any <CancellationToken>()).Returns(writer);

            worker = new SingleFileWorker();

            events     = new ConcurrentBoundedQueue <LogEventInfo>(2);
            buffer     = new LogEventInfo[1];
            eventsLost = new AtomicLong(0);
        }
        public void Dispose()
        {
            if (writerProvider == null)
            {
                return;
            }

            workerCancellation.Cancel();

            lock (sync)
            {
                writerProvider.Dispose();
                writerProvider = null;
                workerCancellation.Dispose();
            }
        }
예제 #6
0
        public void TestSetup()
        {
            eventsWriter = Substitute.For <IEventsWriter>();

            eventsWriterProvider = Substitute.For <IEventsWriterProvider>();
            eventsWriterProvider.ObtainWriterAsync(Arg.Any <CancellationToken>()).Returns(Task.FromResult(eventsWriter));

            writerProviderFactory = Substitute.For <IEventsWriterProviderFactory>();
            writerProviderFactory.CreateProvider(Arg.Any <FilePath>(), Arg.Do <Func <FileLogSettings> >(x => settingsInsideMuxer = x)).Returns(eventsWriterProvider);

            singleFileWorker = Substitute.For <ISingleFileWorker>();
            singleFileWorker.WritePendingEventsAsync(
                Arg.Any <IEventsWriterProvider>(),
                Arg.Any <ConcurrentBoundedQueue <LogEventInfo> >(),
                Arg.Any <LogEventInfo[]>(),
                Arg.Any <AtomicLong>(),
                Arg.Any <AtomicLong>(),
                Arg.Any <CancellationToken>())
            .Returns(Task.FromResult(true));

            muxer = new SingleFileMuxer(writerProviderFactory, singleFileWorker, new FileLogSettings());
        }
예제 #7
0
        public async Task <bool> WritePendingEventsAsync(
            IEventsWriterProvider writerProvider,
            ConcurrentBoundedQueue <LogEventInfo> queue,
            LogEventInfo[] buffer,
            AtomicLong eventsLostCurrently,
            AtomicLong eventsLostSinceLastIteration,
            CancellationToken cancellation)
        {
            var eventsToDrain = queue.Count;

            if (eventsToDrain == 0)
            {
                return(true);
            }

            var writer = await writerProvider.ObtainWriterAsync(cancellation).ConfigureAwait(false);

            if (writer == null)
            {
                return(false);
            }

            while (eventsToDrain > 0)
            {
                var eventsDrained = queue.Drain(buffer, 0, buffer.Length);
                if (eventsDrained == 0)
                {
                    break;
                }

                eventsToDrain -= eventsDrained;

                try
                {
                    writer.WriteEvents(buffer, eventsDrained);
                }
                catch (Exception error)
                {
                    eventsLostCurrently.Add(eventsDrained);

                    SafeConsole.ReportError("Failure in writing log events to a file:", error);

                    break;
                }
                finally
                {
                    Array.Clear(buffer, 0, eventsDrained);
                }
            }

            var lostEventsAfterWriting = eventsLostCurrently.Value;

            if (lostEventsAfterWriting > eventsLostSinceLastIteration)
            {
                buffer[0] = CreateOverflowEvent(queue, lostEventsAfterWriting - eventsLostSinceLastIteration);

                try
                {
                    writer.WriteEvents(buffer, 1);
                }
                catch
                {
                    // ignored
                }

                eventsLostSinceLastIteration.Value = lostEventsAfterWriting;

                return(false);
            }

            return(true);
        }