示例#1
0
        /// <summary>
        /// Processes an incoming telemetry batch for OpenCensus channel.
        /// </summary>
        /// <remarks>This method may be called from multiple threads concurrently.</remarks>
        private void OnOcBatchReceived(ExportSpanRequest batch)
        {
            try
            {
                // send incoming telemetry items to the telemetryClient
                foreach (Span span in batch.Spans)
                {
                    try
                    {
                        //!!!
                        Diagnostics.LogTrace($"OpenCensus message received: {batch.Spans.Count} spans, first span: {batch.Spans.First().Name}");

                        this.telemetryClient.TrackSpan(span, this.ocToAiInstrumentationKey);
                    }
                    catch (Exception e)
                    {
                        // an unexpected issue while tracking an item
                        // log and carry on
                        Diagnostics.LogError(
                            FormattableString.Invariant(
                                $"Could not track an incoming OpenCensus telemetry item. {e.ToString()}"));
                    }
                }
            }
            catch (Exception e)
            {
                // an unexpected issue while processing the batch
                // log and carry on
                Diagnostics.LogError(
                    FormattableString.Invariant(
                        $"Could not process an incoming OpenCensus telemetry batch. {e.ToString()}"));
            }
        }
        public async Task GrpcOpenCensusInputTests_StopsAndRestarts()
        {
            // ARRANGE
            int batchesReceived             = 0;
            ExportSpanRequest receivedBatch = null;

            int port  = GetPort();
            var input = new GrpcOpenCensusInput("localhost", port);

            input.Start(exportSpanRequest =>
            {
                batchesReceived++;
                receivedBatch = exportSpanRequest;
            });

            Assert.IsTrue(SpinWait.SpinUntil(() => input.IsRunning, GrpcOpenCensusInputTests.DefaultTimeout));

            var grpcWriter = new GrpcWriter(false, port);

            ExportSpanRequest batch = new ExportSpanRequest();

            batch.Spans.Add(new Span()
            {
                Name = new TruncatableString()
                {
                    Value = "Event1"
                }
            });

            await grpcWriter.Write(batch).ConfigureAwait(false);

            Common.AssertIsTrueEventually(
                () => input.GetStats().BatchesReceived == 1 && batchesReceived == 1 &&
                receivedBatch.Spans.Single().Name.Value == "Event1", GrpcOpenCensusInputTests.DefaultTimeout);

            // ACT
            input.Stop();

            Common.AssertIsTrueEventually(
                () => !input.IsRunning && input.GetStats().BatchesReceived == 1 && batchesReceived == 1 &&
                receivedBatch.Spans.Single().Name.Value == "Event1", GrpcOpenCensusInputTests.DefaultTimeout);

            input.Start(exportSpanRequest =>
            {
                batchesReceived++;
                receivedBatch = exportSpanRequest;
            });

            Assert.IsTrue(SpinWait.SpinUntil(() => input.IsRunning, GrpcOpenCensusInputTests.DefaultTimeout));

            grpcWriter = new GrpcWriter(false, port);
            batch.Spans.Single().Name.Value = "Event2";
            await grpcWriter.Write(batch).ConfigureAwait(false);

            // ASSERT
            Common.AssertIsTrueEventually(
                () => input.IsRunning && input.GetStats().BatchesReceived == 1 && batchesReceived == 2 &&
                receivedBatch.Spans.Single().Name.Value == "Event2", GrpcOpenCensusInputTests.DefaultTimeout);
        }
        public async Task HostTests_StopsLibrary()
        {
            // ARRANGE
            var telemetryClient = Common.SetupStubTelemetryClient(out var sentItems);

            int portAI = Common.GetPort();
            int portOC = Common.GetPort();

            var config = $@"<?xml version=""1.0"" encoding=""utf-8"" ?>
<LocalForwarderConfiguration>
  <Inputs>
    <ApplicationInsightsInput Enabled=""true"">
      <Host>0.0.0.0</Host>
      <Port>{portAI}</Port>
    </ApplicationInsightsInput>
    <OpenCensusInput Enabled=""true"">
      <Host>0.0.0.0</Host>
      <Port>{portOC}</Port>
    </OpenCensusInput>
  </Inputs>
  <OpenCensusToApplicationInsights>
    <InstrumentationKey>ikey1</InstrumentationKey>
  </OpenCensusToApplicationInsights>
</LocalForwarderConfiguration>
";

            Host host = new Host(telemetryClient);

            host.Run(config, TimeSpan.FromSeconds(5));
            Thread.Sleep(TimeSpan.FromMilliseconds(250));

            // ACT
            host.Stop();
            Thread.Sleep(TimeSpan.FromMilliseconds(250));

            var telemetryBatch = new ExportSpanRequest();

            telemetryBatch.Spans.Add(new Span()
            {
                Name = new TruncatableString()
                {
                    Value = "Span1"
                }, Kind = Span.Types.SpanKind.Server
            });
            telemetryBatch.Spans.Add(new Span()
            {
                Name = new TruncatableString()
                {
                    Value = "Span2"
                }, Kind = Span.Types.SpanKind.Client
            });

            // ASSERT
            var writer = new GrpcWriter(false, portOC);
            await writer.Write(telemetryBatch).ConfigureAwait(false);

            Assert.Fail();
        }
