示例#1
0
        private static IAppBuilder UseTraceActuatorComponents(this IAppBuilder builder, IConfiguration config, ITraceRepository traceRepository, ILoggerFactory loggerFactory)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }

            ITraceOptions options = new TraceEndpointOptions(config);

            var mgmtOptions = ManagementOptions.Get(config);

            foreach (var mgmt in mgmtOptions)
            {
                mgmt.EndpointOptions.Add(options);
            }

            traceRepository = traceRepository ?? new TraceDiagnosticObserver(options, loggerFactory?.CreateLogger <TraceDiagnosticObserver>());
            DiagnosticsManager.Instance.Observers.Add((IDiagnosticObserver)traceRepository);
            var endpoint = new TraceEndpoint(options, traceRepository, loggerFactory?.CreateLogger <TraceEndpoint>());
            var logger   = loggerFactory?.CreateLogger <TraceEndpointOwinMiddleware>();

            return(builder.Use <TraceEndpointOwinMiddleware>(endpoint, mgmtOptions, logger));
        }
示例#2
0
        public void MakeTrace_ReturnsExpected()
        {
            var option = new TraceEndpointOptions();

            var obs      = new TraceDiagnosticObserver(option);
            var context  = CreateRequest();
            var duration = TimeSpan.FromTicks(20000000 - 10000000);
            var result   = obs.MakeTrace(context, duration);

            Assert.NotNull(result);
            Assert.NotNull(result.Info);
            Assert.NotEqual(0, result.TimeStamp);
            Assert.True(result.Info.ContainsKey("method"));
            Assert.True(result.Info.ContainsKey("path"));
            Assert.True(result.Info.ContainsKey("headers"));
            Assert.True(result.Info.ContainsKey("timeTaken"));
            Assert.Equal("GET", result.Info["method"]);
            Assert.Equal("/myPath", result.Info["path"]);
            var headers = result.Info["headers"] as Dictionary <string, object>;

            Assert.NotNull(headers);
            Assert.True(headers.ContainsKey("request"));
            Assert.True(headers.ContainsKey("response"));
            var timeTaken = result.Info["timeTaken"] as string;

            Assert.NotNull(timeTaken);
            var expected = duration.TotalMilliseconds.ToString();

            Assert.Equal(expected, timeTaken);
        }
示例#3
0
        public void ProcessEvent_IgnoresUnprocessableEvents()
        {
            var option = new TraceEndpointOptions();

            var obs = new TraceDiagnosticObserver(option);

            // No current activity, event ignored
            obs.ProcessEvent("foobar", null);

            var current = new Activity("barfoo");

            current.Start();

            // Activity current, but no value provided, event ignored
            obs.ProcessEvent("foobar", null);

            // Activity current, value provided, event not stop event, event is ignored
            obs.ProcessEvent("foobar", new object());

            // Activity current, event is stop event, no context in event value, event it ignored
            obs.ProcessEvent("Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop", new object());

            Assert.Empty(obs._queue);
            current.Stop();
        }
        /// <summary>
        /// Adds the services used by the Trace actuator
        /// </summary>
        /// <param name="services">Reference to the service collection</param>
        /// <param name="configuration">Reference to the configuration system</param>
        /// <param name="version">The media version to use</param>
        /// <returns>A reference to the service collection</returns>
        public static IServiceCollection AddTraceActuatorServices(this IServiceCollection services, IConfiguration configuration, MediaTypeVersion version)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            switch (version)
            {
            case MediaTypeVersion.V1:
                var options = new TraceEndpointOptions(configuration);
                services.TryAddSingleton <ITraceOptions>(options);
                services.TryAddSingleton <TraceEndpoint>();
                services.TryAddEnumerable(ServiceDescriptor.Singleton(typeof(IEndpointOptions), options));
                break;

            default:
                var options2 = new HttpTraceEndpointOptions(configuration);
                services.TryAddSingleton <ITraceOptions>(options2);
                services.TryAddEnumerable(ServiceDescriptor.Singleton(typeof(IEndpointOptions), options2));
                break;
            }

            return(services);
        }
        public void RoutesByPathAndVerbTrace()
        {
            var options = new TraceEndpointOptions();

            Assert.True(options.ExactMatch);
            Assert.Equal("/actuator/trace", options.GetContextPath(new ActuatorManagementOptions()));
            Assert.Equal("/cloudfoundryapplication/trace", options.GetContextPath(new CloudFoundryManagementOptions()));
            Assert.Null(options.AllowedVerbs);
        }
