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); }
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); } }
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]); }
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]); }
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); }
/// <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(); } }
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); } }
/// <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); } }
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); } }
/// <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); } } }
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); }
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); } } } }
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); } }
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); } }
/// <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); }
/// <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); }
public static IReadOnlyLogBuffer GetEntries(this ILogSource logSource) { return(logSource.GetEntries(logSource.Columns)); }