コード例 #1
0
        public void ShouldRaiseFlushFailedOnFlushAsyncWhenEventHubClientFails()
        {
            var eventHubClient = Substitute.For <IEventHubClient>();

            using (var sink = new EventHubAmqpSink(eventHubClient, Buffering.DefaultBufferingInterval, Buffering.DefaultBufferingCount, Buffering.DefaultMaxBufferSize, TimeSpan.Zero))
                using (var collectErrorsListener = new MockEventListener())
                {
                    collectErrorsListener.EnableEvents(SemanticLoggingEventSource.Log, EventLevel.Error, Keywords.All);
                    eventHubClient.When(client => client.SendBatchAsync(Arg.Any <IEnumerable <EventData> >()))
                    .Do(action => { throw new Exception(); });

                    sink.OnNext(EventEntryTestHelper.Create());

                    try
                    {
                        sink.FlushAsync().Wait();
                        Assert.Fail("AggregateException should be thrown.");
                    }
                    catch (AggregateException ex)
                    {
                        Assert.IsInstanceOfType(ex.InnerException, typeof(FlushFailedException));
                    }

                    Assert.IsTrue(collectErrorsListener.WrittenEntries.Any(x => x.EventId == 1));
                }
        }
コード例 #2
0
        public void ShouldRaiseFlushFailedOnFlushAsyncWhenEventHubClientFails()
        {
            var eventHubClient = Substitute.For<IEventHubClient>();
            using (var sink = new EventHubAmqpSink(eventHubClient, Buffering.DefaultBufferingInterval, Buffering.DefaultBufferingCount, Buffering.DefaultMaxBufferSize, TimeSpan.Zero))
            using (var collectErrorsListener = new MockEventListener())
            {
                collectErrorsListener.EnableEvents(SemanticLoggingEventSource.Log, EventLevel.Error, Keywords.All);
                eventHubClient.When(client => client.SendBatchAsync(Arg.Any<IEnumerable<EventData>>()))
                    .Do(action => { throw new Exception(); });

                sink.OnNext(EventEntryTestHelper.Create());

                try
                {
                    sink.FlushAsync().Wait();
                    Assert.Fail("AggregateException should be thrown.");
                }
                catch (AggregateException ex)
                {
                    Assert.IsInstanceOfType(ex.InnerException, typeof(FlushFailedException));
                }
                
                Assert.IsTrue(collectErrorsListener.WrittenEntries.Any(x => x.EventId == 1));
            }
        }
コード例 #3
0
        public async Task ShouldWriteEntriesOnFlushAsync()
        {
            var eventHubClient = Substitute.For<IEventHubClient>();
            using (var sink = new EventHubAmqpSink(eventHubClient, Buffering.DefaultBufferingInterval, Buffering.DefaultBufferingCount, Buffering.DefaultMaxBufferSize, TimeSpan.Zero))
            {
                sink.OnNext(EventEntryTestHelper.Create());
                sink.OnNext(EventEntryTestHelper.Create());

                await sink.FlushAsync();
            }

            eventHubClient.Received().SendBatchAsync(Arg.Is<IEnumerable<EventData>>(l => l.Count() == 2)).Wait();
        }
