public override void GetEntries(IReadOnlyList <LogLineIndex> sourceIndices,
                                 ILogBuffer destination,
                                 int destinationIndex,
                                 LogSourceQueryOptions queryOptions)
 {
     _source.GetEntries(sourceIndices, destination, destinationIndex, queryOptions);
 }
        public void GetEntries(IReadOnlyList <LogLineIndex> sourceIndices,
                               ILogBuffer destination,
                               int destinationIndex,
                               LogSourceQueryOptions queryOptions)
        {
            if (TryReadFromCache(sourceIndices, destination, destinationIndex, queryOptions, out var accessedPageBoundaries))
            {
                return;
            }

            if ((queryOptions.QueryMode & LogSourceQueryMode.FetchForLater) == LogSourceQueryMode.FetchForLater)
            {
                FetchForLater(accessedPageBoundaries);
            }

            // For some clients (GUI) it is permissible to serve partial requests and to default out the rest.
            // The ui will try again at a later date until it gets what it needs.
            if ((queryOptions.QueryMode & LogSourceQueryMode.FromSource) == 0)
            {
                return;
            }

            // Whelp, we gotta fetch from the source instead.
            // Note: We don't lock this part because this would block any other thread currently
            //       trying to read data from cache, etc.. We only block when we need to and only
            //       for a short amount of time!
            _source.GetEntries(sourceIndices, destination, destinationIndex, queryOptions);

            // However now that we got some data, we could try to add it to our cache
            AddToCache(sourceIndices, destination, destinationIndex, queryOptions);
        }
Esempio n. 3
0
        private bool ExportPortion(StreamWriter writer, LogBufferArray array, int index, int count)
        {
            try
            {
                _logSource.GetEntries(new LogSourceSection(index, count), array);

                for (var i = 0; i < count; ++i)
                {
                    if (_written)
                    {
                        writer.WriteLine();
                    }

                    var logLine = array[i];
                    if (logLine.Index == LogLineIndex.Invalid)                     //< EOF
                    {
                        break;
                    }

                    writer.Write(logLine.RawContent);
                    _written = true;
                }

                return(true);
            }
            catch (IndexOutOfRangeException)
            {
                // The file has been invalidated and reduced in size already.
                // That's okay and we can end this export....
                return(false);
            }
        }
Esempio n. 4
0
        public static IReadOnlyLogEntry GetEntry(this ILogSource logSource, LogLineIndex sourceIndex)
        {
            var buffer = new LogBufferArray(1, logSource.Columns);

            logSource.GetEntries(new LogSourceSection(sourceIndex, 1), buffer);
            return(buffer[0]);
        }
Esempio n. 5
0
        public static IReadOnlyLogEntry GetEntry(this ILogSource logSource, LogLineIndex sourceIndex, IEnumerable <IColumnDescriptor> columns)
        {
            var buffer = new LogBufferArray(1, columns);

            logSource.GetEntries(new LogSourceSection(sourceIndex, 1), buffer);
            return(buffer[0]);
        }
Esempio n. 6
0
        public static IReadOnlyLogBuffer GetEntries(this ILogSource logSource, IReadOnlyList <LogLineIndex> sourceIndices, IEnumerable <IColumnDescriptor> columns)
        {
            var buffer = new LogBufferArray(sourceIndices.Count, columns);

            logSource.GetEntries(sourceIndices, buffer);
            return(buffer);
        }
Esempio n. 7
0
        /// <summary>
        ///    Processes all newly arrived log entries.
        /// </summary>
        /// <param name="token"></param>
        private void ProcessNewLogEntries(CancellationToken token)
        {
            if (!_fullSourceSection.IsEndOfSection(_currentSourceIndex))
            {
                int remaining   = _fullSourceSection.Index + _fullSourceSection.Count - _currentSourceIndex;
                int nextCount   = Math.Min(remaining, BatchSize);
                var nextSection = new LogSourceSection(_currentSourceIndex, nextCount);
                _source.GetEntries(nextSection, _array);

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

                    var logEntry = _array[i];
                    if (Log.IsDebugEnabled)
                    {
                        Log.DebugFormat("Processing: LineIndex={0}, OriginalLineIndex={1}, LogEntryIndex={2}, Message={3}",
                                        logEntry.Index,
                                        logEntry.OriginalIndex,
                                        logEntry.LogEntryIndex,
                                        logEntry.RawContent);
                    }

                    if (_lastLogBuffer.Count == 0 || _lastLogBuffer[0].LogEntryIndex == logEntry.LogEntryIndex)
                    {
                        TryAddLogLine(logEntry);
                    }
                    else if (logEntry.LogEntryIndex != _lastLogBuffer[0].LogEntryIndex)
                    {
                        TryAddLogEntry(_lastLogBuffer);
                        _lastLogBuffer.Clear();
                        TryAddLogLine(logEntry);
                    }
                }

                _currentSourceIndex += nextCount;
            }

            // Now that we've processes all newly added log entries, we can check if we're at the end just yet...
            if (_fullSourceSection.IsEndOfSection(_currentSourceIndex))
            {
                TryAddLogEntry(_lastLogBuffer);
                UpdateProperties();                 //< we need to update our own properties after we've added the last entry, but before we notify listeners...
                Listeners.OnRead(_indices.Count);

                if (_properties.GetValue(Core.Properties.PercentageProcessed) == Percentage.HundredPercent)
                {
                    Listeners.Flush();
                }
            }
            else
            {
                UpdateProperties();
            }
        }
