예제 #1
0
        public void SkipLogEventGivenItExceedsBatchSizeLimit()
        {
            // Arrange
            using var stream = new MemoryStream();

            const string logEventExceedingBatchSizeLimit = "{ \"foo\": \"This document exceeds the batch size limit\" }";

            using var writer = new StreamWriter(stream, Encoding.UTF8WithoutBom);
            writer.Write(logEventExceedingBatchSizeLimit + Environment.NewLine);
            writer.Write(BarLogEvent + Environment.NewLine);
            writer.Flush();

            var batchSizeLimit = ByteSize.From(logEventExceedingBatchSizeLimit) - 1;

            // Act
            var got = BufferFileReader.Read(
                stream,
                ref nextLineBeginsAtOffset,
                null,
                null,
                batchSizeLimit);

            // Assert
            got.LogEvents.ShouldBe(new[] { BarLogEvent });
            got.HasReachedLimit.ShouldBeFalse();
            nextLineBeginsAtOffset.ShouldBe(stream.Length);
        }
예제 #2
0
        private static bool TryReadLine(Stream current, ref long nextStart, out string nextLine)
        {
            var includesBom = nextStart == 0;

            if (current.Length <= nextStart)
            {
                nextLine = null;
                return(false);
            }

            current.Position = nextStart;

            nextLine = ReadLine(current);

            if (nextLine == null)
            {
                return(false);
            }

            nextStart += ByteSize.From(nextLine) + ByteSize.From(Environment.NewLine);

            if (includesBom)
            {
                nextStart += 3;
            }

            return(true);
        }
        /// <summary>
        /// Checks the size of the log event body.
        /// </summary>
        /// <returns>true if body size is within acceptable range; otherwise false.</returns>
        protected bool CheckEventBodySize(string json)
        {
            if (eventBodyLimitBytes.HasValue &&
                ByteSize.From(json) > eventBodyLimitBytes.Value)
            {
                SelfLog.WriteLine(
                    "Event JSON representation exceeds the byte size limit of {0} set for this sink and will be dropped; data: {1}",
                    eventBodyLimitBytes,
                    json);

                return(false);
            }

            return(true);
        }
예제 #4
0
        public void Post([FromBody] string logEventBatch)
        {
            var contentType     = Request.ContentType;
            var contentEncoding = Request.Headers["Content-Encoding"].FirstOrDefault() ?? "";
            var contentLength   = (int?)Request.ContentLength ?? throw new Exception("No content length on request");

            var batchSize = ByteSize.From(logEventBatch);

            var logEventSizes = Json
                                .ParseArray(logEventBatch)
                                .Select(ByteSize.From)
                                .ToArray();

            _statistics.ReportReceivedBatch(contentType, contentEncoding, contentLength, batchSize, logEventSizes);
        }
    protected bool CheckEventBodySize(string json)
    {
        var sizeLimit = _options.EventSizeLimitBytes ?? 255 * ByteSize.KB;

        if (ByteSize.From(json) > sizeLimit)
        {
            SelfLog.WriteLine(
                "Event JSON representation exceeds the byte size limit of {0} set for this sink and will be dropped; data: {1}",
                sizeLimit,
                json);

            return(false);
        }

        return(true);
    }
        public static Batch Read(LogEventQueue queue, int batchPostingLimit, long batchSizeLimitBytes)
        {
            var batch = new Batch();
            var remainingBatchSizeBytes = batchSizeLimitBytes;

            while (true)
            {
                var result = queue.TryDequeue(remainingBatchSizeBytes, out var logEvent);
                if (result == LogEventQueue.DequeueResult.Ok)
                {
                    batch.LogEvents.Add(logEvent);
                    remainingBatchSizeBytes -= ByteSize.From(logEvent);

                    // Respect batch posting limit
                    if (batch.LogEvents.Count == batchPostingLimit)
                    {
                        batch.HasReachedLimit = true;
                        break;
                    }
                }
                else if (result == LogEventQueue.DequeueResult.MaxSizeViolation)
                {
                    if (batch.LogEvents.Count == 0)
                    {
                        // This single log event exceeds the batch size limit, let's drop it
                        queue.TryDequeue(long.MaxValue, out var logEventToDrop);

                        SelfLog.WriteLine(
                            "Event exceeds the batch size limit of {0} bytes set for this sink and will be dropped; data: {1}",
                            batchSizeLimitBytes,
                            logEventToDrop);
                    }
                    else
                    {
                        batch.HasReachedLimit = true;
                        break;
                    }
                }
                else if (result == LogEventQueue.DequeueResult.QueueEmpty)
                {
                    break;
                }
            }

            return(batch);
        }
        public void SkipLogEventGivenItExceedsBatchSizeLimit()
        {
            // Arrange
            const string logEventExceedingBatchSizeLimit = "{ \"foo\": \"This document exceeds the batch size limit\" }";

            var queue = new LogEventQueue(null);

            queue.Enqueue(logEventExceedingBatchSizeLimit);
            queue.Enqueue(BarLogEvent);

            var batchSizeLimit = ByteSize.From(logEventExceedingBatchSizeLimit) - 1;

            // Act
            var got = LogEventQueueReader.Read(queue, int.MaxValue, batchSizeLimit);

            // Assert
            got.LogEvents.ShouldBe(new[] { BarLogEvent });
            got.HasReachedLimit.ShouldBeFalse();
        }
