public void BroadcastProcessor_ShutsDownAll() { var processor1 = new TestActivityProcessor(null, null); var processor2 = new TestActivityProcessor(null, null); var broadcastProcessor = new BroadcastActivityProcessor(new[] { processor1, processor2 }); broadcastProcessor.ShutdownAsync(default);
public void BroadcastProcessor_OneProcessorThrows() { bool start1Called = false; bool start2Called = false; bool end1Called = false; bool end2Called = false; var processor1 = new TestActivityProcessor( ss => { start1Called = true; Assert.False(start2Called); Assert.False(end1Called); Assert.False(end2Called); throw new Exception("Start exception"); }, se => { end1Called = true; Assert.True(start1Called); Assert.True(start2Called); Assert.False(end2Called); throw new Exception("End exception"); }); var processor2 = new TestActivityProcessor( ss => { start2Called = true; Assert.True(start1Called); Assert.False(end1Called); Assert.False(end2Called); }, se => { end2Called = true; Assert.True(start1Called); Assert.True(start2Called); Assert.True(end1Called); }); var broadcastProcessor = new BroadcastActivityProcessor(new[] { processor1, processor2 }); var activity = new Activity("somename"); broadcastProcessor.OnStart(activity); Assert.True(start1Called); Assert.True(start2Called); broadcastProcessor.OnEnd(activity); Assert.True(end1Called); Assert.True(end2Called); }
public void BroadcastProcessor_CallsAllProcessorSequentially() { bool start1Called = false; bool start2Called = false; bool end1Called = false; bool end2Called = false; var processor1 = new TestActivityProcessor( ss => { start1Called = true; Assert.False(start2Called); Assert.False(end1Called); Assert.False(end2Called); }, se => { end1Called = true; Assert.True(start1Called); Assert.True(start2Called); Assert.False(end2Called); }); var processor2 = new TestActivityProcessor( ss => { start2Called = true; Assert.True(start1Called); Assert.False(end1Called); Assert.False(end2Called); }, se => { end2Called = true; Assert.True(start1Called); Assert.True(start2Called); Assert.True(end1Called); }); var broadcastProcessor = new BroadcastActivityProcessor(new[] { processor1, processor2 }); var activity = new Activity("somename"); broadcastProcessor.OnStart(activity); Assert.True(start1Called); Assert.True(start2Called); broadcastProcessor.OnEnd(activity); Assert.True(end1Called); Assert.True(end2Called); }
/// <summary> /// Creates TracerProvider with the configuration provided. /// This sets up listeners for all configured ActivitySources and /// sends activities to the pipeline of Sampler, Processor and Exporter. /// </summary> /// <param name="configureTracerProviderBuilder">Action to configure TracerProviderBuilder.</param> /// <returns>TracerProvider instance, which must be disposed upon shutdown.</returns> public static TracerProvider CreateTracerProvider(Action <TracerProviderBuilder> configureTracerProviderBuilder) { var tracerProviderBuilder = new TracerProviderBuilder(); configureTracerProviderBuilder?.Invoke(tracerProviderBuilder); var tracerProviderSdk = new TracerProviderSdk(); Sampler sampler = tracerProviderBuilder.Sampler ?? new AlwaysOnSampler(); ActivityProcessor activityProcessor; if (tracerProviderBuilder.ProcessingPipelines == null || !tracerProviderBuilder.ProcessingPipelines.Any()) { // if there are no pipelines are configured, use noop processor activityProcessor = new NoopActivityProcessor(); } else if (tracerProviderBuilder.ProcessingPipelines.Count == 1) { // if there is only one pipeline - use it's outer processor as a // single processor on the tracerSdk. var processorFactory = tracerProviderBuilder.ProcessingPipelines[0]; activityProcessor = processorFactory.Build(); } else { // if there are more pipelines, use processor that will broadcast to all pipelines var processors = new ActivityProcessor[tracerProviderBuilder.ProcessingPipelines.Count]; for (int i = 0; i < tracerProviderBuilder.ProcessingPipelines.Count; i++) { processors[i] = tracerProviderBuilder.ProcessingPipelines[i].Build(); } activityProcessor = new BroadcastActivityProcessor(processors); } tracerProviderSdk.Resource = tracerProviderBuilder.Resource; var activitySource = new ActivitySourceAdapter(sampler, activityProcessor, tracerProviderSdk.Resource); if (tracerProviderBuilder.InstrumentationFactories != null) { foreach (var instrumentation in tracerProviderBuilder.InstrumentationFactories) { tracerProviderSdk.Instrumentations.Add(instrumentation.Factory(activitySource)); } } // This is what subscribes to Activities. // Think of this as the replacement for DiagnosticListener.AllListeners.Subscribe(onNext => diagnosticListener.Subscribe(..)); tracerProviderSdk.ActivityListener = new ActivityListener { // Callback when Activity is started. ActivityStarted = (activity) => { if (activity.IsAllDataRequested) { activity.SetResource(tracerProviderSdk.Resource); } activityProcessor.OnStart(activity); }, // Callback when Activity is stopped. ActivityStopped = activityProcessor.OnEnd, // Function which takes ActivitySource and returns true/false to indicate if it should be subscribed to // or not ShouldListenTo = (activitySource) => tracerProviderBuilder.ActivitySourceNames?.Contains(activitySource.Name.ToUpperInvariant()) ?? false, // The following parameter is not used now. GetRequestedDataUsingParentId = (ref ActivityCreationOptions <string> options) => ActivityDataRequest.AllData, // This delegate informs ActivitySource about sampling decision when the parent context is an ActivityContext. GetRequestedDataUsingContext = (ref ActivityCreationOptions <ActivityContext> options) => ComputeActivityDataRequest(options, sampler), }; ActivitySource.AddActivityListener(tracerProviderSdk.ActivityListener); tracerProviderSdk.ActivityProcessor = activityProcessor; return(tracerProviderSdk); }