public void ReadLogEvent() { // Arrange // The initial space is there to adapt to offset 1 var fileContent = $" {Foo}{Environment.NewLine}"; var stream = new MemoryStream(Encoding.UTF8.GetBytes(fileContent)); // Act var actual = PayloadReader.Read(stream, ref nextLineBeginsAtOffset, ref count, int.MaxValue); // Assert actual.ShouldBe(new[] { Foo }); nextLineBeginsAtOffset.ShouldBe(fileContent.Length); count.ShouldBe(1); }
public void NotReadLogEventGivenPartiallyWritten() { // Arrange // The initial space is there to adapt to offset 1, and the partially written log event // is missing new line var fileContent = $" {Foo}"; var stream = new MemoryStream(Encoding.UTF8.GetBytes(fileContent)); // Act var actual = PayloadReader.Read(stream, ref nextLineBeginsAtOffset, ref count, int.MaxValue); // Assert actual.ShouldBeEmpty(); nextLineBeginsAtOffset.ShouldBe(fileContent.IndexOf(Foo, StringComparison.InvariantCulture)); count.ShouldBe(0); }
private async Task OnTick() { try { int count; do { count = 0; using (var bookmark = new BookmarkFile(bookmarkFilename)) { bookmark.TryReadBookmark(out var nextLineBeginsAtOffset, out var currentFile); var fileSet = GetFileSet(); if (currentFile == null || !System.IO.File.Exists(currentFile)) { nextLineBeginsAtOffset = 0; currentFile = fileSet.FirstOrDefault(); } if (currentFile == null) { continue; } var logEvents = PayloadReader.Read( currentFile, ref nextLineBeginsAtOffset, ref count, batchPostingLimit); var payloadWriter = new StringWriter(); batchFormatter.Format(logEvents, payloadWriter); var payload = payloadWriter.ToString(); if (count > 0 || nextRequiredLevelCheckUtc < DateTime.UtcNow) { lock (stateLock) { nextRequiredLevelCheckUtc = DateTime.UtcNow.Add(RequiredLevelCheckInterval); } if (string.IsNullOrEmpty(payload)) { continue; } var content = new StringContent(payload, Encoding.UTF8, ContentType); var result = await client.PostAsync(requestUri, content).ConfigureAwait(false); if (result.IsSuccessStatusCode) { connectionSchedule.MarkSuccess(); bookmark.WriteBookmark(nextLineBeginsAtOffset, currentFile); } else { connectionSchedule.MarkFailure(); SelfLog.WriteLine( "Received failed HTTP shipping result {0}: {1}", result.StatusCode, await result.Content.ReadAsStringAsync().ConfigureAwait(false)); break; } } else { // For whatever reason, there's nothing waiting to send. This means we should try connecting // again at the regular interval, so mark the attempt as successful. connectionSchedule.MarkSuccess(); // Only advance the bookmark if no other process has the // current file locked, and its length is as we found it. if (fileSet.Length == 2 && fileSet.First() == currentFile && IsUnlockedAtLength(currentFile, nextLineBeginsAtOffset)) { bookmark.WriteBookmark(0, fileSet[1]); } if (fileSet.Length > 2) { // Once there's a third file waiting to ship, we do our // best to move on, though a lock on the current file // will delay this. System.IO.File.Delete(fileSet[0]); } } } } while (count == batchPostingLimit); } catch (Exception e) { SelfLog.WriteLine("Exception while emitting periodic batch from {0}: {1}", this, e); connectionSchedule.MarkFailure(); } finally { lock (stateLock) { if (!unloading) { SetTimer(); } } } }