public async Task <string> CompleteDiagnosticObserverTest()
        {
            Tracer.Instance = GetTracer();

            var builder = new WebHostBuilder()
                          .UseStartup <Startup>();

            var testServer = new TestServer(builder);
            var client     = testServer.CreateClient();
            var observers  = new List <DiagnosticObserver> {
                new AspNetCoreDiagnosticObserver()
            };
            string retValue = null;

            using (var diagnosticManager = new DiagnosticManager(observers))
            {
                diagnosticManager.Start();
                DiagnosticManager.Instance = diagnosticManager;
                retValue = await client.GetStringAsync("/Home");

                try
                {
                    await client.GetStringAsync("/Home/error");
                }
                catch { }
                DiagnosticManager.Instance = null;
            }

            return(retValue);
        }
示例#2
0
        /// <summary>
        /// Паттерн "Заместитель" представляет суррогатный объект, управляющий доступом к другому объекту.
        /// Отличие "Заместителя" от "Декоратора" в том, что первый управляет доступом, а второй расширяет поведение объекта.
        ///
        /// Клиентский объект работает так, словно он вызывает методы удаленного объекта. Но в действительности он вызывает
        /// методы объекта-заместителя, существующего в локальной куче, который берет на себя все низкоуровневые подробности сетевых взаимодействий.
        ///
        /// Виды паттерна:
        /// - удаленный заместитель (управляет взаимодействием клиента с удаленным объектом);
        /// - виртуальный заместитель (управляет доступом к объекту, создание которого сопряжено с большими затратами);
        /// - защитный заместитель (управляет доступом к методам объекта в зависимости от привилегий вызывающей стороны);
        /// - фильтрующий заместитель (управляет доступом к группам сетевых ресурсов, защищая их от "недобросовестных" клиентов);
        /// - умная ссылка (обеспечивает выполнение дополнительных действий при обращении к объекту (например изменение ссылок счетчика));
        /// - кэширующий заместитель (обеспечивает временное хранение результатов высокозатратных операций.
        /// Также может обеспечивать совместный доступ к результатам для предотвращения лишних вычислений или пересылки данных по сети);
        /// - синхронизирующий заместитель (предоставляет безопасный доступ к объекту из нескольких программных потоков);
        /// - упрощающий заместитель (скрывает сложность и управляет доступом к сложному набору классов. Иногда по очевидным соображениям называется фасадным заместителем.
        /// Упрощающий заместитель отличается от паттерна "Фасад" тем, что первый управляет доступом, а второй только предоставляет альтернативный интерфейс);
        /// - заместитель отложенного копирования (задерживает фактическое копирование объекта до момента выполнения операции с копией (разновидность виртуального заместителя)).
        /// </summary>
        public void DemoProxy()
        {
            // Пример применения паттерна "удаленный заместитель"
            IDiagnosticManager diagnosticManager = new DiagnosticManager();

            diagnosticManager.GetSummary("localhost");
        }
示例#3
0
        internal void StartDiagnosticObserversInternal()
        {
            DiagnosticManager?.Stop();

            var observers = new List <DiagnosticObserver>();

#if NETSTANDARD
            if (Settings.IsIntegrationEnabled(AspNetCoreDiagnosticObserver.IntegrationName))
            {
                Log.Debug("Adding AspNetCoreDiagnosticObserver");

                var aspNetCoreDiagnosticOptions = new AspNetCoreDiagnosticOptions();
                observers.Add(new AspNetCoreDiagnosticObserver(this, aspNetCoreDiagnosticOptions));
            }
#endif

            if (observers.Count == 0)
            {
                Log.Debug("DiagnosticManager not started, zero observers added.");
            }
            else
            {
                Log.Debug("Starting DiagnosticManager with {0} observers.", observers.Count);

                var diagnosticManager = new DiagnosticManager(observers);
                diagnosticManager.Start();
                DiagnosticManager = diagnosticManager;
            }
        }
        public HttpHandlerDiagnosticTest(ITestOutputHelper output)
        {
            _tracer  = new MockTracer();
            _options = new HttpHandlerDiagnosticOptions();

            IServiceProvider serviceProvider = new ServiceCollection()
                                               .AddLogging(logging =>
            {
                logging.AddXunit(output);
            })
                                               .AddOpenTracingCoreServices(builder =>
            {
                builder.AddCoreFx();
                builder.Services.AddSingleton <ITracer>(_tracer);
                builder.Services.AddSingleton(Options.Create(_options));
            })
                                               .BuildServiceProvider();

            _diagnosticsManager = serviceProvider.GetRequiredService <DiagnosticManager>();
            _diagnosticsManager.Start();

            // Inner handler for mocking the result
            _httpHandler = new MockHttpMessageHandler();

            // Wrap with DiagnosticsHandler (which is internal :( )
            Type               type               = typeof(HttpClientHandler).Assembly.GetType("System.Net.Http.DiagnosticsHandler");
            ConstructorInfo    constructor        = type.GetConstructors(BindingFlags.Instance | BindingFlags.Public)[0];
            HttpMessageHandler diagnosticsHandler = (HttpMessageHandler)constructor.Invoke(new object[] { _httpHandler });

            _httpClient = new HttpClient(diagnosticsHandler);
        }
        public void EmptyDiagnosticManagerConfigurationIsEmptyByDefault()
        {
            var configuration = new EmptyDiagnosticManagerConfiguration();
            Assert.IsNotNull(configuration);

            var diagnosticManager = new DiagnosticManager(configuration);
            Assert.IsNotNull(diagnosticManager);

            Assert.IsTrue(!diagnosticManager.Providers.Any());
        }
        private static void StartDiagnosticManager()
        {
            var observers = new List <DiagnosticObserver> {
                new AspNetCoreDiagnosticObserver()
            };
            var diagnosticManager = new DiagnosticManager(observers);

            diagnosticManager.Start();

            DiagnosticManager.Instance = diagnosticManager;
        }
        public void EmptyDiagnosticManagerConfigurationReturnsEmptyDiagnosticReport()
        {
            var configuration = new EmptyDiagnosticManagerConfiguration();
            Assert.IsNotNull(configuration);

            var diagnosticManager = new DiagnosticManager(configuration);
            Assert.IsNotNull(diagnosticManager);

            Assert.IsTrue(!diagnosticManager.Providers.Any());

            var diagnosticReport = diagnosticManager.GetReports();
            Assert.IsNotNull(diagnosticReport);
            Assert.IsTrue(!diagnosticReport.Reports.Any());
        }