示例#4
0
        public async Task Write(ExportSpanRequest batch)
        {
            if (this.aiMode)
            {
                throw new InvalidOperationException("Incorrect mode");
            }

            try
            {
                await this.openCensusStreamingCall.RequestStream.WriteAsync(batch).ConfigureAwait(false);
            }
            catch (System.Exception e)
            {
                throw new InvalidOperationException(
                          FormattableString.Invariant($"Error sending a message via gRpc. {e.ToString()}"));
            }
        }
        public async Task GrpcOpenCensusInputTests_ReceivesDataFromMultipleClients()
        {
            // ARRANGE
            int batchesReceived             = 0;
            ExportSpanRequest receivedBatch = null;

            int port  = GetPort();
            var input = new GrpcOpenCensusInput("localhost", port);

            input.Start(exportSpanRequest =>
            {
                Interlocked.Increment(ref batchesReceived);
                receivedBatch = exportSpanRequest;
            });
            Assert.IsTrue(SpinWait.SpinUntil(() => input.IsRunning, GrpcOpenCensusInputTests.DefaultTimeout));

            // ACT
            ExportSpanRequest batch = new ExportSpanRequest();

            batch.Spans.Add(new Span()
            {
                Name = new TruncatableString()
                {
                    Value = "Event1"
                }
            });

            Parallel.For(0, 1000, new ParallelOptions()
            {
                MaxDegreeOfParallelism = 1000
            }, async i =>
            {
                var grpcWriter = new GrpcWriter(false, port);

                await grpcWriter.Write(batch).ConfigureAwait(false);
            });

            // ASSERT
            Common.AssertIsTrueEventually(
                () => input.GetStats().BatchesReceived == 1000 && batchesReceived == 1000, GrpcOpenCensusInputTests.DefaultTimeout);

            input.Stop();
            Assert.IsTrue(SpinWait.SpinUntil(() => !input.IsRunning, GrpcOpenCensusInputTests.DefaultTimeout));
        }
        public async Task GrpcOpenCensusInputTests_HandlesExceptionsInProcessingHandler()
        {
            // ARRANGE
            int port  = GetPort();
            var input = new GrpcOpenCensusInput("localhost", port);

            input.Start(exportSpanRequest => throw new InvalidOperationException());

            Assert.IsTrue(SpinWait.SpinUntil(() => input.IsRunning, GrpcOpenCensusInputTests.DefaultTimeout));

            var grpcWriter = new GrpcWriter(false, port);

            ExportSpanRequest batch = new ExportSpanRequest();

            batch.Spans.Add(new Span()
            {
                Name = new TruncatableString()
                {
                    Value = "Event1"
                }
            });

            // ACT
            await grpcWriter.Write(batch).ConfigureAwait(false);

            // ASSERT

            // must have handled the exception by logging it
            // should still be able to process items
            Common.AssertIsTrueEventually(
                () => input.IsRunning && input.GetStats().BatchesReceived == 0 && input.GetStats().BatchesFailed == 1,
                GrpcOpenCensusInputTests.DefaultTimeout);

            await grpcWriter.Write(batch).ConfigureAwait(false);

            Common.AssertIsTrueEventually(
                () => input.IsRunning && input.GetStats().BatchesReceived == 0 && input.GetStats().BatchesFailed == 2,
                GrpcOpenCensusInputTests.DefaultTimeout);
        }
