예제 #1
0
        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);
        }
예제 #4
0
        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();
        }