示例#1
0
        public void UpdateLineNumbers(ILogFile logFile, LogFileSection visibleSection, double yOffset)
        {
            int lineNumberCharacterCount;
            if (logFile != null)
            {
                lineNumberCharacterCount = (int)Math.Ceiling(Math.Log10(logFile.Count));
            }
            else
            {
                lineNumberCharacterCount = 0;
            }

            // We always reserve space for at least 3 characters.
            _lineNumberWidth = TextHelper.EstimateWidthUpperLimit(Math.Max(lineNumberCharacterCount, 3));
            Width = _lineNumberWidth + TextHelper.LineNumberSpacing;

            _yOffset = yOffset;

            _lineNumbers.Clear();
            for (int i = 0; i < visibleSection.Count; ++i)
            {
                _lineNumbers.Add(new LineNumber(visibleSection.Index + i));
            }
            InvalidateVisual();
        }
 public void Invalidate(int firstIndex, int count)
 {
     int lastIndex = Math.Min(firstIndex + count, _lastNumberOfLines);
     int invalidateCount = lastIndex - firstIndex;
     // When the start index of the invalidation is greater than the last reported index
     // then this means that our listeners haven't even gotten the change yet and thus
     // they don't need to be notified of the invalidation either.
     if (invalidateCount > 0)
     {
         var section = new LogFileSection(firstIndex, invalidateCount, true);
         _listener.OnLogFileModified(_logFile, section);
         _lastNumberOfLines = firstIndex;
     }
 }
示例#3
0
        public void TestManyEntries5()
        {
            var logFile = new MultiLineLogFile(_taskScheduler, _source.Object, TimeSpan.Zero);

            _lines.Add(new LogLine(0, 0, "Foo", LevelFlags.Other));
            _lines.Add(new LogLine(1, 1, "Bar", LevelFlags.Other));
            _lines.Add(new LogLine(2, 2, "INFO: Sup", LevelFlags.Info));
            logFile.OnLogFileModified(_source.Object, new LogFileSection(0, 3));
            logFile.OnLogFileModified(_source.Object, LogFileSection.Invalidate(1, 2));
            logFile.OnLogFileModified(_source.Object, new LogFileSection(1, 2));
            _taskScheduler.RunOnce();
            logFile.Count.Should().Be(3);
            var entries = logFile.GetSection(new LogFileSection(0, 3));

            entries.Should().Equal(new object[]
            {
                new LogLine(0, 0, "Foo", LevelFlags.Other),
                new LogLine(1, 0, "Bar", LevelFlags.Other),
                new LogLine(2, 1, "INFO: Sup", LevelFlags.Info)
            });
        }
示例#4
0
        public void TestListen3()
        {
            using (var proxy = new LogFileProxy(_scheduler, TimeSpan.Zero, _logFile.Object))
            {
                proxy.AddListener(_listener.Object, TimeSpan.Zero, 1000);

                _listeners.OnRead(500);
                _listeners.Invalidate(400, 100);
                _listeners.OnRead(550);

                _scheduler.RunOnce();

                _modifications.Should().Equal(new[]
                {
                    LogFileSection.Reset,
                    new LogFileSection(0, 500),
                    LogFileSection.Invalidate(400, 100),
                    new LogFileSection(400, 150)
                });
            }
        }
示例#5
0
        public void TestOneEntry3()
        {
            var logFile = new MultiLineLogFile(_taskScheduler, _source.Object, TimeSpan.Zero);

            logFile.AddListener(_listener.Object, TimeSpan.Zero, 10);

            _lines.Add(new LogLine(0, 0, "INFO: hello", LevelFlags.Info));
            logFile.OnLogFileModified(_source.Object, new LogFileSection(0, 1));
            _taskScheduler.RunOnce();
            _changes.Should().Equal(new object[] { LogFileSection.Reset, new LogFileSection(0, 1) });

            _changes.Clear();
            _lines.Add(new LogLine(1, 1, "world!", LevelFlags.None));
            logFile.OnLogFileModified(_source.Object, new LogFileSection(1, 1));
            _taskScheduler.RunOnce();
            _changes.Should().Equal(new object[]
            {
                LogFileSection.Invalidate(0, 1),
                new LogFileSection(0, 2)
            });
        }