예제 #8
0
        public void RespectLogEventLimitBytes()
        {
            // Arrange
            using var stream = new MemoryStream();

            using var writer = new StreamWriter(stream, Encoding.UTF8WithoutBom);
            writer.Write(FooLogEvent + Environment.NewLine);
            writer.Flush();

            var logEventLimitBytes = ByteSize.From(FooLogEvent) - 1;

            // Act
            var got = BufferFileReader.Read(
                stream,
                ref nextLineBeginsAtOffset,
                logEventLimitBytes,
                null,
                null);

            // Assert
            got.LogEvents.ShouldBeEmpty();
            got.HasReachedLimit.ShouldBeFalse();
            nextLineBeginsAtOffset.ShouldBe(stream.Length);
        }
예제 #9
0
        public static Batch Read(
            Stream stream,
            ref long nextLineBeginsAtOffset,
            int batchPostingLimit,
            long batchSizeLimitBytes)
        {
            var  batch          = new Batch();
            long batchSizeBytes = 0;

            while (true)
            {
                if (stream.Length <= nextLineBeginsAtOffset)
                {
                    break;
                }

                stream.Position = nextLineBeginsAtOffset;

                // Read log event
                var line = ReadLine(stream);
                if (string.IsNullOrEmpty(line.Text))
                {
                    break;
                }

                // Calculate the size of the log event
                var lineSizeBytes = ByteSize.From(line.Text);
                var includeLine   = true;

                // Respect batch size limit
                if (lineSizeBytes > batchSizeLimitBytes)
                {
                    // This single log event exceeds the batch size limit, let's drop it
                    includeLine = false;

                    SelfLog.WriteLine(
                        "Event exceeds the batch size limit of {0} bytes set for this sink and will be dropped; data: {1}",
                        batchSizeLimitBytes,
                        line);
                }
                else if (batchSizeBytes + lineSizeBytes > batchSizeLimitBytes)
                {
                    // The accumulated size of the batch is exceeding the batch size limit
                    batch.HasReachedLimit = true;
                    break;
                }

                // Update cursor
                nextLineBeginsAtOffset += lineSizeBytes + ByteSize.From(line.NewLine);

                // Add log event
                if (includeLine)
                {
                    batch.LogEvents.Add(line.Text);
                    batchSizeBytes += lineSizeBytes;
                }

                // Respect batch posting limit
                if (batch.LogEvents.Count == batchPostingLimit)
                {
                    batch.HasReachedLimit = true;
                    break;
                }
            }

            return(batch);
        }