示例#6
0
        public void GetProperty_NoProperties_ReturnsExpected()
        {
            var option = new TraceEndpointOptions();

            var obs = new TraceDiagnosticObserver(option);

            obs.GetProperty(new { foo = "bar" }, out var context);
            Assert.Null(context);
        }
示例#7
0
        public void GetRemoteAddress_NoConnection_ReturnsExpected()
        {
            var option = new TraceEndpointOptions();

            var obs     = new TraceDiagnosticObserver(option);
            var context = CreateRequest();
            var result  = obs.GetRemoteAddress(context);

            Assert.Null(result);
        }
示例#8
0
        public void GetProperty_WithProperties_ReturnsExpected()
        {
            var option = new TraceEndpointOptions();

            var obs             = new TraceDiagnosticObserver(option);
            var expectedContext = CreateRequest();

            obs.GetProperty(new { HttpContext = expectedContext }, out var context);
            Assert.True(object.ReferenceEquals(expectedContext, context));
        }
        public void GetSessionId_NoSession_ReturnsExpected()
        {
            var option = new TraceEndpointOptions();

            TraceDiagnosticObserver obs     = new TraceDiagnosticObserver(option);
            HttpContext             context = CreateRequest();
            var result = obs.GetSessionId(context);

            Assert.Null(result);
        }
示例#10
0
        public void GetUserPrincipal_NotAuthenticated_ReturnsExpected()
        {
            var option = new TraceEndpointOptions();

            var obs     = new TraceDiagnosticObserver(option);
            var context = CreateRequest();
            var result  = obs.GetUserPrincipal(context);

            Assert.Null(result);
        }
示例#11
0
        public void GetRequestUri_ReturnsExpected()
        {
            var option = new TraceEndpointOptions();

            var obs     = new TraceDiagnosticObserver(option);
            var context = CreateRequest();
            var result  = obs.GetRequestUri(context.Request);

            Assert.Equal("http://localhost:1111/myPath", result);
        }
示例#12
0
        public void GetPathInfo_ReturnsExpected()
        {
            var option = new TraceEndpointOptions();

            var obs     = new TraceDiagnosticObserver(option);
            var context = CreateRequest();

            var result = obs.GetPathInfo(context.Request);

            Assert.Equal("/myPath", result);
        }
示例#13
0
        private static void UseTraceActuatorComponents(IConfiguration configuration, ITraceRepository traceRepository, ILoggerFactory loggerFactory)
        {
            var options = new TraceEndpointOptions(configuration);

            _mgmtOptions.RegisterEndpointOptions(configuration, options);
            traceRepository = traceRepository ?? new TraceDiagnosticObserver(options, CreateLogger <TraceDiagnosticObserver>(loggerFactory));
            DiagnosticsManager.Instance.Observers.Add((IDiagnosticObserver)traceRepository);
            var ep      = new TraceEndpoint(options, traceRepository, CreateLogger <TraceEndpoint>(loggerFactory));
            var handler = new TraceHandler(ep, SecurityServices, _mgmtOptions, CreateLogger <TraceHandler>(loggerFactory));

            ConfiguredHandlers.Add(handler);
        }
        public void TraceEndpointMiddleware_PathAndVerbMatching_ReturnsExpected()
        {
            var opts  = new TraceEndpointOptions();
            var mopts = TestHelpers.GetManagementOptions(opts);
            TraceDiagnosticObserver obs = new TraceDiagnosticObserver(opts);
            var ep     = new TraceEndpoint(opts, obs);
            var middle = new TraceEndpointMiddleware(null, ep, mopts);

            Assert.True(middle.RequestVerbAndPathMatch("GET", "/cloudfoundryapplication/trace"));
            Assert.False(middle.RequestVerbAndPathMatch("PUT", "/cloudfoundryapplication/trace"));
            Assert.False(middle.RequestVerbAndPathMatch("GET", "/cloudfoundryapplication/badpath"));
        }
示例#15
0
        public void GetUserPrincipal_Authenticated_ReturnsExpected()
        {
            var option = new TraceEndpointOptions();

            var obs     = new TraceDiagnosticObserver(option);
            var context = CreateRequest();

            context.User = new ClaimsPrincipal(new MyIdentity());
            var result = obs.GetUserPrincipal(context);

            Assert.Equal("MyTestName", result);
        }