示例#7
0
        public async Task LibraryTests_LibraryProcessesOcBatchesCorrectly()
        {
            // ARRANGE
            var telemetryClient = Common.SetupStubTelemetryClient(out var sentItems);

            int portAI = Common.GetPort();
            int portOC = Common.GetPort();

            var config = $@"<?xml version=""1.0"" encoding=""utf-8"" ?>
<LocalForwarderConfiguration>
  <Inputs>
    <ApplicationInsightsInput Enabled=""true"">
      <Host>0.0.0.0</Host>
      <Port>{portAI}</Port>
    </ApplicationInsightsInput>
    <OpenCensusInput Enabled=""true"">
      <Host>0.0.0.0</Host>
      <Port>{portOC}</Port>
    </OpenCensusInput>
  </Inputs>
  <OpenCensusToApplicationInsights>
    <InstrumentationKey>ikey1</InstrumentationKey>
  </OpenCensusToApplicationInsights>
  <ApplicationInsights>
    <LiveMetricsStreamInstrumentationKey>[SPECIFY LIVE METRICS STREAM INSTRUMENTATION KEY HERE]</LiveMetricsStreamInstrumentationKey>
  </ApplicationInsights>
</LocalForwarderConfiguration>
";

            var telemetryBatch = new ExportSpanRequest();

            telemetryBatch.Spans.Add(new Span()
            {
                Name = new TruncatableString()
                {
                    Value = "Span1"
                }, Kind = Span.Types.SpanKind.Server
            });
            telemetryBatch.Spans.Add(new Span()
            {
                Name = new TruncatableString()
                {
                    Value = "Span2"
                }, Kind = Span.Types.SpanKind.Client
            });

            var lib = new Library(config, telemetryClient);

            lib.Run();

            // ACT
            var writer = new GrpcWriter(false, portOC);
            await writer.Write(telemetryBatch).ConfigureAwait(false);

            // ASSERT
            Common.AssertIsTrueEventually(() => sentItems.Count == 2);

            lib.Stop();

            Assert.AreEqual("Span1", (sentItems.Skip(0).First() as RequestTelemetry).Name);
            Assert.AreEqual("Span2", (sentItems.Skip(1).First() as DependencyTelemetry).Name);
        }
        public async Task HostTests_RestartsLibraryIfStoppedUnexpectedly()
        {
            // ARRANGE
            var telemetryClient = Common.SetupStubTelemetryClient(out var sentItems);

            int portAI = Common.GetPort();
            int portOC = Common.GetPort();

            var config = $@"<?xml version=""1.0"" encoding=""utf-8"" ?>
<LocalForwarderConfiguration>
  <Inputs>
    <ApplicationInsightsInput Enabled=""true"">
      <Host>0.0.0.0</Host>
      <Port>{portAI}</Port>
    </ApplicationInsightsInput>
    <OpenCensusInput Enabled=""true"">
      <Host>0.0.0.0</Host>
      <Port>{portOC}</Port>
    </OpenCensusInput>
  </Inputs>
  <OpenCensusToApplicationInsights>
    <InstrumentationKey>ikey1</InstrumentationKey>
  </OpenCensusToApplicationInsights>
  <ApplicationInsights>
    <LiveMetricsStreamInstrumentationKey>ikey1</LiveMetricsStreamInstrumentationKey>
  </ApplicationInsights>
</LocalForwarderConfiguration>
";

            Host host = new Host(telemetryClient);

            host.Run(config, TimeSpan.FromSeconds(1));

            FieldInfo libraryFieldInfo = host.GetType().GetField("library", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

            Common.AssertIsTrueEventually(() => libraryFieldInfo.GetValue(host) != null);

            // ACT
            // stop the existing library (as if something went wrong)
            var library = libraryFieldInfo.GetValue(host) as Library;

            library.Stop();

            Common.AssertIsTrueEventually(() => !library.IsRunning);

            // ASSERT
            // wait for a new library
            Common.AssertIsTrueEventually(() => libraryFieldInfo.GetValue(host) != null);

            // verify the new library works
            var telemetryBatch = new ExportSpanRequest();

            telemetryBatch.Spans.Add(new Span()
            {
                Name = new TruncatableString()
                {
                    Value = "Span1"
                }, Kind = Span.Types.SpanKind.Server
            });
            telemetryBatch.Spans.Add(new Span()
            {
                Name = new TruncatableString()
                {
                    Value = "Span2"
                }, Kind = Span.Types.SpanKind.Client
            });

            var writer = new GrpcWriter(false, portOC);
            await writer.Write(telemetryBatch).ConfigureAwait(false);

            Common.AssertIsTrueEventually(() => sentItems.Count == 2);

            Assert.AreEqual("Span1", (sentItems.Skip(0).First() as RequestTelemetry).Name);
            Assert.AreEqual("Span2", (sentItems.Skip(1).First() as DependencyTelemetry).Name);
        }