示例#8
0
        public HostingTest(ITestOutputHelper output)
        {
            _tracer = new MockTracer();

            var aspNetCoreOptions = new AspNetCoreDiagnosticOptions();

            _options = aspNetCoreOptions.Hosting;

            _serviceProvider = new ServiceCollection()
                               .AddLogging(logging =>
            {
                logging.AddXunit(output);
                logging.AddFilter("OpenTracing", LogLevel.Trace);
            })
                               .AddOpenTracingCoreServices(builder =>
            {
                builder.AddAspNetCore();

                builder.Services.AddSingleton <ITracer>(_tracer);
                builder.Services.AddSingleton(Options.Create(aspNetCoreOptions));
            })
                               .BuildServiceProvider();

            _diagnosticManager = _serviceProvider.GetRequiredService <DiagnosticManager>();
            _diagnosticManager.Start();

            // Request

            _httpContext = new DefaultHttpContext();
            SetRequest();

            // Hosting Application

            var diagnosticSource = new DiagnosticListener("Microsoft.AspNetCore");

            _features = new FeatureCollection();
            _features.Set <IHttpRequestFeature>(new HttpRequestFeature());

            var httpContextFactory = Substitute.For <IHttpContextFactory>();

            httpContextFactory.Create(_features).Returns(_httpContext);

            _hostingApplication = new HostingApplication(
                ctx => Task.FromResult(0),
                _serviceProvider.GetRequiredService <ILogger <HostingTest> >(),
                diagnosticSource,
                httpContextFactory);
        }
示例#9
0
        public void Start_if_valid_Tracer()
        {
            var loggerFactory         = new NullLoggerFactory();
            var tracer                = new MockTracer();
            var diagnosticSubscribers = new List <DiagnosticObserver>();
            var options               = Options.Create(new DiagnosticManagerOptions());

            using (DiagnosticManager diagnosticManager = new DiagnosticManager(loggerFactory, tracer, diagnosticSubscribers, options))
            {
                Assert.False(diagnosticManager.IsRunning);

                diagnosticManager.Start();

                Assert.True(diagnosticManager.IsRunning);
            }
        }
示例#10
0
        public void Does_not_Start_if_Tracer_is_GlobalTracer_with_NoopTracer()
        {
            var loggerFactory         = new NullLoggerFactory();
            var tracer                = GlobalTracer.Instance;
            var diagnosticSubscribers = new List <DiagnosticObserver>();
            var options               = Options.Create(new DiagnosticManagerOptions());

            using (DiagnosticManager diagnosticManager = new DiagnosticManager(loggerFactory, tracer, diagnosticSubscribers, options))
            {
                Assert.False(diagnosticManager.IsRunning);

                diagnosticManager.Start();

                Assert.False(diagnosticManager.IsRunning);
            }
        }
示例#11
0
        private static void StartDiagnosticManager()
        {
            var observers = new List <DiagnosticObserver>();

            if (!PlatformHelpers.AzureAppServices.Metadata.IsFunctionsApp)
            {
                // Not adding the `AspNetCoreDiagnosticObserver` is particularly important for Azure Functions.
                // The AspNetCoreDiagnosticObserver will be loaded in a separate Assembly Load Context, breaking the connection of AsyncLocal
                // This is because user code is loaded within the functions host in a separate context
                observers.Add(new AspNetCoreDiagnosticObserver());
            }

            var diagnosticManager = new DiagnosticManager(observers);

            diagnosticManager.Start();
            DiagnosticManager.Instance = diagnosticManager;
        }