示例#16
0
        public void GetTimeTaken_ReturnsExpected()
        {
            var option = new TraceEndpointOptions();

            var obs      = new TraceDiagnosticObserver(option);
            var context  = CreateRequest();
            var time     = TimeSpan.FromTicks(10000000);
            var result   = obs.GetTimeTaken(time);
            var expected = time.TotalMilliseconds.ToString();

            Assert.Equal(expected, result);
        }
示例#17
0
        public void Contstructor_BindsConfigurationCorrectly()
        {
            var appsettings = new Dictionary <string, string>()
            {
                ["management:endpoints:enabled"]                           = "false",
                ["management:endpoints:path"]                              = "/cloudfoundryapplication",
                ["management:endpoints:loggers:enabled"]                   = "false",
                ["management:endpoints:trace:enabled"]                     = "true",
                ["management:endpoints:trace:capacity"]                    = "1000",
                ["management:endpoints:trace:addTimeTaken"]                = "false",
                ["management:endpoints:trace:addRequestHeaders"]           = "false",
                ["management:endpoints:trace:addResponseHeaders"]          = "false",
                ["management:endpoints:trace:addPathInfo"]                 = "true",
                ["management:endpoints:trace:addUserPrincipal"]            = "true",
                ["management:endpoints:trace:addParameters"]               = "true",
                ["management:endpoints:trace:addQueryString"]              = "true",
                ["management:endpoints:trace:addAuthType"]                 = "true",
                ["management:endpoints:trace:addRemoteAddress"]            = "true",
                ["management:endpoints:trace:addSessionId"]                = "true",
                ["management:endpoints:cloudfoundry:validatecertificates"] = "true",
                ["management:endpoints:cloudfoundry:enabled"]              = "true"
            };
            ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();

            configurationBuilder.AddInMemoryCollection(appsettings);
            var config = configurationBuilder.Build();

            var opts      = new TraceEndpointOptions(config);
            var cloudOpts = new CloudFoundryEndpointOptions(config);

            Assert.True(cloudOpts.Enabled);
            Assert.Equal(string.Empty, cloudOpts.Id);
            Assert.Equal(string.Empty, cloudOpts.Path);
            Assert.True(cloudOpts.ValidateCertificates);

            Assert.True(opts.Enabled);
            Assert.Equal("trace", opts.Id);
            Assert.Equal("trace", opts.Path);
            Assert.Equal(1000, opts.Capacity);
            Assert.False(opts.AddTimeTaken);
            Assert.False(opts.AddRequestHeaders);
            Assert.False(opts.AddResponseHeaders);
            Assert.True(opts.AddPathInfo);
            Assert.True(opts.AddUserPrincipal);
            Assert.True(opts.AddParameters);
            Assert.True(opts.AddQueryString);
            Assert.True(opts.AddAuthType);
            Assert.True(opts.AddRemoteAddress);
            Assert.True(opts.AddSessionId);
        }
示例#18
0
        public async void TraceInvoke_ReturnsExpected()
        {
            // arrange
            var opts        = new TraceEndpointOptions();
            var mgmtOptions = TestHelpers.GetManagementOptions(opts);
            var ep          = new TestTraceEndpoint(opts, new TraceDiagnosticObserver(opts));
            var middle      = new EndpointOwinMiddleware <List <TraceResult> >(null, ep, mgmtOptions);
            var context     = OwinTestHelpers.CreateRequest("GET", "/cloudfoundryapplication/trace");

            // act
            var json = await middle.InvokeAndReadResponse(context);

            // assert
            Assert.Equal("[]", json);
        }
        public async void HandleTraceRequestAsync_OtherPathReturnsExpected()
        {
            var opts  = new TraceEndpointOptions();
            var mopts = TestHelpers.GetManagementOptions(opts);

            TraceDiagnosticObserver obs = new TraceDiagnosticObserver(opts);
            var ep      = new TestTraceEndpoint(opts, obs);
            var middle  = new TraceEndpointMiddleware(null, ep, mopts);
            var context = CreateRequest("GET", "/cloudfoundryapplication/trace");
            await middle.HandleTraceRequestAsync(context);

            context.Response.Body.Seek(0, SeekOrigin.Begin);
            StreamReader rdr  = new StreamReader(context.Response.Body);
            string       json = await rdr.ReadToEndAsync();

            Assert.Equal("[]", json);
        }