示例#6
0
        private void Add(ILogFile logFile, LogFileSection section)
        {
            // !!!We deliberately retrieve this section OUTSIDE of our own lock!!!
            logFile.GetEntries(section, _buffer);

            // Calculating the max width of a line takes time and is therefore done outside
            // the lock!
            var indices = new List <ILogEntry>(section.Count);

            for (var i = 0; i < section.Count; ++i)
            {
                var logEntry = _buffer[i];
                indices.Add(CreateIndex(logEntry));
            }

            lock (_syncRoot)
            {
                if (!ReferenceEquals(logFile, _source))
                {
                    // We've retrieved data from a different log file than we wanted to...
                    Log.WarnFormat("Ignoring add '{0}': It's probably from a previous log file", section);
                }
                else
                {
                    foreach (var index in indices)
                    {
                        if (_indices.Count > 0)
                        {
                            var last     = _indices[_indices.Count - 1];
                            var maxWidth = last.GetValue(LogFileColumns.PresentationStartingLineNumber) +
                                           last.GetValue(LogFileColumns.PresentationLineCount);
                            index.SetValue(LogFileColumns.PresentationStartingLineNumber, maxWidth);
                        }
                        _indices.Add(index);
                        _maxWidth   = Math.Max(_maxWidth, index.GetValue(LogFileColumns.RawContentMaxPresentationWidth));
                        _lineCount += index.GetValue(LogFileColumns.PresentationLineCount);
                    }
                }
            }
        }
示例#7
0
        private void GetDeltaTime(LogFileSection section, TimeSpan?[] buffer, int destinationIndex)
        {
            var actualIndices = new LogLineIndex[section.Count + 1];

            lock (_indices)
            {
                var startIndex = section.Index;
                if (startIndex > 0)
                {
                    actualIndices[0] = _indices[startIndex - 1];
                }
                else
                {
                    actualIndices[0] = -1;
                }

                for (int i = 0; i < section.Count; ++i)
                {
                    var filteredIndex = (startIndex + i).Value;
                    if (filteredIndex >= 0 && filteredIndex < _indices.Count)
                    {
                        actualIndices[i + 1] = _indices[filteredIndex];
                    }
                    else
                    {
                        actualIndices[i + 1] = -1;
                    }
                }
            }

            var timestamps = _source.GetColumn(actualIndices, LogFileColumns.Timestamp);

            for (int i = 1; i <= section.Count; ++i)
            {
                var previousTimestamp = timestamps[i - 1];
                var currentTimestamp  = timestamps[i];
                var delta             = currentTimestamp - previousTimestamp;
                buffer[destinationIndex + i - 1] = delta;
            }
        }
示例#8
0
 private void Update(ILogFile logFile, LogFileSection section)
 {
     try
     {
         if (section.IsReset)
         {
             Clear(logFile);
         }
         else if (section.IsInvalidate)
         {
             InvalidateFrom(logFile, section.Index);
         }
         else
         {
             Add(logFile, section);
         }
     }
     catch (Exception e)
     {
         Log.ErrorFormat("Caught unexpected exception: {0}", e);
     }
 }
示例#9
0
        public void TestInvalidate2()
        {
            using (var file = new FilteredLogFile(_taskScheduler, TimeSpan.Zero, _logFile.Object, null, Filter.Create(null, true, LevelFlags.Info)))
            {
                file.AddListener(_listener.Object, TimeSpan.Zero, 1);

                _taskScheduler.RunOnce();
                file.EndOfSourceReached.Should().BeTrue();

                _entries.AddRange(new[]
                {
                    new LogLine(0, 0, "A", LevelFlags.Info),
                    new LogLine(1, 1, "B", LevelFlags.Info),
                    new LogLine(2, 2, "C", LevelFlags.Info),
                    new LogLine(3, 3, "D", LevelFlags.Info)
                });
                file.OnLogFileModified(_logFile.Object, new LogFileSection(0, 4));

                _taskScheduler.RunOnce();
                file.EndOfSourceReached.Should().BeTrue();
                file.Count.Should().Be(4);

                file.OnLogFileModified(_logFile.Object, LogFileSection.Invalidate(2, 2));

                _taskScheduler.RunOnce();
                file.EndOfSourceReached.Should().BeTrue();
                file.Count.Should().Be(2);

                _sections.Should().Equal(new[]
                {
                    LogFileSection.Reset,
                    new LogFileSection(0, 1),
                    new LogFileSection(1, 1),
                    new LogFileSection(2, 1),
                    new LogFileSection(3, 1),
                    LogFileSection.Invalidate(2, 2)
                });
            }
        }