示例#12
0
 public InstrumentationService(DiagnosticManager diagnosticManager)
 {
     _diagnosticManager = diagnosticManager ??
                          throw new ArgumentNullException(nameof(diagnosticManager));
 }
        private static async Task AssertDiagnosticObserverSubmitsSpans <T>(
            string path,
            HttpStatusCode statusCode,
            bool isError,
            string resourceName,
            SerializableDictionary expectedParentSpanTags,
            bool featureFlag = false,
            int spanCount    = 1,
            string childSpan1ResourceName              = null,
            SerializableDictionary firstChildSpanTags  = null,
            string childSpan2ResourceName              = null,
            SerializableDictionary secondChildSpanTags = null)
            where T : class
        {
            var writer       = new AgentWriterStub();
            var configSource = new NameValueConfigurationSource(new NameValueCollection
            {
                { ConfigurationKeys.FeatureFlags.RouteTemplateResourceNamesEnabled, featureFlag.ToString() },
            });
            var tracer = GetTracer(writer, configSource);

            var builder = new WebHostBuilder()
                          .UseStartup <T>();

            var testServer = new TestServer(builder);
            var client     = testServer.CreateClient();
            var observers  = new List <DiagnosticObserver> {
                new AspNetCoreDiagnosticObserver(tracer)
            };

            using (var diagnosticManager = new DiagnosticManager(observers))
            {
                diagnosticManager.Start();
                try
                {
                    var response = await client.GetAsync(path);

                    Assert.Equal(statusCode, response.StatusCode);
                }
                catch (Exception ex)
                {
                    Assert.True(isError, $"Unexpected error calling endpoint: {ex}");
                }

                // The diagnostic observer runs on a separate thread
                // This gives time for the Stop event to run and to be flushed to the writer
                const int timeoutInMilliseconds = 10000;

                var deadline = DateTime.Now.AddMilliseconds(timeoutInMilliseconds);
                while (DateTime.Now < deadline)
                {
                    if (writer.Traces.Count > 0)
                    {
                        break;
                    }

                    Thread.Sleep(200);
                }
            }

            var trace = Assert.Single(writer.Traces);

            trace.Should().HaveCount(spanCount);

            var parentSpan = trace.Should()
                             .ContainSingle(x => x.OperationName == "aspnet_core.request")
                             .Subject;

            AssertTagHasValue(parentSpan, Tags.InstrumentationName, "aspnet_core");
            parentSpan.Type.Should().Be(SpanTypes.Web);
            parentSpan.ResourceName.Should().Be(resourceName);
            AssertTagHasValue(parentSpan, Tags.SpanKind, SpanKinds.Server);
            AssertTagHasValue(parentSpan, Tags.Language, TracerConstants.Language);
            AssertTagHasValue(parentSpan, Tags.HttpStatusCode, ((int)statusCode).ToString());
            parentSpan.Error.Should().Be(isError);

            if (expectedParentSpanTags is not null)
            {
                foreach (var expectedTag in expectedParentSpanTags.Values)
                {
                    AssertTagHasValue(parentSpan, expectedTag.Key, expectedTag.Value);
                }
            }

            if (spanCount > 1)
            {
                trace.Should().Contain(x => x.OperationName == "aspnet_core_mvc.request");

                var childSpan = trace.First(x => x.OperationName == "aspnet_core_mvc.request");

                AssertTagHasValue(childSpan, Tags.InstrumentationName, "aspnet_core");
                childSpan.Type.Should().Be(SpanTypes.Web);
                childSpan.ResourceName.Should().Be(childSpan1ResourceName ?? resourceName);
                AssertTagHasValue(childSpan, Tags.SpanKind, SpanKinds.Server);
                AssertTagHasValue(childSpan, Tags.Language, TracerConstants.Language);

                if (firstChildSpanTags is not null)
                {
                    foreach (var expectedTag in firstChildSpanTags.Values)
                    {
                        AssertTagHasValue(childSpan, expectedTag.Key, expectedTag.Value);
                    }
                }

                if (spanCount > 2)
                {
                    var childSpan2 = trace.Last(x => x.OperationName == "aspnet_core_mvc.request");
                    childSpan2.Should().NotBe(childSpan);

                    AssertTagHasValue(childSpan2, Tags.InstrumentationName, "aspnet_core");
                    childSpan2.Type.Should().Be(SpanTypes.Web);
                    childSpan2.ResourceName.Should().Be(childSpan2ResourceName);
                    AssertTagHasValue(childSpan2, Tags.SpanKind, SpanKinds.Server);
                    AssertTagHasValue(childSpan2, Tags.Language, TracerConstants.Language);

                    if (secondChildSpanTags is not null)
                    {
                        foreach (var expectedTag in secondChildSpanTags.Values)
                        {
                            AssertTagHasValue(childSpan2, expectedTag.Key, expectedTag.Value);
                        }
                    }
                }
            }
        }
        public InstrumentationService(DiagnosticManager diagnosticManager)
        {
            _diagnosticsManager = diagnosticManager ?? throw new ArgumentNullException(nameof(diagnosticManager));

            Status = HostedServiceStatus.Created;
        }