public void GivingTheLastSeenEventKeyRemovesPrecedingEvents() { using (var temp = TempFolder.ForCaller()) using (var buffer = new LogBuffer(temp.AllocateFilename("mdb"), DefaultBufferSize)) { byte[] a1 = Some.Bytes(140), a2 = Some.Bytes(140), a3 = Some.Bytes(140); buffer.Enqueue(new[] { a1, a2, a3 }); var contents = buffer.Peek(420); Assert.Equal(3, contents.Length); buffer.Dequeue(contents[2].Key); var remaining = buffer.Peek(420); Assert.Equal(0, remaining.Length); } }
void OnTick() { try { var sendingSingles = 0; do { var available = _logBuffer.Peek((int)_outputConfig.RawPayloadLimitBytes); if (available.Length == 0) { // 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(); break; } Stream payload; ulong lastIncluded; MakePayload(available, sendingSingles > 0, out payload, out lastIncluded); var content = new StreamContent(new UnclosableStreamWrapper(payload)); content.Headers.ContentType = new MediaTypeHeaderValue("application/json") { CharSet = Encoding.UTF8.WebName }; if (!string.IsNullOrWhiteSpace(_outputConfig.ApiKey)) { content.Headers.Add(ApiKeyHeaderName, _outputConfig.ApiKey); } var result = _httpClient.PostAsync(BulkUploadResource, content).Result; if (result.IsSuccessStatusCode) { _connectionSchedule.MarkSuccess(); _logBuffer.Dequeue(lastIncluded); if (sendingSingles > 0) { sendingSingles--; } } else if (result.StatusCode == HttpStatusCode.BadRequest || result.StatusCode == HttpStatusCode.RequestEntityTooLarge) { // The connection attempt was successful - the payload we sent was the problem. _connectionSchedule.MarkSuccess(); if (sendingSingles != 0) { payload.Position = 0; var payloadText = new StreamReader(payload, Encoding.UTF8).ReadToEnd(); Log.Error("HTTP shipping failed with {StatusCode}: {Result}; payload was {InvalidPayload}", result.StatusCode, result.Content.ReadAsStringAsync().Result, payloadText); _logBuffer.Dequeue(lastIncluded); sendingSingles = 0; } else { // Unscientific (shoudl "binary search" in batches) but sending the next // hundred events singly should flush out the problematic one. sendingSingles = 100; } } else { _connectionSchedule.MarkFailure(); Log.Error("Received failed HTTP shipping result {StatusCode}: {Result}", result.StatusCode, result.Content.ReadAsStringAsync().Result); break; } }while (true); } catch (Exception ex) { Log.Error(ex, "Exception while sending a batch from the log shipper"); _connectionSchedule.MarkFailure(); } finally { lock (_stateLock) { if (!_unloading) { SetTimer(); } } } }