示例#10
0
        public void TestAppendTwoSourcesWrongOrderSeparateChangesFullInvalidation()
        {
            var source1 = new InMemoryLogFile();

            source1.AddEntry("B", LevelFlags.None, new DateTime(2019, 5, 27, 23, 10, 0));
            var source2 = new InMemoryLogFile();

            source2.AddEntry("A", LevelFlags.None, new DateTime(2019, 5, 27, 23, 09, 0));

            var index   = new MergedLogFileIndex(source1, source2);
            var changes = index.Process(new MergedLogFilePendingModification(source1, new LogFileSection(0, 1)));

            changes.Should().Equal(new object[]
            {
                new LogFileSection(0, 1)
            });

            changes = index.Process(new MergedLogFilePendingModification(source2, new LogFileSection(0, 1)));
            changes.Should().Equal(new object[]
            {
                LogFileSection.Invalidate(0, 1),
                new LogFileSection(0, 2)
            });

            var indices = index.Get(new LogFileSection(0, 2));

            indices.Count.Should().Be(2);
            indices[0].LogFileIndex.Should().Be(1);
            indices[0].SourceLineIndex.Should().Be(0);
            indices[0].OriginalLogEntryIndex.Should().Be(0);
            indices[0].MergedLogEntryIndex.Should().Be(0);
            indices[0].Timestamp.Should().Be(new DateTime(2019, 5, 27, 23, 9, 0));

            indices[1].LogFileIndex.Should().Be(0);
            indices[1].SourceLineIndex.Should().Be(0);
            indices[1].OriginalLogEntryIndex.Should().Be(0);
            indices[1].MergedLogEntryIndex.Should().Be(1);
            indices[1].Timestamp.Should().Be(new DateTime(2019, 5, 27, 23, 10, 0));
        }
        public void TestReadAll2()
        {
            using (var file = new TextLogFile(_scheduler, File20Mb))
            {
                var listener = new Mock <ILogFileListener>();
                var sections = new List <LogFileSection>();
                listener.Setup(x => x.OnLogFileModified(It.IsAny <ILogFile>(), It.IsAny <LogFileSection>()))
                .Callback((ILogFile logFile, LogFileSection section) => sections.Add(section));

                file.AddListener(listener.Object, TimeSpan.Zero, 1);

                file.Property(x => x.EndOfSourceReached).ShouldAfter(TimeSpan.FromSeconds(20)).BeTrue();
                file.Count.Should().Be(165342);

                sections[0].Should().Equal(LogFileSection.Reset);
                for (int i = 1; i < sections.Count; ++i)
                {
                    LogFileSection change = sections[i];
                    change.Index.Should().Be((LogLineIndex)(i - 1));
                    change.Count.Should().Be(1);
                }
            }
        }
        /// <summary>
        ///     Fetches the newest values for this presenter's column from the given log file.
        /// </summary>
        /// <param name="logFile"></param>
        /// <param name="visibleSection"></param>
        /// <param name="yOffset"></param>
        public void FetchValues(ILogFile logFile, LogFileSection visibleSection, double yOffset)
        {
            if (Visibility != Visibility.Visible)             //< We shouldn't waste CPU cycles when we're hidden from view...
            {
                return;
            }

            _yOffset = yOffset;

            _values.Clear();
            if (logFile != null)
            {
                var values = new T[visibleSection.Count];
                logFile.GetColumn(visibleSection, _column, values);
                foreach (var value in values)
                {
                    _values.Add(CreatePresenter(value));
                }
            }

            UpdateWidth(logFile);
            InvalidateVisual();
        }
示例#13
0
        public string ExtractLogFile(string cffFilename, string line, Validations validations)
        {
            string EXPECTED_LOGFILE_FORMAT = $"\"[name].{LOGFILE_EXTENSION}\"";

            // Check whether the line starts opening/closing LOGFILE section
            // If yes, mark it exist
            LogFileSection.MarkSection(line, Int16.Parse(validations.LineNumber));

            bool openingSectionVisited = LogFileSection.ValidSectionPair[0];

            // Check the line start with the expected keyword, "DEFAULT"
            if (openingSectionVisited && line.StartsWith(CffKeywords.DEFAULT_LOGFILE))
            {
                // Check whether the pair key-value exists
                string[] lineData = validations.CheckPairKeyValue(
                    line,
                    CffKeywords.DEFAULT_LOGFILE,
                    EXPECTED_LOGFILE_FORMAT);

                if (lineData != null)
                {
                    LogFile = validations.CheckTextValueExist(
                        lineData[1],
                        LogFile,
                        EXPECTED_LOGFILE_FORMAT);
                }
            }

            // Check whether the value in the above pair has the valid extension (.text),
            // and check the filename has no invalia file character
            bool logfileExtensionValid = LogFile != null &&
                                         validations.CheckExtension(LogFile, LOGFILE_EXTENSION);
            bool noInvalidFilenameChars = logfileExtensionValid &&
                                          validations.CheckInvalidFileNameChars(LogFile);

            return(LogFile);
        }