Esempio n. 8
0
        private void AppendMatches(LogSourceSection section)
        {
            try
            {
                LogBufferArray lines;
                lock (_syncRoot)
                {
                    lines = _logLinesArray;
                    if (lines == null)
                    {
                        return;
                    }
                }

                // We've instructed the logfile to give us exactly up to
                // _logLinesBuffer.Length amount of entries in the ctor, hence the following
                // is correct:
                _logSource.GetEntries(section, lines);

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

                    _filter.Match(line, _matchesBuffer);
                    if (_matchesBuffer.Count > 0)
                    {
                        lock (_syncRoot)
                        {
                            foreach (LogLineMatch logLineMatch in _matchesBuffer)
                            {
                                var match = new LogMatch(line.Index, 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);
            }
        }
Esempio n. 9
0
 /// <inheritdoc />
 public void GetEntries(IReadOnlyList <LogLineIndex> sourceIndices, ILogBuffer destination, int destinationIndex, LogSourceQueryOptions queryOptions)
 {
     try
     {
         _logSource.GetEntries(sourceIndices, destination, destinationIndex, queryOptions);
     }
     catch (Exception e)
     {
         BlameExceptionOnPlugin(e);
     }
 }
Esempio n. 10
0
        private void UpdateMaxWidth(LogSourceSection section, ILogSource logSource)
        {
            logSource.GetEntries(section, _buffer);
            for (int i = 0; i < section.Count; ++i)
            {
                var rawContent = _buffer[i].RawContent;
                if (rawContent == null)
                {
                    break;
                }

                _maxCharactersInLine = Math.Max(_maxCharactersInLine, rawContent.Length);
            }
        }
Esempio n. 11
0
        /// <inheritdoc />
        public void GetEntries(IReadOnlyList <LogLineIndex> sourceIndices, ILogBuffer destination, int destinationIndex, LogSourceQueryOptions queryOptions)
        {
            ILogSource logSource = _source;

            if (logSource != null)
            {
                logSource.GetEntries(sourceIndices, destination, destinationIndex, queryOptions);
            }
            else
            {
                foreach (var column in destination.Columns)
                {
                    destination.FillDefault(column, destinationIndex, sourceIndices.Count);
                }
            }
        }
Esempio n. 12
0
        private void AppendSection(LogSourceSection section)
        {
            _count = (int)(section.Index + section.Count);
            try
            {
                _source.GetEntries(section, _fetchBuffer);
                OnSectionAppended(section, _fetchBuffer, _count);
            }
            catch (Exception e)
            {
                Log.WarnFormat("Caught unexpected exception: {0}", e);
            }

            SynchronizeProperties();
            Listeners.OnRead(_count);
        }
Esempio n. 13
0
        private void Add(ILogSource logSource, LogSourceSection section)
        {
            // !!!We deliberately retrieve this section OUTSIDE of our own lock!!!
            logSource.GetEntries(section, _array);

            // 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 = _array[i];
                indices.Add(CreateIndex(logEntry));
            }

            lock (_syncRoot)
            {
                if (!ReferenceEquals(logSource, _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(PresentationStartingLineNumber) +
                                           last.GetValue(PresentationLineCount);
                            index.SetValue(PresentationStartingLineNumber, maxWidth);
                        }
                        _indices.Add(index);
                        _maxWidth   = Math.Max(_maxWidth, index.GetValue(RawContentMaxPresentationWidth));
                        _lineCount += index.GetValue(PresentationLineCount);
                    }
                }
            }
        }
Esempio n. 14
0
        public void OnCopyToClipboard()
        {
            try
            {
                var        builder   = new StringBuilder();
                ILogSource logSource = _logSource;
                if (logSource != null)
                {
                    var sortedIndices = new List <LogLineIndex>(_selectedIndices);
                    sortedIndices.Sort();
                    // TODO: What do we do if some mad man has 1 million lines selected?
                    // TODO: Request in batches
                    var buffer = new LogBufferArray(_selectedIndices.Count, Columns.RawContent);
                    logSource.GetEntries(sortedIndices, buffer);

                    for (int i = 0; i < sortedIndices.Count; ++i)
                    {
                        var entry = buffer[i];
                        if (i < sortedIndices.Count - 1)
                        {
                            builder.AppendLine(entry.RawContent);
                        }
                        else
                        {
                            builder.Append(entry.RawContent);
                        }
                    }
                }
                string message = builder.ToString();
                Clipboard.SetText(message);
            }
            catch (Exception e)
            {
                Log.ErrorFormat("Caught unexpected exception: {0}", e);
            }
        }
Esempio n. 15
0
        public void UpdateVisibleLines()
        {
            _visibleTextLines.Clear();
            if (_logSource == null)
            {
                return;
            }

            try
            {
                _visibleBufferBuffer.Clear();
                _visibleBufferBuffer.Resize(_currentlyVisibleSection.Count);
                if (_currentlyVisibleSection.Count > 0)
                {
                    // We don't want to block the UI thread for very long at all so we instruct the log source to only
                    // fetch data from the cache, but to fetch missing data for later (from the source).
                    var queryOptions = new LogSourceQueryOptions(LogSourceQueryMode.FromCache | LogSourceQueryMode.FetchForLater, TimeSpan.Zero);
                    _logSource.GetEntries(_currentlyVisibleSection, _visibleBufferBuffer, 0, queryOptions);

                    // Now comes the fun part. We need to detect if we could fetch *all* the data.
                    // This is done by inspecting the BufferedLogSource.RetrievalState - if we encounter any NotCached value,
                    // then the entry is part of the source, but was not cached at the time of trying to access it.
                    // If that's the case, we will instruct this canvas to re-fetch the once more in a bit. This loop will terminate once the
                    // cache has managed to fetch the desired data which should happen some time...
                    if (_visibleBufferBuffer.ContainsAny(PageBufferedLogSource.RetrievalState,
                                                         RetrievalState.NotCached,
                                                         new Int32Range(offset: 0, _currentlyVisibleSection.Count)))
                    {
                        if (!_requiresFurtherUpdate)
                        {
                            Log.DebugFormat("Requires further update (at least one entry is not in cache)");
                            _requiresFurtherUpdate = true;
                            _updateStart           = DateTime.Now;
                        }
                    }
                    else
                    {
                        if (_requiresFurtherUpdate)
                        {
                            var elapsed = DateTime.Now - _updateStart;
                            Log.DebugFormat("No longer requires further update (all retrieved log entries are in cache), took {0:F1}ms", elapsed.TotalMilliseconds);
                            _requiresFurtherUpdate = false;
                        }
                    }

                    for (int i = 0; i < _currentlyVisibleSection.Count; ++i)
                    {
                        var line = new TextLine(_visibleBufferBuffer[i], _hoveredIndices, _selectedIndices,
                                                _colorByLevel, _textSettings, _textBrushes)
                        {
                            IsFocused     = IsFocused,
                            SearchResults = _searchResults
                        };
                        _visibleTextLines.Add(line);
                    }
                }

                Action fn = VisibleLinesChanged;
                fn?.Invoke();

                InvalidateVisual();
            }
            catch (ArgumentOutOfRangeException e)
            {
                Log.DebugFormat("Caught exception while trying to update text: {0}", e);
            }
            catch (IndexOutOfRangeException e)
            {
                Log.DebugFormat("Caught exception while trying to update text: {0}", e);
            }
        }
Esempio n. 16
0
 /// <summary>
 ///     Retrieves all entries with the given <paramref name="sourceIndices"/> from this log file and copies
 ///     them into the given <paramref name="destination"/>.
 /// </summary>
 /// <param name="logSource"></param>
 /// <param name="sourceIndices"></param>
 /// <param name="destination"></param>
 /// <param name="destinationIndex"></param>
 public static void GetEntries(this ILogSource logSource, IReadOnlyList <LogLineIndex> sourceIndices, ILogBuffer destination, int destinationIndex)
 {
     logSource.GetEntries(sourceIndices, destination, destinationIndex, LogSourceQueryOptions.Default);
 }
Esempio n. 17
0
 /// <summary>
 ///     Retrieves all entries with the given <paramref name="sourceIndices"/> from this log file and copies
 ///     them into the given <paramref name="destination"/>.
 /// </summary>
 /// <param name="logSource"></param>
 /// <param name="sourceIndices"></param>
 /// <param name="destination"></param>
 /// <param name="queryOptions">Configures how the data is to be retrieved</param>
 public static void GetEntries(this ILogSource logSource, IReadOnlyList <LogLineIndex> sourceIndices, ILogBuffer destination, LogSourceQueryOptions queryOptions)
 {
     logSource.GetEntries(sourceIndices, destination, 0, queryOptions);
 }
Esempio n. 18
0
 public static IReadOnlyLogBuffer GetEntries(this ILogSource logSource)
 {
     return(logSource.GetEntries(logSource.Columns));
 }