public async Task IncomingRequestInstrumentationTest( bool instrument, bool filter = false, bool includeVersion = false, bool enrich = false, bool enrichmentExcecption = false) { List <Activity> stoppedActivities = new List <Activity>(); using ActivityListener activityListener = new ActivityListener { ShouldListenTo = activitySource => true, ActivityStopped = activity => stoppedActivities.Add(activity), }; ActivitySource.AddActivityListener(activityListener); TracerProvider tracerProvider = null; if (instrument) { tracerProvider = Sdk.CreateTracerProviderBuilder() .AddWcfInstrumentation(options => { if (enrich) { if (!enrichmentExcecption) { options.Enrich = (activity, eventName, message) => { switch (eventName) { case WcfEnrichEventNames.AfterReceiveRequest: activity.SetTag( "server.afterreceiverequest", WcfEnrichEventNames.AfterReceiveRequest); break; case WcfEnrichEventNames.BeforeSendReply: activity.SetTag( "server.beforesendreply", WcfEnrichEventNames.BeforeSendReply); break; } }; } else { options.Enrich = (activity, eventName, message) => { throw new Exception("Failure whilst enriching activity"); }; } } options.IncomingRequestFilter = (Message m) => { return(!filter); }; options.SetSoapMessageVersion = includeVersion; }) .Build(); } ServiceClient client = new ServiceClient( new NetTcpBinding(), new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); try { var response = await client.ExecuteAsync( new ServiceRequest { Payload = "Hello Open Telemetry!", }).ConfigureAwait(false); } finally { if (client.State == CommunicationState.Faulted) { client.Abort(); } else { client.Close(); } tracerProvider?.Shutdown(); tracerProvider?.Dispose(); WcfInstrumentationActivitySource.Options = null; } if (instrument && !filter) { Assert.NotEmpty(stoppedActivities); Assert.Single(stoppedActivities); Activity activity = stoppedActivities[0]; Assert.Equal(WcfInstrumentationActivitySource.IncomingRequestActivityName, activity.OperationName); Assert.Equal(WcfInstrumentationConstants.WcfSystemValue, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcSystemTag).Value); Assert.Equal("http://opentelemetry.io/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcServiceTag).Value); Assert.Equal("Execute", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); Assert.Equal(this.serviceBaseUri.Host, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetHostNameTag).Value); Assert.Equal(this.serviceBaseUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetHostPortTag).Value); Assert.Equal("net.tcp", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelSchemeTag).Value); Assert.Equal("/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelPathTag).Value); Assert.Equal("http://opentelemetry.io/Service/ExecuteResponse", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.SoapReplyActionTag).Value); if (includeVersion) { Assert.Equal("Soap12 (http://www.w3.org/2003/05/soap-envelope) Addressing10 (http://www.w3.org/2005/08/addressing)", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.SoapMessageVersionTag).Value); } if (enrich && !enrichmentExcecption) { Assert.Equal(WcfEnrichEventNames.AfterReceiveRequest, activity.TagObjects.Single(t => t.Key == "server.afterreceiverequest").Value); Assert.Equal(WcfEnrichEventNames.BeforeSendReply, activity.TagObjects.Single(t => t.Key == "server.beforesendreply").Value); } } else { Assert.Empty(stoppedActivities); } }
public async Task OutgoingRequestInstrumentationTest( bool instrument, bool filter = false, bool suppressDownstreamInstrumentation = true, bool includeVersion = false) { #if NETFRAMEWORK const string OutgoingHttpOperationName = "OpenTelemetry.HttpWebRequest.HttpRequestOut"; #else const string OutgoingHttpOperationName = "System.Net.Http.HttpRequestOut"; #endif List <Activity> stoppedActivities = new List <Activity>(); var builder = Sdk.CreateTracerProviderBuilder() .AddInMemoryExporter(stoppedActivities); if (instrument) { builder .AddWcfInstrumentation(options => { options.OutgoingRequestFilter = (Message m) => { return(!filter); }; options.SuppressDownstreamInstrumentation = suppressDownstreamInstrumentation; options.SetSoapMessageVersion = includeVersion; }) .AddHttpClientInstrumentation(); // <- Added to test SuppressDownstreamInstrumentation. } TracerProvider tracerProvider = builder.Build(); ServiceClient client = new ServiceClient( new BasicHttpBinding(BasicHttpSecurityMode.None), new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); try { client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); var response = await client.ExecuteAsync( new ServiceRequest { Payload = "Hello Open Telemetry!", }).ConfigureAwait(false); } finally { if (client.State == CommunicationState.Faulted) { client.Abort(); } else { client.Close(); } tracerProvider.Shutdown(); tracerProvider.Dispose(); WcfInstrumentationActivitySource.Options = null; } if (instrument) { if (!suppressDownstreamInstrumentation) { Assert.NotEmpty(stoppedActivities); if (filter) { Assert.Single(stoppedActivities); Assert.Equal(OutgoingHttpOperationName, stoppedActivities[0].OperationName); } else { Assert.Equal(2, stoppedActivities.Count); Assert.Equal(OutgoingHttpOperationName, stoppedActivities[0].OperationName); Assert.Equal(WcfInstrumentationActivitySource.OutgoingRequestActivityName, stoppedActivities[1].OperationName); } } else { if (!filter) { Assert.NotEmpty(stoppedActivities); Assert.Single(stoppedActivities); Activity activity = stoppedActivities[0]; Assert.Equal(WcfInstrumentationActivitySource.OutgoingRequestActivityName, activity.OperationName); Assert.Equal(WcfInstrumentationConstants.WcfSystemValue, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcSystemTag).Value); Assert.Equal("http://opentelemetry.io/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcServiceTag).Value); Assert.Equal("Execute", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); Assert.Equal(this.serviceBaseUri.Host, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetPeerNameTag).Value); Assert.Equal(this.serviceBaseUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetPeerPortTag).Value); Assert.Equal("http", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelSchemeTag).Value); Assert.Equal("/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelPathTag).Value); if (includeVersion) { Assert.Equal("Soap11 (http://schemas.xmlsoap.org/soap/envelope/) AddressingNone (http://schemas.microsoft.com/ws/2005/05/addressing/none)", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.SoapMessageVersionTag).Value); } } else { Assert.Empty(stoppedActivities); } } } else { Assert.Empty(stoppedActivities); } }
public void IncomingRequestOneWayOperationInstrumentationTest() { List <Activity> stoppedActivities = new List <Activity>(); using ActivityListener activityListener = new ActivityListener { ShouldListenTo = activitySource => true, ActivityStopped = activity => stoppedActivities.Add(activity), }; ActivitySource.AddActivityListener(activityListener); TracerProvider tracerProvider = Sdk.CreateTracerProviderBuilder() .AddWcfInstrumentation() .Build(); ServiceClient client = new ServiceClient( new NetTcpBinding(), new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); try { client.ExecuteWithOneWay(new ServiceRequest()); this.thrownExceptionsHandle.WaitOne(3000); } finally { if (client.State == CommunicationState.Faulted) { client.Abort(); } else { client.Close(); } tracerProvider?.Shutdown(); tracerProvider?.Dispose(); WcfInstrumentationActivitySource.Options = null; } // Assert Assert.Empty(this.thrownExceptions); Assert.NotEmpty(stoppedActivities); Assert.Single(stoppedActivities); Activity activity = stoppedActivities[0]; Assert.Equal("http://opentelemetry.io/Service/ExecuteWithOneWay", activity.DisplayName); Assert.Equal("ExecuteWithOneWay", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); Assert.DoesNotContain(activity.TagObjects, t => t.Key == WcfInstrumentationConstants.SoapReplyActionTag); Assert.Equal(WcfInstrumentationActivitySource.IncomingRequestActivityName, activity.OperationName); Assert.Equal(WcfInstrumentationConstants.WcfSystemValue, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcSystemTag).Value); Assert.Equal("http://opentelemetry.io/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcServiceTag).Value); Assert.Equal(this.serviceBaseUri.Host, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetHostNameTag).Value); Assert.Equal(this.serviceBaseUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetHostPortTag).Value); Assert.Equal("net.tcp", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelSchemeTag).Value); Assert.Equal("/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelPathTag).Value); }
public static async Task Main(string[] args) { // create the tracer to export the traces CreateTracerProvider(); // attach a listener to generate activities // the listener has callbacks to log at ActivityStart and ActivityEnd ActivitySource.AddActivityListener(GetBatchActivityListener()); // get the metrics api to generate Histograms IMetricsRoot metricsRoot = GetMetricsRoot(); Context context = null; // instrument first activity // sleep for 250ms and add test tag List <KeyValuePair <string, object> > batchAttribute = new List <KeyValuePair <string, object> > { new KeyValuePair <string, object>("batch", "1") }; var worker1 = new InstrumentedWorker("Test activity", ActivityKind.Server, null, batchAttribute, () => Thread.Sleep(250), ActivitySource); Activity firstActivity = worker1.DoWork(); if (firstActivity?.IsAllDataRequested == true) { firstActivity.SetTag("Test tag", "A value for a custom tag"); metricsRoot.Measure.Histogram.Update(SampleHistogram, Convert.ToInt64(firstActivity.Duration.Milliseconds)); context = new Context(firstActivity.Context); } // instrument second activity // sleep for 350 ms batchAttribute[0] = new KeyValuePair <string, object>("batch", "2"); var worker2 = new InstrumentedWorker("Another test activity", ActivityKind.Server, context, batchAttribute, () => Thread.Sleep(350), ActivitySource); Activity secondActivity = worker2.DoWork(); if (secondActivity?.IsAllDataRequested == true) { metricsRoot.Measure.Histogram.Update(SampleHistogram, Convert.ToInt64(secondActivity.Duration.Milliseconds)); context = new Context(secondActivity.Context); } // instrument third activity, keep it opened // sleep for 500 ms and add events batchAttribute[0] = new KeyValuePair <string, object>("batch", "3"); var worker3 = new InstrumentedWorker("Third test activity", ActivityKind.Internal, context, batchAttribute, () => Thread.Sleep(500), ActivitySource); Activity thirdActivity = worker3.StartWork(); if (thirdActivity?.IsAllDataRequested == true) { thirdActivity.AddEvent(new ActivityEvent("An event")); Thread.Sleep(500); thirdActivity.AddEvent(new ActivityEvent("An event 500ms later")); context = new Context(thirdActivity.Context); } // add event using current activity Activity.Current?.AddEvent(new ActivityEvent("An event added to the current activity")); // instrument fourth activity as a nested activity // sleep for 500 ms batchAttribute[0] = new KeyValuePair <string, object>("batch", "4"); var worker4 = new InstrumentedWorker("Nested activity", ActivityKind.Client, context, batchAttribute, () => Thread.Sleep(500), ActivitySource); Activity fourthActivity = worker4.DoWork(); if (fourthActivity?.IsAllDataRequested == true) { metricsRoot.Measure.Histogram.Update(SampleHistogram, Convert.ToInt64(fourthActivity.Duration.Milliseconds)); } // stop 3rd activity thirdActivity = worker3.StopWork(); if (thirdActivity != null) { metricsRoot.Measure.Histogram.Update(SampleHistogram, Convert.ToInt64(thirdActivity.Duration.Milliseconds)); } // export the metrics await Task.WhenAll(metricsRoot.ReportRunner.RunAllAsync()); tracerProvider.Shutdown(); }