示例#14
0
        /// <inheritdoc />
        public override void GetColumn <T>(LogFileSection section, ILogFileColumn <T> column, T[] buffer, int destinationIndex)
        {
            if (column == null)
            {
                throw new ArgumentNullException(nameof(column));
            }
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }
            if (destinationIndex < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(destinationIndex));
            }
            if (destinationIndex + section.Count > buffer.Length)
            {
                throw new ArgumentException("The given buffer must have an equal or greater length than destinationIndex+length");
            }

            if (Equals(column, LogFileColumns.DeltaTime))
            {
                GetDeltaTime(section, (TimeSpan?[])(object)buffer, destinationIndex);
            }
            else if (Equals(column, LogFileColumns.LineNumber))
            {
                GetLineNumber(section, (int[])(object)buffer, destinationIndex);
            }
            else if (Equals(column, LogFileColumns.OriginalIndex))
            {
                GetOriginalIndices(section, (LogLineIndex[])(object)buffer, destinationIndex);
            }
            else
            {
                var actualIndices = GetOriginalIndices(section);
                _source.GetColumn(actualIndices, column, buffer, destinationIndex);
            }
        }
示例#15
0
        public void TestInvalidate1()
        {
            using (var file = new FilteredLogFile(_taskScheduler, TimeSpan.Zero, _logFile.Object, null, Filter.Create(null, true, LevelFlags.Info)))
            {
                _taskScheduler.RunOnce();
                file.EndOfSourceReached.Should().BeTrue();

                _entries.AddRange(new[]
                {
                    new LogLine(0, 0, "A", LevelFlags.Info),
                    new LogLine(1, 1, "B", LevelFlags.Info),
                    new LogLine(2, 2, "C", LevelFlags.Info),
                    new LogLine(3, 3, "D", LevelFlags.Info)
                });

                file.OnLogFileModified(_logFile.Object, new LogFileSection(0, 4));
                file.OnLogFileModified(_logFile.Object, LogFileSection.Invalidate(2, 2));

                _taskScheduler.RunOnce();

                file.EndOfSourceReached.Should().BeTrue();
                file.Count.Should().Be(2, "because we've invalidated the last 2 out of 4 lines");
            }
        }
示例#16
0
        /// <inheritdoc />
        public override void GetColumn <T>(LogFileSection section, ILogFileColumn <T> column, T[] buffer, int destinationIndex)
        {
            if (column == null)
            {
                throw new ArgumentNullException(nameof(column));
            }
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }
            if (destinationIndex < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(destinationIndex));
            }
            if (destinationIndex + section.Count > buffer.Length)
            {
                throw new ArgumentException("The given buffer must have an equal or greater length than destinationIndex+length");
            }

            if (!TryGetSpecialColumn(section, column, buffer, destinationIndex))
            {
                _source.GetColumn(section, column, buffer, destinationIndex);
            }
        }
示例#17
0
        private LogLineResponse Request(LogFileSection section)
        {
            var lines = new LogLine[section.Count];

            // TODO: Can we retrieve those lines with fewer locks?
            for (var i = 0; i < section.Count; ++i)
            {
                var     index = section.Index + i;
                LogLine line;
                if (TryRetrieveFromCache(index, out line))
                {
                    lines[i] = line;
                }
                else
                {
                    lines[i] = RetrieveFromAccessor(i);
                }
            }

            return(new LogLineResponse
            {
                Lines = lines
            });
        }
示例#18
0
 private void Clear()
 {
     _fullSourceSection = new LogFileSection();
     lock (_indices)
     {
         _indices.Clear();
     }
     Listeners.OnRead(-1);
 }
示例#19
0
 /// <inheritdoc />
 public void OnLogFileModified(ILogFile logFile, LogFileSection section)
 {
     _pendingModifications.Enqueue(section);
     ResetEndOfSourceReached();
 }
示例#20
0
 public abstract void GetSection(LogFileSection section, LogLine[] dest);
示例#21
0
            private void AddRange(ILogFile logFile, LogFileSection section)
            {
                LogLine previousLine;
                if (_lines.Count > 0)
                    previousLine = _lines[_lines.Count - 1];
                else
                    previousLine = new LogLine(-1, -1, null, LevelFlags.None);

                LogLine[] lines = logFile.GetSection(section);
                for (int i = 0; i < section.Count; ++i)
                {
                    LogLine line = lines[i];
                    IncrementCount(line, previousLine);
                    previousLine = line;
                }
                _lines.AddRange(lines);
            }