コード例 #4
0
        /// <summary>
        /// Subscribes to an <see cref="IObservable{EventEntry}" /> using a <see cref="EventHubAmqpSink" />.
        /// </summary>
        /// <param name="eventStream">The event stream. Typically this is an instance of <see cref="ObservableEventListener" />.</param>
        /// <param name="eventHubConnectionString">The connection string for the eventhub.</param>
        /// <param name="eventHubName">The name of the eventhub.</param>
        /// <param name="bufferingInterval">The buffering interval between each batch publishing. Default value is <see cref="Buffering.DefaultBufferingInterval" />.</param>
        /// <param name="bufferingCount">The number of entries that will trigger a batch publishing.</param>
        /// <param name="onCompletedTimeout">Defines a timeout interval for when flushing the entries after an <see cref="EventHubAmqpSink.OnCompleted" /> call is received and before disposing the sink.</param>
        /// <param name="maxBufferSize">The maximum number of entries that can be buffered while it's sending to Azure EventHub before the sink starts dropping entries.
        /// This means that if the timeout period elapses, some event entries will be dropped and not sent to the store. Normally, calling <see cref="IDisposable.Dispose" /> on
        /// the <see cref="System.Diagnostics.Tracing.EventListener" /> will block until all the entries are flushed or the interval elapses.
        /// If <see langword="null" /> is specified, then the call will block indefinitely until the flush operation finishes.</param>
        /// <param name="partitionKey">PartitionKey is optional. If no partition key is supplied the log messages are sent to eventhub 
        /// and distributed to various partitions in a round robin manner.</param>
        /// <returns>
        /// A subscription to the sink that can be disposed to unsubscribe the sink and dispose it, or to get access to the sink instance.
        /// </returns>
        public static SinkSubscription<EventHubAmqpSink> LogToEventHubUsingAmqp(this IObservable<EventEntry> eventStream, string eventHubConnectionString, string eventHubName, TimeSpan? bufferingInterval = null, int bufferingCount = Buffering.DefaultBufferingCount, TimeSpan? onCompletedTimeout = null, int maxBufferSize = Buffering.DefaultMaxBufferSize, string partitionKey = null)
        {
            var sink = new EventHubAmqpSink(
                eventHubConnectionString,
                eventHubName,
                bufferingInterval ?? Buffering.DefaultBufferingInterval,
                bufferingCount,
                maxBufferSize,
                onCompletedTimeout ?? Timeout.InfiniteTimeSpan,
                partitionKey);

            var subscription = eventStream.Subscribe(sink);
            return new SinkSubscription<EventHubAmqpSink>(subscription, sink);
        }
コード例 #5
0
        public async Task ShouldWriteEntriesOnFlushAsync()
        {
            var eventHubClient = Substitute.For <IEventHubClient>();

            using (var sink = new EventHubAmqpSink(eventHubClient, Buffering.DefaultBufferingInterval, Buffering.DefaultBufferingCount, Buffering.DefaultMaxBufferSize, TimeSpan.Zero))
            {
                sink.OnNext(EventEntryTestHelper.Create());
                sink.OnNext(EventEntryTestHelper.Create());

                await sink.FlushAsync();
            }

            eventHubClient.Received().SendBatchAsync(Arg.Is <IEnumerable <EventData> >(l => l.Count() == 2)).Wait();
        }
コード例 #6
0
        public async Task ShouldWritePartitionKey()
        {
            var          eventHubClient = Substitute.For <IEventHubClient>();
            var          entry          = EventEntryTestHelper.Create();
            const string partitionKey   = "PartitionKey";

            using (var sink = new EventHubAmqpSink(eventHubClient, Buffering.DefaultBufferingInterval, Buffering.DefaultBufferingCount, Buffering.DefaultMaxBufferSize, TimeSpan.Zero, partitionKey))
            {
                sink.OnNext(entry);

                await sink.FlushAsync();
            }

            eventHubClient.Received().SendBatchAsync(Arg.Is <IEnumerable <EventData> >(l => l.First().PartitionKey == partitionKey)).Wait();
        }
コード例 #7
0
        public void ShouldNotStallOrThrowWhenEventHubClientFails()
        {
            var eventHubClient = Substitute.For<IEventHubClient>();
            using (var sink = new EventHubAmqpSink(eventHubClient, Buffering.DefaultBufferingInterval, Buffering.DefaultBufferingCount, Buffering.DefaultMaxBufferSize, TimeSpan.Zero))
            using (var collectErrorsListener = new MockEventListener())
            {
                collectErrorsListener.EnableEvents(SemanticLoggingEventSource.Log, EventLevel.Error, Keywords.All);
                eventHubClient.When(client => client.SendBatchAsync(Arg.Any<IEnumerable<EventData>>()))
                    .Do(action => { throw new Exception(); });

                sink.OnNext(EventEntryTestHelper.Create());

                Assert.IsTrue(Task.Run(() => sink.OnCompleted()).Wait(TimeSpan.FromSeconds(5)));
                Assert.IsTrue(collectErrorsListener.WrittenEntries.Any(x => x.EventId == 1));
            }
        }
