Example #1
0
        private async Task RunUploader(CancellationToken cancellationToken)
        {
            TimeSpan errorDelay = _serverErrorBackoffSettings.Delay;

            while (true)
            {
                List <LogEntryExtra> entries;
                // Wait/loop until there are some log entries that need uploading.
                while (true)
                {
                    DateTimeRange logEntriesLost;
                    lock (_lockObj)
                    {
                        logEntriesLost  = _logEntriesLost;
                        _logEntriesLost = null;
                    }
                    entries = await _logQ.PeekAsync(_maxUploadBatchSize - (logEntriesLost != null ? 1 : 0), cancellationToken);

                    if (logEntriesLost != null)
                    {
                        var lostEntryExtra = new LogEntryExtra(-1, MakeLostEntry(logEntriesLost));
                        entries = (new[] { lostEntryExtra }).Concat(entries ?? Enumerable.Empty <LogEntryExtra>()).ToList();
                    }
                    if (entries != null && entries.Count() > 0)
                    {
                        // There are log entries that need uploading, so do that now.
                        break;
                    }
                    await _uploadReadyEvent.WaitAsync(cancellationToken);
                }
                // Upload entries to the Cloud Logging server
                try
                {
                    await _client.WriteLogEntriesAsync(null, null, s_emptyLabels, entries.Select(x => x.Entry), cancellationToken);

                    await _logQ.RemoveUntilAsync(entries.Last().Id, cancellationToken);

                    lock (_lockObj)
                    {
                        _maxConfirmedSentId = entries.Last().Id;
                    }
                    _uploadCompleteEvent.Set();
                    errorDelay = _serverErrorBackoffSettings.Delay;
                }
                catch (Exception e)
                {
                    // Always retry, regardless of error, as there's nothing much else to be done.
                    await _scheduler.Delay(errorDelay, cancellationToken);

                    errorDelay = new TimeSpan((long)(errorDelay.Ticks * _serverErrorBackoffSettings.DelayMultiplier));
                    if (errorDelay > _serverErrorBackoffSettings.MaxDelay)
                    {
                        errorDelay = _serverErrorBackoffSettings.MaxDelay;
                    }
                    // Use log4net internal logging to warn user of upload error.
                    // Internal logging can be enabled as described in the "Troubleshooting" section of the log4net FAQ.
                    log4net.Util.LogLog.Warn(typeof(LogUploader), "Error uploading log messages to server.", e);
                }
            }
        }
Example #2
0
        private async Task RunUploader()
        {
            TimeSpan errorDelay = _serverErrorBackoffSettings.Delay;

            while (true)
            {
                IEnumerable <LogEntryExtra> entries;
                // Wait/loop until there are some log entries that need uploading.
                // TODO: See if log4net can be shutdown. If so, then this loop needs to terminate after
                // all log entries have been uploaded.
                while (true)
                {
                    DateTimeRange logEntriesLost;
                    lock (_lockObj)
                    {
                        logEntriesLost  = _logEntriesLost;
                        _logEntriesLost = null;
                    }
                    entries = await _logQ.PeekAsync(_maxUploadBatchSize - (logEntriesLost != null ? 1 : 0));

                    if (logEntriesLost != null)
                    {
                        var lostEntryExtra = new LogEntryExtra(-1, MakeLostEntry(logEntriesLost));
                        entries = (new[] { lostEntryExtra }).Concat(entries ?? Enumerable.Empty <LogEntryExtra>());
                    }
                    if (entries != null && entries.Count() > 0)
                    {
                        // There are log entries that need uploading, so do that now.
                        break;
                    }
                    await _uploadReadyEvent.WaitAsync();
                }
                // Upload entries to the Cloud Logging server
                try
                {
                    await _client.WriteLogEntriesAsync("", null, s_emptyLabels, entries.Select(x => x.Entry));

                    await _logQ.RemoveUntilAsync(entries.Last().Id);

                    _emptyEvent.Set();
                    errorDelay = _serverErrorBackoffSettings.Delay;
                }
                catch (Exception)
                {
                    // Always retry, regardless of error, as there's nothing much else to be done.
                    await _scheduler.Delay(errorDelay);

                    errorDelay = errorDelay.Scale(_serverErrorBackoffSettings.DelayMultiplier);
                    if (errorDelay > _serverErrorBackoffSettings.MaxDelay)
                    {
                        errorDelay = _serverErrorBackoffSettings.MaxDelay;
                    }
                }
            }
        }
Example #3
0
        // Note: calls to ConfigureAwait(false) aren't strictly required here,
        // as this method is only ever called in Task.Run, so there won't be a synchronization
        // context, but it's simple and harmless to make it "obviously okay".
        private async Task RunUploader(CancellationToken cancellationToken)
        {
            TimeSpan errorDelay = _serverErrorRetrySettings.InitialBackoff;

            while (true)
            {
                List <LogEntryExtra> entries;
                // Wait/loop until there are some log entries that need uploading.
                while (true)
                {
                    var peek = await _logQ.PeekAsync(_maxUploadBatchSize, cancellationToken).ConfigureAwait(false);

                    var logEntriesLost = peek.Lost;
                    entries = peek.Entries;
                    if (logEntriesLost != null)
                    {
                        var lostEntryExtra = new LogEntryExtra(-1, MakeLostEntry(logEntriesLost));
                        entries = (new[] { lostEntryExtra }).Concat(entries ?? Enumerable.Empty <LogEntryExtra>()).ToList();
                    }
                    if (entries != null && entries.Count() > 0)
                    {
                        // There are log entries that need uploading, so do that now.
                        break;
                    }
                    await _uploadReadyEvent.WaitAsync(cancellationToken).ConfigureAwait(false);
                }
                // Upload entries to the Cloud Logging server
                try
                {
                    await _client.WriteLogEntriesAsync((LogName)null, null, s_emptyLabels, entries.Select(x => x.Entry), cancellationToken).ConfigureAwait(false);

                    await _logQ.RemoveUntilAsync(entries.Last().Id, cancellationToken).ConfigureAwait(false);

                    lock (_lock)
                    {
                        _maxConfirmedSentId = entries.Last().Id;
                    }
                    _uploadCompleteEvent.Set();
                    errorDelay = _serverErrorRetrySettings.InitialBackoff;
                }
                catch (Exception e)
                {
                    // Always retry, regardless of error, as there's nothing much else to be done.
                    await _scheduler.Delay(errorDelay, cancellationToken).ConfigureAwait(false);

                    // TODO: Try to use RetryAttempt for this.
                    errorDelay = _serverErrorRetrySettings.NextBackoff(errorDelay);
                    // Use log4net internal logging to warn user of upload error.
                    // Internal logging can be enabled as described in the "Troubleshooting" section of the log4net FAQ.
                    log4net.Util.LogLog.Warn(typeof(LogUploader), "Error uploading log messages to server.", e);
                }
            }
        }