示例#22
0
        /// <inheritdoc />
        public override void GetColumn <T>(LogFileSection section, ILogFileColumn <T> column, T[] buffer, int destinationIndex)
        {
            if (column == null)
            {
                throw new ArgumentNullException(nameof(column));
            }
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }
            if (destinationIndex < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(destinationIndex));
            }
            if (destinationIndex + section.Count > buffer.Length)
            {
                throw new ArgumentException("The given buffer must have an equal or greater length than destinationIndex+length");
            }

            lock (_syncRoot)
            {
                if (Equals(column, LogFileColumns.Index) ||
                    Equals(column, LogFileColumns.OriginalIndex))
                {
                    GetIndex(section, (LogLineIndex[])(object)buffer, destinationIndex);
                }
                else if (Equals(column, LogFileColumns.LogEntryIndex))
                {
                    GetIndex(section, (LogEntryIndex[])(object)buffer, destinationIndex);
                }
                else if (Equals(column, LogFileColumns.LineNumber) ||
                         Equals(column, LogFileColumns.OriginalLineNumber))
                {
                    GetLineNumber(section, (int[])(object)buffer, destinationIndex);
                }
                else if (Equals(column, LogFileColumns.LogLevel))
                {
                    GetLogLevel(section, (LevelFlags[])(object)buffer, destinationIndex);
                }
                else if (Equals(column, LogFileColumns.Timestamp))
                {
                    GetTimestamp(section, (DateTime?[])(object)buffer, destinationIndex);
                }
                else if (Equals(column, LogFileColumns.DeltaTime))
                {
                    GetDeltaTime(section, (TimeSpan?[])(object)buffer, destinationIndex);
                }
                else if (Equals(column, LogFileColumns.ElapsedTime))
                {
                    GetElapsedTime(section, (TimeSpan?[])(object)buffer, destinationIndex);
                }
                else if (Equals(column, LogFileColumns.RawContent))
                {
                    GetRawContent(section, (string[])(object)buffer, destinationIndex);
                }
                else
                {
                    throw new NoSuchColumnException(column);
                }
            }
        }
示例#23
0
 public void GetSection(LogFileSection section, LogLine[] dest)
 {
     ILogFile logFile = _innerLogFile;
     if (logFile != null)
     {
         logFile.GetSection(section, dest);
     }
     else
     {
         throw new IndexOutOfRangeException();
     }
 }
示例#24
0
 /// <summary>
 ///     Retrieves all entries from the given <paramref name="section" /> from this log file and copies
 ///     them into the given <paramref name="buffer" />.
 /// </summary>
 /// <param name="logFile"></param>
 /// <param name="section"></param>
 /// <param name="buffer"></param>
 public static void GetEntries(this ILogFile logFile, LogFileSection section, ILogEntries buffer)
 {
     GetEntries(logFile, section, buffer, 0);
 }
示例#25
0
        public override void GetSection(LogFileSection section, LogLine[] dest)
        {
            if (section.Index < 0)
                throw new ArgumentOutOfRangeException("section.Index");
            if (section.Count < 0)
                throw new ArgumentOutOfRangeException("section.Count");
            if (dest == null)
                throw new ArgumentNullException("dest");
            if (dest.Length < section.Count)
                throw new ArgumentOutOfRangeException("section.Count");

            lock (_syncRoot)
            {
                if (section.Index + section.Count > _entries.Count)
                    throw new ArgumentOutOfRangeException("section");

                _entries.CopyTo((int) section.Index, dest, 0, section.Count);
            }
        }
示例#26
0
        /// <inheritdoc />
        protected override TimeSpan RunOnce(CancellationToken token)
        {
            var  lastCount     = _fullSourceSection.Count;
            bool performedWork = false;

            LogFileSection section;

            while (_pendingModifications.TryDequeue(out section) && !token.IsCancellationRequested)
            {
                if (section.IsReset)
                {
                    Clear();
                }
                else if (section.IsInvalidate)
                {
                    Invalidate(section);
                }
                else
                {
                    _fullSourceSection = LogFileSection.MinimumBoundingLine(_fullSourceSection, section);
                }
                performedWork = true;
            }

            if (!_fullSourceSection.IsEndOfSection(_currentSourceIndex))
            {
                var remaining = Math.Min(_fullSourceSection.Count - _currentSourceIndex, MaximumBatchSize);
                var buffer    = new LogLine[remaining];
                _source.GetSection(new LogFileSection(_currentSourceIndex, remaining), buffer);
                LogLineIndex?resetIndex = null;

                lock (_syncRoot)
                {
                    for (var i = 0; i < remaining; ++i)
                    {
                        var line = buffer[i];
                        if (_currentLogEntry.EntryIndex.IsInvalid ||
                            line.Level != LevelFlags.None ||
                            _currentLogEntryLevel == LevelFlags.None)
                        {
                            _currentLogEntry      = _currentLogEntry.NextEntry(line.LineIndex);
                            _currentLogEntryLevel = line.Level;
                        }
                        else if (_currentLogEntry.FirstLineIndex < lastCount && resetIndex == null)
                        {
                            var index = _currentLogEntry.FirstLineIndex;
                            resetIndex = index;

                            _currentLogEntryLevel = _source.GetLine((int)index).Level;
                        }
                        _indices.Add(_currentLogEntry);
                    }
                }

                if (resetIndex != null)
                {
                    var resetCount = lastCount - resetIndex.Value;
                    if (resetCount > 0)
                    {
                        Listeners.Invalidate((int)resetIndex.Value, resetCount);
                    }
                }

                _currentSourceIndex += remaining;
            }

            // Now we can perform a block-copy of all properties.
            _source.GetValues(_properties);

            _maxCharactersPerLine = _source.MaxCharactersPerLine;

            if (_indices.Count != _currentSourceIndex)
            {
                Log.ErrorFormat("Inconsistency detected: We have {0} indices for {1} lines", _indices.Count,
                                _currentSourceIndex);
            }

            Listeners.OnRead((int)_currentSourceIndex);

            if (_source.EndOfSourceReached && _fullSourceSection.IsEndOfSection(_currentSourceIndex))
            {
                SetEndOfSourceReached();
            }

            if (performedWork)
            {
                return(TimeSpan.Zero);
            }

            return(_maximumWaitTime);
        }