예제 #10
0
        private void CreateBindings(ControlListenGroup clg)
        {
            txtUrl.BindValueTo(v => {
                isYoutube = txtUrl.IsValidUrl() && new Uri(v).Host.Contains("youtube.com");
            });

            txtUrl.BindValueTo(v => api.Arguments.Url = v).Listen(clg);


            nudVideoQualityWidth.BindEnableTo(rbVqCustom);
            nudVideoQualityHeight.BindEnableTo(rbVqCustom);
            nudFpsCustom.BindEnableTo(rbFpsCustom);

            gbVideoQuality.BindEnableTo(cbs => !cbs[0].Checked, cbCustomFormatSelector);
            gbFrameRate.BindEnableTo(cbs => !cbs[0].Checked, cbCustomFormatSelector);

            #region General

            cbIgnoreErrors.BindValueTo(v => api.Arguments.General.IgnoreErrors  = v).Listen(clg);
            cbAbortOnErrors.BindValueTo(v => api.Arguments.General.AbortOnError = v).Listen(clg);
            cbMarkWatched.BindValueTo(v => api.Arguments.General.MarkWatched    = isYoutube ? v : false, cbUsernamePassword, clg);

            #endregion

            #region Video Selection
            nudPlaylistStart.BindEnableTo(cbPlaylistStart).BindValueTo(v => api.Arguments.VideoSelection.PlaylistStart = (int?)v, cbPlaylistStart, clg);
            nudPlaylistEnd.BindEnableTo(cbPlaylistEnd).BindValueTo(v => api.Arguments.VideoSelection.PlaylistEnd       = (int?)v, cbPlaylistEnd, clg);
            txtPlaylistRange.BindEnableTo(cbPlaylistRange).BindValueTo(v => api.Arguments.VideoSelection.PlaylistItems = v, cbPlaylistRange, clg);
            txtMatchTitle.BindEnableTo(cbMatchTitle).BindValueTo(v => api.Arguments.VideoSelection.MatchTitle          = v, cbMatchTitle, clg);
            txtRejectTitle.BindEnableTo(cbRejectTitle).BindValueTo(v => api.Arguments.VideoSelection.RejectTitle       = v, cbRejectTitle, clg);
            nudMaxDownloads.BindEnableTo(cbMaxDownloads).BindValueTo(v => api.Arguments.VideoSelection.MaxDownloads    = (int?)v, cbMaxDownloads, clg);

            txtMatchFilter.BindEnableTo(cbMatchFilter).BindValueTo(v => api.Arguments.VideoSelection.MatchFilter = v, cbMatchFilter, clg);

            void filesizeMinEvt(float?v)
            {
                api.Arguments.VideoSelection.MinFilesize = (v == null || v == 0) ? (ByteSize?)null : ByteSize.From(v.Value, (FilesizeUnit)cbxFilesizeMinUnits.SelectedItem);
            }

            cbxFilesizeMinUnits.BindEnableTo(cbFilesizeMin).BindValueTo(obj => filesizeMinEvt(nudFilesizeMin.GetValueFloat(cbFilesizeMin))).Listen(clg);
            nudFilesizeMin.BindEnableTo(cbFilesizeMin).BindValueTo(filesizeMinEvt, cbFilesizeMin, clg);

            void filesizeMaxEvt(float?v)
            {
                api.Arguments.VideoSelection.MaxFilesize = (v == null || v == 0) ? (ByteSize?)null : ByteSize.From(v.Value, (FilesizeUnit)cbxFilesizeMaxUnits.SelectedItem);
            }

            cbxFilesizeMaxUnits.BindEnableTo(cbFilesizeMax).BindValueTo(obj => filesizeMaxEvt(nudFilesizeMax.GetValueFloat(cbFilesizeMax))).Listen(clg);
            nudFilesizeMax.BindEnableTo(cbFilesizeMax).BindValueTo(filesizeMaxEvt, cbFilesizeMax, clg);

            dtpDate.BindEnableTo(cbDate).BindValueTo(v => api.Arguments.VideoSelection.Date = v, cbDate, clg);
            dtpDateAfter.BindEnableTo(cbDateAfter).BindValueTo(v => api.Arguments.VideoSelection.DateAfter    = v, cbDateAfter, clg);
            dtpDateBefore.BindEnableTo(cbDateBefore).BindValueTo(v => api.Arguments.VideoSelection.DateBefore = v, cbDateBefore, clg);

            nudViewRangeMin.BindEnableTo(cbMinViews).BindValueTo(v => api.Arguments.VideoSelection.MinViews = (int?)v, cbMinViews, clg);
            nudViewRangeMax.BindEnableTo(cbMaxViews).BindValueTo(v => api.Arguments.VideoSelection.MaxViews = (int?)v, cbMaxViews, clg);

            ////    api.Arguments.VideoSelection.MatchFilter =

            rbPlaylistOnly.BindValueTo(v => api.Arguments.VideoSelection.YesPlaylist = v).Listen(clg);
            rbVideoOnly.BindValueTo(v => api.Arguments.VideoSelection.NoPlaylist     = v).Listen(clg);

            nudAgeLimit.BindEnableTo(cbAgeLimit).BindValueTo(v => api.Arguments.VideoSelection.AgeLimit = (int?)v, cbAgeLimit, clg);
            btnBrowseDownloadArchive.BindEnableTo(cbDownloadArchive);
            txtDownloadArchive.BindEnableTo(cbDownloadArchive).BindValueTo(v => {
                api.Arguments.VideoSelection.DownloadArchive = v;
            }, cbDownloadArchive, clg);

            #endregion

            #region Filesystem

            txtFileTemplate.BindEnableTo(cbFileTemplate).BindValueTo(v => { api.Arguments.FileSystem.OutputTemplate = v; }, cbFileTemplate, clg);
            cbRestrictFilenames.BindValueTo(v => api.Arguments.FileSystem.RestrictFilenames = v).Listen(clg);
            cbNoOverwrites.BindValueTo(v => api.Arguments.FileSystem.NoOverwrites           = v).Listen(clg);
            cbWriteDescription.BindValueTo(v => api.Arguments.FileSystem.WriteDescription   = v).Listen(clg);
            cbWriteAnnotations.BindValueTo(v => api.Arguments.FileSystem.WriteAnnotations   = v).Listen(clg);

            #endregion

            #region Network

            txtProxy.BindEnableTo(cbProxy).BindValueTo(v => api.Arguments.Network.Proxy = v, cbProxy, clg);
            txtSourceAddress.BindEnableTo(cbSourceAddress).BindValueTo(v => api.Arguments.Network.SourceAddress = v, cbSourceAddress, clg);
            nudSocketTimeout.BindEnableTo(cbSocketTimeout).BindValueTo(v => api.Arguments.Network.SocketTimeout = (int?)v, cbSocketTimeout, clg);
            rbForceIpv4.BindValueTo(v => api.Arguments.Network.ForceIpv4 = v).Listen(clg);
            rbForceIpv6.BindValueTo(v => api.Arguments.Network.ForceIpv6 = v).Listen(clg);

            #endregion

            #region Download

            void limitRateEvt(float?v)
            {
                api.Arguments.Download.LimitRate = (v == null || v == 0) ? (ByteSize?)null : ByteSize.From(v.Value, (FilesizeUnit)cbxLimitRateUnits.SelectedItem);
            }

            cbxLimitRateUnits.BindEnableTo(cbLimitRate).BindValueTo(obj => limitRateEvt(nudLimitRate.GetValueFloat(cbLimitRate))).Listen(clg);
            nudLimitRate.BindEnableTo(cbLimitRate).BindValueTo(limitRateEvt, cbLimitRate, clg);

            cbRetriesInf.BindEnableTo(cbRetries);
            nudRetries.BindEnableTo(cbs => {
                return(cbs[0].Checked && !cbs[1].Checked);
            }, cbRetries, cbRetriesInf).BindValueTo(v => api.Arguments.Download.Retries = (v == null) ? null : v >= 0 ? v.ToString() : "infinite", cbRetries, clg);

            cbFragmentRetriesInf.BindEnableTo(cbFragmentRetries);
            nudFragmentRetries.BindEnableTo(cbs => {
                return(cbs[0].Checked && !cbs[1].Checked);
            }, cbFragmentRetries, cbFragmentRetriesInf).BindValueTo(v => api.Arguments.Download.FragmentRetries = (v == null) ? null : v >= 0 ? v.ToString() : "infinite", cbFragmentRetries, clg);

            cbPlaylistRandom.BindValueTo(v => api.Arguments.Download.PlaylistRandom    = v).Listen(clg);
            cbPlaylistReversed.BindValueTo(v => api.Arguments.Download.PlaylistReverse = v).Listen(clg);

            #endregion

            cbWriteThumbnail.BindValueTo(v => api.Arguments.Thumbnail.WriteThumbnail = v).Listen(clg);

            #region Workarounds

            txtReferer.BindEnableTo(cbReferer).BindValueTo(v => api.Arguments.Workarounds.Referer       = v, cbReferer, clg);
            txtUserAgent.BindEnableTo(cbUserAgent).BindValueTo(v => api.Arguments.Workarounds.UserAgent = v, cbUserAgent, clg);

            dgvHeaders.BindValueTo(v => {
                api.Arguments.Workarounds.Headers.Clear();
                foreach (DataGridViewRow row in v)
                {
                    string key   = row.Cells["cKey"].Value as string;
                    string value = row.Cells["cValue"].Value as string;
                    if (!string.IsNullOrWhiteSpace(key) && !string.IsNullOrWhiteSpace(value))
                    {
                        api.Arguments.Workarounds.Headers.Add(key, value);
                    }
                }
            }).Listen(clg);

            nudSleepValue.BindEnableTo(rbSleepValue).BindValueTo(v => api.Arguments.Workarounds.SleepInterval       = (int?)v, rbSleepValue, clg);
            nudSleepRangeMin.BindEnableTo(rbSleepRange).BindValueTo(v => api.Arguments.Workarounds.MinSleepInterval = (int?)v, rbSleepRange, clg);
            nudSleepRangeMax.BindEnableTo(rbSleepRange).BindValueTo(v => api.Arguments.Workarounds.MaxSleepInterval = (int?)v, rbSleepRange, clg);

            #endregion

            #region Auth

            string user = null, pass = null;
            txtPassword.BindEnableTo(cbUsernamePassword).BindValueTo(v => api.Arguments.Authentication.Password = v, cbUsernamePassword, clg);
            txtPassword.BindValueTo(v => {
                pass = v;
                if (string.IsNullOrWhiteSpace(user) || string.IsNullOrWhiteSpace(pass))
                {
                    api.Arguments.Authentication.Username = null;
                    api.Arguments.Authentication.Password = null;
                }
                else
                {
                    api.Arguments.Authentication.Username = user;
                    api.Arguments.Authentication.Password = pass;
                }
                clg.Trigger();
            }, cbUsernamePassword);
            txtUsername.BindEnableTo(cbUsernamePassword).BindValueTo(v => {
                user = v;
                if (string.IsNullOrWhiteSpace(user) || string.IsNullOrWhiteSpace(pass))
                {
                    api.Arguments.Authentication.Username = null;
                    api.Arguments.Authentication.Password = null;
                }
                else
                {
                    api.Arguments.Authentication.Username = user;
                    api.Arguments.Authentication.Password = pass;
                }
                clg.Trigger();
            }, cbUsernamePassword, clg);
            txtTwoFactor.BindEnableTo(cbTwoFactor).BindValueTo(v => api.Arguments.Authentication.TwoFactor             = v, cbTwoFactor, clg);
            txtVideoPassword.BindEnableTo(cbVideoPassword).BindValueTo(v => api.Arguments.Authentication.VideoPassword = v, cbVideoPassword, clg);

            #endregion

            #region Post Processing
            api.Arguments.PostProcessing.PreferFFmpeg   = true;
            api.Arguments.PostProcessing.FFmpegLocation = ffmpegPath;
            cbxRecodeFormat.BindEnableTo(cbRecodeFormat).BindValueTo(v => api.Arguments.PostProcessing.RecodeVideo = (VideoFormatRecode?)v, cbRecodeFormat, clg);
            #endregion

            #region Video Format

            ControlListenGroup formatGroup = ControlListenGroup.New();
            txtCustomFormatSelector.BindEnableTo(cbCustomFormatSelector).BindValueTo(v => api.Arguments.VideoFormat.Format = v, cbCustomFormatSelector, formatGroup);

            cbxOutputFormat.BindEnableTo(cbOutputFormat).BindValueTo(v => api.Arguments.VideoFormat.MergeOutputFormat = (v == null) ? null : (MergeVideoFormat?)v, cbOutputFormat, clg);

            formatGroup.Listen(rbVq2160p, rbVq1440p, rbVq1080p, rbVq720p, rbVq480p, rbVq360p, rbVq240p, rbVqCustom, rbFps144, rbFps120, rbFps60, rbFps30, rbFps25, rbFpsCustom);
            formatGroup.Listen(cbVqPreferred, cbFpsPreferred, cbVqFallback, cbFpsFallback);
            formatGroup.Listen(nudFpsCustom, nudVideoQualityWidth, nudVideoQualityHeight);

            formatGroup.OnChanged += () => {
                if (!cbCustomFormatSelector.Checked)
                {
                    api.Arguments.VideoFormat.Format = GetVideoQuality().FormatSelector;
                }

                VideoQuality vq = GetVideoQuality();
                if (!rbVqCustom.Checked)
                {
                    nudVideoQualityWidth.Value  = vq.Width;
                    nudVideoQualityHeight.Value = vq.Height;
                }
                if (!rbFpsCustom.Checked)
                {
                    nudFpsCustom.Value = vq.Fps;
                }

                if (!cbCustomFormatSelector.Checked)
                {
                    txtCustomFormatSelector.Text = vq.FormatSelector;
                }

                clg.Trigger();
            };
            formatGroup.Trigger();


            #endregion
        }