/// <summary> /// Processes incoming trace config request and responds with always sample config. /// </summary> /// <param name="configRequest">Incoming config request.</param> /// <param name="callContext">Call context.</param> /// <returns>LocalForwarder trace config.</returns> private UpdatedLibraryConfig OnOcConfigReceived(CurrentLibraryConfig configRequest, ServerCallContext callContext) { TryGetOrUpdatePeerInfo(configRequest.Node, callContext, out var _); Diagnostics.LogTrace($"Got config request from {callContext.Peer} with {configRequest.Config?.SamplerCase}"); return(new UpdatedLibraryConfig { Config = DefaultOpencensusConfig }); }
public async Task GrpcOpenCensusInputTests_ReceivesConfigWithNode() { // ARRANGE int configsReceived = 0; CurrentLibraryConfig receivedConfigRequest = null; int port = GetPort(); var input = new GrpcOpenCensusInput("localhost", port); input.Start( (telemetryBatch, callContext) => { }, (configRequest, callContext) => { configsReceived++; receivedConfigRequest = configRequest; return(ConfigResponse); }); Assert.IsTrue(SpinWait.SpinUntil(() => input.IsRunning, GrpcOpenCensusInputTests.DefaultTimeout)); var grpcWriter = new GrpcWriter(false, port); // ACT CurrentLibraryConfig request = new CurrentLibraryConfig { Config = new TraceConfig { RateLimitingSampler = new RateLimitingSampler { Qps = 1 } }, Node = new Node { Identifier = new ProcessIdentifier { Pid = 2 } } }; await grpcWriter.Write(request).ConfigureAwait(false); // ASSERT Common.AssertIsTrueEventually( () => input.GetStats().ConfigsReceived == 1 && configsReceived == 1 && receivedConfigRequest.Node.Identifier.Pid == 2 && receivedConfigRequest.Config.RateLimitingSampler.Qps == 1, GrpcOpenCensusInputTests.DefaultTimeout); input.Stop(); Assert.IsTrue(SpinWait.SpinUntil(() => !input.IsRunning, GrpcOpenCensusInputTests.DefaultTimeout)); }
private async Task OnSendConfig(IAsyncStreamReader<CurrentLibraryConfig> requestStream, IServerStreamWriter<UpdatedLibraryConfig> responseStream, ServerCallContext context) { if (this.onConfigReceived == null) { return; } try { while (await requestStream.MoveNext(this.cts.Token).ConfigureAwait(false)) { CurrentLibraryConfig configRequest = requestStream.Current; try { var configResponse = this.onConfigReceived(configRequest, context); if (configRequest.Config == null || !configRequest.Config.Equals(configResponse.Config)) { await responseStream.WriteAsync(configResponse) .ConfigureAwait(false); } Interlocked.Increment(ref this.stats.ConfigsReceived); } catch (System.Exception e) { // unexpected exception occured while processing the config request Interlocked.Increment(ref this.stats.ConfigsFailed); Diagnostics.LogError(FormattableString.Invariant($"Unknown exception while processing a config request through the OpenCensus gRpc input. {e.ToString()}")); } } } catch (TaskCanceledException) { // we have been stopped } catch (System.Exception e) { // unexpected exception occured Diagnostics.LogError(FormattableString.Invariant($"Unknown exception while reading config from gRpc stream. {e.ToString()}")); this.Stop(); } }
public async Task Write(CurrentLibraryConfig config) { if (this.aiMode) { throw new InvalidOperationException("Incorrect mode"); } try { await this.openCensusConfigStreamingCall.RequestStream.WriteAsync(config).ConfigureAwait(false); } catch (System.Exception e) { throw new InvalidOperationException( FormattableString.Invariant($"Error sending a message via gRpc. {e.ToString()}")); } }
public async Task GrpcOpenCensusInputTests_HandlesExceptionsInConfigRequestsProcessingHandler() { // ARRANGE int port = GetPort(); var input = new GrpcOpenCensusInput("localhost", port); input.Start((exportSpanRequest, callContext) => { }, (cr, cc) => throw new InvalidOperationException()); Assert.IsTrue(SpinWait.SpinUntil(() => input.IsRunning, GrpcOpenCensusInputTests.DefaultTimeout)); var grpcWriter = new GrpcWriter(false, port); CurrentLibraryConfig configRequest = new CurrentLibraryConfig { Config = new TraceConfig { RateLimitingSampler = new RateLimitingSampler { Qps = 1 } } }; // ACT await grpcWriter.Write(configRequest).ConfigureAwait(false); // ASSERT // must have handled the exception by logging it // should still be able to process items Common.AssertIsTrueEventually( () => input.IsRunning && input.GetStats().ConfigsReceived == 0 && input.GetStats().ConfigsFailed == 1, GrpcOpenCensusInputTests.DefaultTimeout); await grpcWriter.Write(configRequest).ConfigureAwait(false); Common.AssertIsTrueEventually( () => input.IsRunning && input.GetStats().ConfigsReceived == 0 && input.GetStats().ConfigsFailed == 2, GrpcOpenCensusInputTests.DefaultTimeout); }
public async Task HostTests_RunsLibrary() { // 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> <LiveMetricsStreamAuthenticationApiKey></LiveMetricsStreamAuthenticationApiKey> <AdaptiveSampling Enabled=""false""> <MaxEventsPerSecond>%APPINSIGHTS_ADAPTIVESAMPLINGEVENTSLIMIT%</MaxEventsPerSecond> <!--Telemetry items other than events are counted together--> <MaxOtherItemsPerSecond>%APPINSIGHTS_ADAPTIVESAMPLINGNONEVENTSLIMIT%</MaxOtherItemsPerSecond> </AdaptiveSampling> </ApplicationInsights> </LocalForwarderConfiguration> "; // ACT Host host = new Host(telemetryClient); host.Run(config, TimeSpan.FromSeconds(5)); Thread.Sleep(TimeSpan.FromMilliseconds(250)); var telemetryBatch = new ExportTraceServiceRequest(); 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 }); telemetryBatch.Node = new Node { ServiceInfo = new ServiceInfo { Name = "tests" } }; var configRequest = new CurrentLibraryConfig { Config = new TraceConfig { RateLimitingSampler = new RateLimitingSampler { Qps = 1 } } }; var writer = new GrpcWriter(false, portOC); await writer.Write(telemetryBatch).ConfigureAwait(false); await writer.Write(configRequest).ConfigureAwait(false); Common.AssertIsTrueEventually(() => sentItems.Count == 3); // ASSERT Assert.AreEqual("tests", (sentItems.Skip(0).First() as EventTelemetry).Context.Cloud.RoleName); Assert.AreEqual("Span1", (sentItems.Skip(1).First() as RequestTelemetry).Name); Assert.AreEqual("Span2", (sentItems.Skip(2).First() as DependencyTelemetry).Name); }