Пример #1
0
        private async Task OnTick()
        {
            try
            {
                int count;

                do
                {
                    count = 0;

                    // 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))
                    {
                        long   nextLineBeginsAtOffset;
                        string currentFile;

                        TryReadBookmark(bookmark, out nextLineBeginsAtOffset, out currentFile);

                        var fileSet = GetFileSet();

                        if (currentFile == null || !IOFile.Exists(currentFile))
                        {
                            nextLineBeginsAtOffset = 0;
                            currentFile            = fileSet.FirstOrDefault();
                        }

                        if (currentFile == null)
                        {
                            continue;
                        }

                        var payload = ReadPayload(currentFile, ref nextLineBeginsAtOffset, ref count);

                        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();

                                WriteBookmark(bookmark, 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))
                            {
                                WriteBookmark(bookmark, 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 e)
            {
                SelfLog.WriteLine("Exception while emitting periodic batch from {0}: {1}", this, e);
                connectionSchedule.MarkFailure();
            }
            finally
            {
                lock (stateLock)
                {
                    if (!unloading)
                    {
                        SetTimer();
                    }
                }
            }
        }
        private async Task OnTick()
        {
            try
            {
                int count;

                do
                {
                    count = 0;

                    using (var bookmark = new BookmarkFile(bufferFiles.BookmarkFileName))
                    {
                        bookmark.TryReadBookmark(out var nextLineBeginsAtOffset, out var currentFile);

                        var fileSet = bufferFiles.Get();

                        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();
                    }
                }
            }
        }