示例#27
0
 public PendingModification(ILogFile logFile, LogFileSection section)
 {
     LogFile = logFile;
     Section = section;
 }
示例#28
0
 public override void GetSection(LogFileSection section, LogLine[] dest)
 {
     throw new NotImplementedException();
 }
        private void Report(int numberOfLinesRead, DateTime now)
        {
            // We may never report all lines in one go if the listener specified
            // that he only wants to receive batches of N.
            // Therefore we invoke the listener multiple times.
            int count;
            while ((count = numberOfLinesRead - _lastNumberOfLines) > 0)
            {
                count = Math.Min(count, _maximumCount);
                var section = new LogFileSection(_lastNumberOfLines, count);
                _listener.OnLogFileModified(_logFile, section);

                _lastNumberOfLines += count;
                _lastReportedTime = now;
            }
        }
示例#30
0
        public void TestGetSection()
        {
            using (var proxy = new LogFileProxy(_scheduler, TimeSpan.Zero, _logFile.Object))
            {
                proxy.GetSection(new LogFileSection(42, 101), new LogLine[101]);

                var expected = new LogFileSection(42, 101);
                _logFile.Verify(l => l.GetSection(It.Is<LogFileSection>(x => Equals(x, expected)),
                                                 It.IsAny<LogLine[]>()), Times.Once);
            }
        }
示例#31
0
 internal void OnSizeChanged()
 {
     DetermineVerticalOffset();
     _currentlyVisibleSection = CalculateVisibleSection();
     UpdateVisibleLines();
 }
示例#32
0
 public void UpdateVisibleSection()
 {
     _currentlyVisibleSection = CalculateVisibleSection();
 }
示例#33
0
 protected override void OnLogFileModifiedInternal(ILogFile logFile, LogFileSection section)
 {
     _modifications.Enqueue(section);
 }
示例#34
0
 public void OnLogFileModified(ILogFile logFile, LogFileSection section)
 {
     _pendingModifications.Enqueue(section);
 }
示例#35
0
 public static LogLine[] GetSection(this ILogFile logFile, LogFileSection section)
 {
     var entries = new LogLine[section.Count];
     logFile.GetSection(section, entries);
     return entries;
 }
示例#36
0
 private void TextCanvasOnVisibleSectionChanged(LogFileSection section)
 {
     CurrentLine = section.Index;
 }
示例#37
0
 public void TestToString()
 {
     LogFileSection.Reset.ToString().Should().Be("Reset");
     LogFileSection.Invalidate(42, 5).ToString().Should().Be("Invalidated [#42, #5]");
 }
示例#38
0
 public void OnLogFileModified(ILogFile logFile, LogFileSection section)
 {
     _pendingSections.Enqueue(new KeyValuePair<ILogFile, LogFileSection>(logFile, section));
 }