コード例 #8
0
        public async Task ShouldWriteProperties()
        {
            var eventHubClient = Substitute.For <IEventHubClient>();
            var entry          = EventEntryTestHelper.Create();

            using (var sink = new EventHubAmqpSink(eventHubClient, Buffering.DefaultBufferingInterval, Buffering.DefaultBufferingCount, Buffering.DefaultMaxBufferSize, TimeSpan.Zero))
            {
                sink.OnNext(entry);

                await sink.FlushAsync();
            }

            var byteRepresentation = Encoding.Default.GetBytes(JsonConvert.SerializeObject(entry));

            eventHubClient.Received().SendBatchAsync(Arg.Is <IEnumerable <EventData> >(l => byteRepresentation.SequenceEqual(l.First().GetBytes()))).Wait();
        }
コード例 #9
0
        public void ShouldNotStallOrThrowWhenEventHubClientFails()
        {
            var eventHubClient = Substitute.For <IEventHubClient>();

            using (var sink = new EventHubAmqpSink(eventHubClient, Buffering.DefaultBufferingInterval, Buffering.DefaultBufferingCount, Buffering.DefaultMaxBufferSize, TimeSpan.Zero))
                using (var collectErrorsListener = new MockEventListener())
                {
                    collectErrorsListener.EnableEvents(SemanticLoggingEventSource.Log, EventLevel.Error, Keywords.All);
                    eventHubClient.When(client => client.SendBatchAsync(Arg.Any <IEnumerable <EventData> >()))
                    .Do(action => { throw new Exception(); });

                    sink.OnNext(EventEntryTestHelper.Create());

                    Assert.IsTrue(Task.Run(() => sink.OnCompleted()).Wait(TimeSpan.FromSeconds(5)));
                    Assert.IsTrue(collectErrorsListener.WrittenEntries.Any(x => x.EventId == 1));
                }
        }
コード例 #10
0
        public async Task ShouldWriteProperties()
        {
            var eventHubClient = Substitute.For<IEventHubClient>();
            var entry = EventEntryTestHelper.Create();
            using (var sink = new EventHubAmqpSink(eventHubClient, Buffering.DefaultBufferingInterval, Buffering.DefaultBufferingCount, Buffering.DefaultMaxBufferSize, TimeSpan.Zero))
            {
                sink.OnNext(entry);
                
                await sink.FlushAsync();
            }

            var byteRepresentation = Encoding.Default.GetBytes(JsonConvert.SerializeObject(entry));

            eventHubClient.Received().SendBatchAsync(Arg.Is<IEnumerable<EventData>>(l => byteRepresentation.SequenceEqual(l.First().GetBytes()))).Wait();
        }
コード例 #11
0
        public async Task ShouldWritePartitionKey()
        {
            var eventHubClient = Substitute.For<IEventHubClient>();
            var entry = EventEntryTestHelper.Create();
            const string partitionKey = "PartitionKey";

            using (var sink = new EventHubAmqpSink(eventHubClient, Buffering.DefaultBufferingInterval, Buffering.DefaultBufferingCount, Buffering.DefaultMaxBufferSize, TimeSpan.Zero, partitionKey))
            {
                sink.OnNext(entry);

                await sink.FlushAsync();
            }

            eventHubClient.Received().SendBatchAsync(Arg.Is<IEnumerable<EventData>>(l => l.First().PartitionKey == partitionKey)).Wait();
        }