示例#20
0
        public void ProcessEvent_HonorsCapacity()
        {
            var option = new TraceEndpointOptions();

            var obs     = new TraceDiagnosticObserver(option);
            var current = new Activity("Microsoft.AspNetCore.Hosting.HttpRequestIn");

            current.Start();

            for (var i = 0; i < 200; i++)
            {
                var context = CreateRequest();
                obs.ProcessEvent("Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop", new { HttpContext = context });
            }

            Assert.Equal(option.Capacity, obs._queue.Count);
        }
示例#21
0
        public void Constructor_InitializesWithDefaults()
        {
            var opts = new TraceEndpointOptions();

            Assert.Null(opts.Enabled);
            Assert.Equal("trace", opts.Id);
            Assert.Equal(100, opts.Capacity);
            Assert.True(opts.AddTimeTaken);
            Assert.True(opts.AddRequestHeaders);
            Assert.True(opts.AddResponseHeaders);
            Assert.False(opts.AddPathInfo);
            Assert.False(opts.AddUserPrincipal);
            Assert.False(opts.AddParameters);
            Assert.False(opts.AddQueryString);
            Assert.False(opts.AddAuthType);
            Assert.False(opts.AddRemoteAddress);
            Assert.False(opts.AddSessionId);
        }
示例#22
0
        public async Task HandleTraceRequestAsync_ReturnsExpected()
        {
            var opts  = new TraceEndpointOptions();
            var mopts = new CloudFoundryManagementOptions();

            mopts.EndpointOptions.Add(opts);

            var obs     = new TraceDiagnosticObserver(opts);
            var ep      = new TestTraceEndpoint(opts, obs);
            var middle  = new TraceEndpointMiddleware(null, ep, mopts);
            var context = CreateRequest("GET", "/cloudfoundryapplication/httptrace");
            await middle.HandleTraceRequestAsync(context);

            context.Response.Body.Seek(0, SeekOrigin.Begin);
            var rdr  = new StreamReader(context.Response.Body);
            var json = await rdr.ReadToEndAsync();

            Assert.Equal("[]", json);
        }
示例#23
0
        public void GetSessionId_WithSession_ReturnsExpected()
        {
            var option = new TraceEndpointOptions();

            var obs     = new TraceDiagnosticObserver(option);
            var context = CreateRequest();

            var             session     = new TestSession();
            ISessionFeature sessFeature = new SessionFeature
            {
                Session = session
            };

            context.Features.Set <ISessionFeature>(sessFeature);

            var result = obs.GetSessionId(context);

            Assert.Equal("TestSessionId", result);
        }
        private static void RegisterTraceActuatorComponents(this ContainerBuilder container, IConfiguration config)
        {
            container.Register(c =>
            {
                var options     = new TraceEndpointOptions(config);
                var mgmtOptions = c.Resolve <IEnumerable <IManagementOptions> >();
                foreach (var mgmt in mgmtOptions)
                {
                    mgmt.EndpointOptions.Add(options);
                }
                return(options);
            }).As <ITraceOptions>().IfNotRegistered(typeof(ITraceOptions)).SingleInstance();

            container.RegisterType <TraceDiagnosticObserver>().As <IDiagnosticObserver>().As <ITraceRepository>().SingleInstance();
            container.RegisterType <DiagnosticsManager>().As <IDiagnosticsManager>().IfNotRegistered(typeof(IDiagnosticsManager)).SingleInstance();

            container.RegisterType <TraceEndpoint>().As <IEndpoint <List <TraceResult> > >().SingleInstance();
            container.RegisterType <EndpointOwinMiddleware <List <TraceResult> > >().SingleInstance();
        }
        public void Subscribe_Listener_StopActivity_AddsToQueue()
        {
            DiagnosticListener listener = new DiagnosticListener("Microsoft.AspNetCore");
            var option = new TraceEndpointOptions();

            TraceDiagnosticObserver obs = new TraceDiagnosticObserver(option);

            obs.Subscribe(listener);

            var      context      = CreateRequest();
            string   activityName = "Microsoft.AspNetCore.Hosting.HttpRequestIn";
            Activity current      = new Activity(activityName);

            listener.StartActivity(current, new { HttpContext = context });

            Thread.Sleep(1000);

            listener.StopActivity(current, new { HttpContext = context });

            Assert.Single(obs._queue);

            Assert.True(obs._queue.TryPeek(out TraceResult result));
            Assert.NotNull(result.Info);
            Assert.NotEqual(0, result.TimeStamp);
            Assert.True(result.Info.ContainsKey("method"));
            Assert.True(result.Info.ContainsKey("path"));
            Assert.True(result.Info.ContainsKey("headers"));
            Assert.True(result.Info.ContainsKey("timeTaken"));
            Assert.Equal("GET", result.Info["method"]);
            Assert.Equal("/myPath", result.Info["path"]);
            var headers = result.Info["headers"] as Dictionary <string, object>;

            Assert.NotNull(headers);
            Assert.True(headers.ContainsKey("request"));
            Assert.True(headers.ContainsKey("response"));
            var timeTaken = result.Info["timeTaken"] as string;

            Assert.NotNull(timeTaken);
            Assert.StartsWith("10", timeTaken);

            obs.Dispose();
            listener.Dispose();
        }