示例#39
0
        protected override TimeSpan RunOnce(CancellationToken token)
        {
            LogFileSection section;
            while (_pendingModifications.TryDequeue(out section) && !token.IsCancellationRequested)
            {
                if (section.IsReset)
                {
                    Clear();
                    _lastLogEntry.Clear();
                    _currentSourceIndex = 0;
                }
                else if (section.InvalidateSection)
                {
                    LogLineIndex startIndex = section.Index;
                    _fullSourceSection = new LogFileSection(0, (int)startIndex);

                    if (_currentSourceIndex > _fullSourceSection.LastIndex)
                        _currentSourceIndex = (int)section.Index;

                    Invalidate(_currentSourceIndex);
                    RemoveInvalidatedLines(_lastLogEntry, _currentSourceIndex);
                }
                else
                {
                    _fullSourceSection = LogFileSection.MinimumBoundingLine(_fullSourceSection, section);
                }
            }

            if (!_fullSourceSection.IsEndOfSection(_currentSourceIndex))
            {
                int remaining = _fullSourceSection.Index + _fullSourceSection.Count - _currentSourceIndex;
                int nextCount = Math.Min(remaining, BatchSize);
                var nextSection = new LogFileSection(_currentSourceIndex, nextCount);
                _source.GetSection(nextSection, _buffer);

                for (int i = 0; i < nextCount; ++i)
                {
                    if (token.IsCancellationRequested)
                        break;

                    LogLine line = _buffer[i];
                    if (_lastLogEntry.Count == 0 || _lastLogEntry[0].LogEntryIndex == line.LogEntryIndex)
                    {
                        _lastLogEntry.Add(line);
                    }
                    else if (line.LogEntryIndex != _lastLogEntry[0].LogEntryIndex)
                    {
                        TryAddLogLine(_lastLogEntry);
                        _lastLogEntry.Clear();
                        _lastLogEntry.Add(line);
                    }
                }

                _currentSourceIndex += nextCount;
            }

            if (_fullSourceSection.IsEndOfSection(_currentSourceIndex))
            {
                TryAddLogLine(_lastLogEntry);
                Listeners.OnRead(_indices.Count);

                SetEndOfSourceReached();
            }

            return _maximumWaitTime;
        }
示例#40
0
 public void OnLogFileModified(ILogFile logFile, LogFileSection section)
 {
     if (section.IsReset)
     {
         Clear();
     }
     else if (section.InvalidateSection)
     {
         RemoveRange(section);
     }
     else
     {
         AddRange(logFile, section);
     }
 }
示例#41
0
 public void OnLogFileModified(ILogFile logFile, LogFileSection section)
 {
     _pendingModifications.Enqueue(section);
     ResetEndOfSourceReached();
 }
示例#42
0
            private void RemoveRange(LogFileSection section)
            {
                LogLine previousLine;
                if (section.Index > 0)
                    previousLine = _lines[(int) section.Index];
                else
                    previousLine = new LogLine(-1, -1, null, LevelFlags.None);

                for (int i = 0; i < section.Count; ++i)
                {
                    LogLineIndex index = section.Index + i;
                    LogLine line = _lines[(int) index];
                    DecrementCount(line, previousLine);
                    previousLine = line;
                }

                _lines.RemoveRange((int) section.Index, section.Count);
            }
示例#43
0
 /// <inheritdoc />
 public override void GetEntries(LogFileSection section, ILogEntries buffer, int destinationIndex)
 {
     throw new NotImplementedException();
 }
示例#44
0
        /// <inheritdoc />
        public void CopyFrom(ILogFileColumn column, int destinationIndex, ILogFile source, LogFileSection section)
        {
            if (column == null)
            {
                throw new ArgumentNullException(nameof(column));
            }

            IColumnData columnData;

            if (!_dataByColumn.TryGetValue(column, out columnData))
            {
                throw new NoSuchColumnException(column);
            }

            columnData.CopyFrom(destinationIndex, source, section);
        }
示例#45
0
        /// <inheritdoc />
        protected override TimeSpan RunOnce(CancellationToken token)
        {
            bool performedWork = false;

            LogFileSection section;

            while (_pendingModifications.TryDequeue(out section) && !token.IsCancellationRequested)
            {
                if (section.IsReset)
                {
                    Clear();
                    _lastLogEntry.Clear();
                    _currentSourceIndex = 0;
                }
                else if (section.IsInvalidate)
                {
                    LogLineIndex startIndex = section.Index;
                    _fullSourceSection = new LogFileSection(0, (int)startIndex);

                    if (_currentSourceIndex > _fullSourceSection.LastIndex)
                    {
                        _currentSourceIndex = (int)section.Index;
                    }

                    Invalidate(_currentSourceIndex);
                    RemoveInvalidatedLines(_lastLogEntry, _currentSourceIndex);
                }
                else
                {
                    _fullSourceSection = LogFileSection.MinimumBoundingLine(_fullSourceSection, section);
                }

                performedWork = true;
            }

            if (!_fullSourceSection.IsEndOfSection(_currentSourceIndex))
            {
                int remaining   = _fullSourceSection.Index + _fullSourceSection.Count - _currentSourceIndex;
                int nextCount   = Math.Min(remaining, BatchSize);
                var nextSection = new LogFileSection(_currentSourceIndex, nextCount);
                _source.GetSection(nextSection, _buffer);

                for (int i = 0; i < nextCount; ++i)
                {
                    if (token.IsCancellationRequested)
                    {
                        break;
                    }

                    LogLine line = _buffer[i];
                    if (_lastLogEntry.Count == 0 || _lastLogEntry[0].LogEntryIndex == line.LogEntryIndex)
                    {
                        TryAddLogLine(line);
                    }
                    else if (line.LogEntryIndex != _lastLogEntry[0].LogEntryIndex)
                    {
                        TryAddLogEntry(_lastLogEntry);
                        _lastLogEntry.Clear();
                        TryAddLogLine(line);
                    }
                }

                _currentSourceIndex += nextCount;
            }

            if (_fullSourceSection.IsEndOfSection(_currentSourceIndex))
            {
                TryAddLogEntry(_lastLogEntry);
                Listeners.OnRead(_indices.Count);

                if (_source.EndOfSourceReached)
                {
                    SetEndOfSourceReached();
                }
            }

            if (performedWork)
            {
                return(TimeSpan.Zero);
            }

            return(_maximumWaitTime);
        }
