private void GetElapsedTime(IReadOnlyList <LogLineIndex> indices, TimeSpan?[] buffer, int destinationIndex) { lock (_syncRoot) { var startTimestamp = _properties.GetValue(LogFileProperties.StartTimestamp); for (int i = 0; i < indices.Count; ++i) { var index = indices[i]; var line = GetLogLine(index); buffer[destinationIndex + i] = line != null ? line.Value.Timestamp - startTimestamp : LogFileColumns.ElapsedTime.DefaultValue; } } }
/// <inheritdoc /> protected override TimeSpan RunOnce(CancellationToken token) { bool read = false; try { if (!File.Exists(_fileName)) { SetDoesNotExist(); } else { var info = new FileInfo(_fileName); _properties.SetValue(LogFileProperties.LastModified, info.LastWriteTime); _properties.SetValue(LogFileProperties.Created, info.CreationTime); _properties.SetValue(LogFileProperties.Size, Size.FromBytes(info.Length)); using (var stream = new FileStream(_fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { var format = _properties.GetValue(LogFileProperties.Format); if (format == null) { format = TryFindFormat(stream); _properties.SetValue(LogFileProperties.Format, format); } var encoding = format?.Encoding ?? _encoding; _properties.SetValue(LogFileProperties.Encoding, encoding); using (var reader = new StreamReaderEx(stream, encoding)) { // We change the error flag explicitly AFTER opening // the stream because that operation might throw if we're // not allowed to access the file (in which case a different // error must be set). _properties.SetValue(LogFileProperties.EmptyReason, ErrorFlags.None); if (stream.Length >= _lastPosition) { stream.Position = _lastPosition; } else { OnReset(stream, out _numberOfLinesRead, out _lastPosition); } string currentLine; while ((currentLine = reader.ReadLine()) != null) { token.ThrowIfCancellationRequested(); ResetEndOfSourceReached(); LevelFlags level = LogLine.DetermineLevelFromLine(currentLine); bool lastLineHadNewline = _lastLineHadNewline; var trimmedLine = currentLine.TrimNewlineEnd(out _lastLineHadNewline); var entryCount = _entries.Count; if (entryCount > 0 && !lastLineHadNewline) { // We need to remove the last line and create a new line // that consists of the entire content. RemoveLast(); trimmedLine = _untrimmedLastLine + trimmedLine; _untrimmedLastLine = _untrimmedLastLine + currentLine; } else { _untrimmedLastLine = currentLine; ++_numberOfLinesRead; read = true; } var timestamp = ParseTimestamp(trimmedLine); Add(trimmedLine, level, _numberOfLinesRead, timestamp); } _lastPosition = stream.Position; } } Listeners.OnRead(_numberOfLinesRead); SetEndOfSourceReached(); } } catch (FileNotFoundException e) { SetError(ErrorFlags.SourceDoesNotExist); Log.Debug(e); } catch (DirectoryNotFoundException e) { SetError(ErrorFlags.SourceDoesNotExist); Log.Debug(e); } catch (OperationCanceledException e) { Log.Debug(e); } catch (UnauthorizedAccessException e) { SetError(ErrorFlags.SourceCannotBeAccessed); Log.Debug(e); } catch (IOException e) { SetError(ErrorFlags.SourceCannotBeAccessed); Log.Debug(e); } catch (Exception e) { Log.Debug(e); } if (read) { return(TimeSpan.Zero); } return(TimeSpan.FromMilliseconds(100)); }
/// <summary> /// /// </summary> /// <param name="entry"></param> public void Add(IReadOnlyLogEntry entry) { lock (_syncRoot) { DateTime?timestamp; entry.TryGetValue(LogFileColumns.Timestamp, out timestamp); LogEntryIndex logEntryIndex; TimeSpan? elapsed, deltaTime; if (_logEntries.Count > 0) { var last = _logEntries[_logEntries.Count - 1]; logEntryIndex = last.LogEntryIndex + 1; elapsed = timestamp - _properties.GetValue(LogFileProperties.StartTimestamp); deltaTime = timestamp - last.Timestamp; } else { logEntryIndex = 0; elapsed = null; deltaTime = null; } if (_properties.GetValue(LogFileProperties.StartTimestamp) == null) { _properties.SetValue(LogFileProperties.StartTimestamp, timestamp); } if (timestamp != null) { _properties.SetValue(LogFileProperties.EndTimestamp, timestamp); } // The user supplies us with a list of properties to add, however we will // never allow the user to supply us things like index or line number. // Therefore we create a log entry which we actually want to add... var finalLogEntry = new LogEntry2(Columns); foreach (var column in Columns) { object value; if (entry.TryGetValue(column, out value)) { finalLogEntry.SetValue(column, value); } } finalLogEntry.Index = _logEntries.Count; finalLogEntry.OriginalIndex = _logEntries.Count; finalLogEntry.LineNumber = _logEntries.Count + 1; finalLogEntry.OriginalLineNumber = _logEntries.Count + 1; finalLogEntry.LogEntryIndex = logEntryIndex; finalLogEntry.Timestamp = timestamp; finalLogEntry.ElapsedTime = elapsed; finalLogEntry.DeltaTime = deltaTime; _logEntries.Add(finalLogEntry); MaxCharactersPerLine = Math.Max(MaxCharactersPerLine, finalLogEntry.RawContent?.Length ?? 0); Touch(); _listeners.OnRead(_logEntries.Count); } }