示例#26
0
        public void GetRequestParameters_ReturnsExpected()
        {
            var option = new TraceEndpointOptions();

            var obs     = new TraceDiagnosticObserver(option);
            var context = CreateRequest();
            var result  = obs.GetRequestParameters(context.Request);

            Assert.NotNull(result);
            Assert.True(result.ContainsKey("foo"));
            Assert.True(result.ContainsKey("bar"));
            var fooVal = result["foo"];

            Assert.Single(fooVal);
            Assert.Equal("bar", fooVal[0]);
            var barVal = result["bar"];

            Assert.Single(barVal);
            Assert.Equal("foo", barVal[0]);
        }
示例#27
0
        public void GetHeaders_ReturnsExpected()
        {
            var option = new TraceEndpointOptions();

            var obs     = new TraceDiagnosticObserver(option);
            var context = CreateRequest();

            var result = obs.GetHeaders(100, context.Request.Headers);

            Assert.NotNull(result);
            Assert.True(result.ContainsKey("header1"));
            Assert.True(result.ContainsKey("header2"));
            Assert.True(result.ContainsKey("status"));
            var header1Val = result["header1"] as string;

            Assert.Equal("header1Value", header1Val);
            var header2Val = result["header2"] as string;

            Assert.Equal("header2Value", header2Val);
            var statusVal = result["status"] as string;

            Assert.Equal("100", statusVal);
        }
示例#28
0
        public void ProcessEvent_AddsToQueue()
        {
            var option = new TraceEndpointOptions();

            var obs = new TraceDiagnosticObserver(option);

            var current = new Activity("Microsoft.AspNetCore.Hosting.HttpRequestIn");

            current.Start();

            var context = CreateRequest();

            obs.ProcessEvent("Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop", new { HttpContext = context });

            Assert.Single(obs._queue);

            Assert.True(obs._queue.TryPeek(out var result));
            Assert.NotNull(result.Info);
            Assert.NotEqual(0, result.TimeStamp);
            Assert.True(result.Info.ContainsKey("method"));
            Assert.True(result.Info.ContainsKey("path"));
            Assert.True(result.Info.ContainsKey("headers"));
            Assert.True(result.Info.ContainsKey("timeTaken"));
            Assert.Equal("GET", result.Info["method"]);
            Assert.Equal("/myPath", result.Info["path"]);
            var headers = result.Info["headers"] as Dictionary <string, object>;

            Assert.NotNull(headers);
            Assert.True(headers.ContainsKey("request"));
            Assert.True(headers.ContainsKey("response"));
            var timeTaken = result.Info["timeTaken"] as string;

            Assert.NotNull(timeTaken);
            Assert.Equal("0", timeTaken); // 0 because activity not stopped

            current.Stop();
        }
示例#29
0
        public void GetTraces_ReturnsTraces()
        {
            var listener = new DiagnosticListener("test");
            var option   = new TraceEndpointOptions();

            var obs     = new TraceDiagnosticObserver(option);
            var current = new Activity("Microsoft.AspNetCore.Hosting.HttpRequestIn");

            current.Start();

            for (var i = 0; i < 200; i++)
            {
                var context = CreateRequest();
                obs.ProcessEvent("Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop", new { HttpContext = context });
            }

            Assert.Equal(option.Capacity, obs._queue.Count);
            var traces = obs.GetTraces();

            Assert.Equal(option.Capacity, traces.Count);
            Assert.Equal(option.Capacity, obs._queue.Count);

            listener.Dispose();
        }