示例#46
0
 public void OnLogFileModified(ILogFile logFile, LogFileSection section)
 {
     _pendingModifications.Enqueue(section);
 }
示例#47
0
        public void OnLogFileModified(ILogFile logFile, LogFileSection section)
        {
            lock (_pendingSections)
            {
                if (section == LogFileSection.Reset)
                    _pendingSections.Clear();

                _pendingSections.Add(new KeyValuePair<ILogFile, LogFileSection>(_logFile, section));
                _dispatcher.BeginInvoke(Synchronize, DispatcherPriority.Background);
            }
        }
示例#48
0
        public void OnLogFileModified(ILogFile logFile, LogFileSection section)
        {
            double width = TextHelper.EstimateWidthUpperLimit(logFile.MaxCharactersPerLine);
            var upperWidth = (int) Math.Ceiling(width);

            // Setting an integer is an atomic operation and thus no
            // special synchronization is required.
            _maxLineWidth = Math.Max(_maxLineWidth, upperWidth);

            Interlocked.Increment(ref _pendingModificationsCount);
        }
示例#49
0
        private void AppendMatches(LogFileSection section)
        {
            try
            {
                // We've instructed the logfile to give us exactly up to
                // _logLinesBuffer.Length amount of entries in the ctor, hence the following
                // is correct:
                _logFile.GetSection(section, _logLinesBuffer);

                bool added = false;
                for (int i = 0; i < section.Count; ++i)
                {
                    var line = _logLinesBuffer[i];

                    _filter.Match(line, _matchesBuffer);
                    if (_matchesBuffer.Count > 0)
                    {
                        lock (_syncRoot)
                        {
                            foreach (LogLineMatch logLineMatch in _matchesBuffer)
                            {
                                var match = new LogMatch(line.LineIndex, logLineMatch);
                                _matches.Add(match);
                            }
                        }

                        _matchesBuffer.Clear();
                        added = true;
                    }
                }

                if (added)
                {
                    _listeners.EmitSearchChanged(_matches);
                }
            }
            catch (IndexOutOfRangeException e)
            {
                // This exception is usually thrown when we access a portion of the
                // log file that has already been reset. This means that a reset event is
                // either pending or soon to be. So not doing anything else to handle
                // this exception is fine.
                Log.DebugFormat("Caught exception while searching log file: {0}", e);
            }
        }
示例#50
0
 private void TextCanvasOnVisibleSectionChanged(LogFileSection section)
 {
     CurrentLine = section.Index;
 }
示例#51
0
        public override void GetSection(LogFileSection section, LogLine[] dest)
        {
            if (section.Index < 0)
                throw new ArgumentOutOfRangeException("section.Index");
            if (section.Count < 0)
                throw new ArgumentOutOfRangeException("section.Count");
            if (dest == null)
                throw new ArgumentNullException("dest");
            if (dest.Length < section.Count)
                throw new ArgumentOutOfRangeException("section.Count");

            lock (_indices)
            {
                if (section.Index + section.Count > _indices.Count)
                    throw new ArgumentOutOfRangeException("section");

                for (int i = 0; i < section.Count; ++i)
                {
                    LogLineIndex index = section.Index + i;
                    int sourceIndex = _indices[(int) index];
                    LogLine line = _source.GetLine(sourceIndex);
                    dest[i] = new LogLine((int)index, line.LogEntryIndex, line.Message, line.Level, line.Timestamp);
                }
            }
        }
示例#52
0
 /// <inheritdoc />
 public override void GetEntries(LogFileSection section, ILogEntries buffer, int destinationIndex)
 {
     _source.GetEntries(section, buffer, destinationIndex);
 }
示例#53
0
 public Task <LogLineResponse> RequestAsync(LogFileSection section, CancellationToken cancellationToken)
 {
     return(_scheduler.StartNew(() => Request(section)));
 }