async Task OnTick() { LogEventLevel?minimumAcceptedLevel = LogEventLevel.Debug; try { //we'll use this to control the number of events read per cycle. If the batch limit is reached, //then there is probably more events queued and we should continue to read them. Otherwise, // we can wait for the next timer tick moment to see if anything new is available. int numberOfEventsRead; do { //this should consistently return the same batch of events until //a MarkAsProcessed message is sent to the provider. Never return a null, please... var payload = _bufferDataProvider.GetNextBatchOfEvents(); numberOfEventsRead = payload.Count(); if (numberOfEventsRead > 0) { //send the loggly events through the bulk API var result = await _logglyClient.Log(payload).ConfigureAwait(false); if (result.Code == ResponseCode.Success) { _connectionSchedule.MarkSuccess(); _bufferDataProvider.MarkCurrentBatchAsProcessed(); } else if (result.Code == ResponseCode.Error) { // The connection attempt was successful - the payload we sent was the problem. _connectionSchedule.MarkSuccess(); _bufferDataProvider.MarkCurrentBatchAsProcessed(); //move foward _invalidPayloadLogger.DumpInvalidPayload(result, payload); } else { _connectionSchedule.MarkFailure(); SelfLog.WriteLine("Received failed HTTP shipping result {0}: {1}", result.Code, result.Message); 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(); // not getting any batch may mean our marker is off, or at the end of the current, old file. // Try to move foward and cleanup _bufferDataProvider.MoveBookmarkForward(); } } while (numberOfEventsRead == _batchPostingLimit); //keep sending as long as we can retrieve a full batch. If not, wait for next tick } catch (Exception ex) { SelfLog.WriteLine("Exception while emitting periodic batch from {0}: {1}", this, ex); _connectionSchedule.MarkFailure(); } finally { lock (_stateLock) { _controlledSwitch.Update(minimumAcceptedLevel); if (!_unloading) { SetTimer(); } } } }
async Task OnTick() { LogEventLevel?minimumAcceptedLevel = LogEventLevel.Debug; try { // Locking the bookmark ensures that though there may be multiple instances of this // class running, only one will ship logs at a time. using (var bookmark = IOFile.Open(_bookmarkFilename, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read)) { using (var bookmarkStreamReader = new StreamReader(bookmark, Encoding.UTF8, false, 128)) { using (var bookmarkStreamWriter = new StreamWriter(bookmark)) { int count; do { count = 0; long nextLineBeginsAtOffset; string currentFile; TryReadBookmark(bookmark, bookmarkStreamReader, out nextLineBeginsAtOffset, out currentFile); var fileSet = GetFileSet(); if (currentFile == null || !IOFile.Exists(currentFile)) { nextLineBeginsAtOffset = 0; currentFile = fileSet.FirstOrDefault(); } if (currentFile == null) { continue; } //grab the list of pending LogglyEvents from the file var payload = GetListOfEvents(currentFile, ref nextLineBeginsAtOffset, ref count); if (count > 0) { //sen the loggly events through the bulk API var result = await _logglyClient.Log(payload).ConfigureAwait(false); if (result.Code == ResponseCode.Success) { _connectionSchedule.MarkSuccess(); WriteBookmark(bookmarkStreamWriter, nextLineBeginsAtOffset, currentFile); } else if (result.Code == ResponseCode.Error) { // The connection attempt was successful - the payload we sent was the problem. _connectionSchedule.MarkSuccess(); DumpInvalidPayload(result, payload); WriteBookmark(bookmarkStreamWriter, nextLineBeginsAtOffset, currentFile); } else { _connectionSchedule.MarkFailure(); SelfLog.WriteLine("Received failed HTTP shipping result {0}: {1}", result.Code, result.Message); 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)) { WriteBookmark(bookmarkStreamWriter, 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. IOFile.Delete(fileSet[0]); } } } while (count == _batchPostingLimit); } } } } catch (Exception ex) { SelfLog.WriteLine("Exception while emitting periodic batch from {0}: {1}", this, ex); _connectionSchedule.MarkFailure(); } finally { lock (_stateLock) { _controlledSwitch.Update(minimumAcceptedLevel); if (!_unloading) { SetTimer(); } } } }