/// <summary>
        /// Adds the needed services for Google Cloud Tracing. Used with <see cref="UseGoogleTrace"/>.
        /// </summary>
        /// <param name="services">The service collection. Cannot be null.</param>
        /// <param name="projectId">The Google Cloud Platform project ID. Cannot be null.</param>
        /// <param name="config">Optional trace configuration, if unset the default will be used.</param>
        /// <param name="client">Optional Trace client, if unset the default will be used.</param>
        /// <param name="traceOverridePredicate">Optional function to trace requests. If the trace header is not set
        ///     then this function will be called to determine if a given request should be traced.  This will
        ///     not override trace headers. If the function returns true the request will be traced, if false
        ///     is returned the trace will not be traced and if null is returned it will not affect the
        ///     trace decision.</param>
        public static void AddGoogleTrace(
            this IServiceCollection services, string projectId,
            TraceConfiguration config = null, TraceServiceClient client = null,
            Func <HttpRequest, bool?> traceOverridePredicate = null)
        {
            GaxPreconditions.CheckNotNull(services, nameof(services));
            GaxPreconditions.CheckNotNull(projectId, nameof(projectId));

            client = client ?? TraceServiceClient.Create();
            config = config ?? TraceConfiguration.Create();

            var traceIdFactory = TraceIdFactory.Create();

            var consumer = ConsumerFactory <TraceProto> .GetConsumer(
                new GrpcTraceConsumer(client), MessageSizer <TraceProto> .GetSize, config.BufferOptions);

            var tracerFactory = new ManagedTracerFactory(projectId, consumer,
                                                         RateLimitingTraceOptionsFactory.Create(config), traceIdFactory);

            services.AddSingleton <IManagedTracerFactory>(tracerFactory);
            services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();
            services.AddSingleton(CreateTraceHeaderPropagatingHandler);
            services.AddSingleton(new ShouldTraceRequest(traceOverridePredicate));
            services.AddSingleton(traceIdFactory);

            services.AddScoped(CreateTraceHeaderContext);
            services.AddScoped(CreateManagedTracer);
        }
示例#2
0
        public async Task Trace_Header()
        {
            string traceId = TraceIdFactory.Create().NextId();
            ulong  spanId  = SpanIdFactory.Create().NextId();

            string testId    = Utils.GetTestId();
            var    startTime = Timestamp.FromDateTime(DateTime.UtcNow);
            var    builder   = new WebHostBuilder().UseStartup <TraceTestNoBufferLowQpsApplication>();

            using (var server = new TestServer(builder))
            {
                var client = server.CreateClient();

                var header = TraceHeaderContext.Create(traceId, spanId, shouldTrace: true);
                client.DefaultRequestHeaders.Add(TraceHeaderContext.TraceHeader, header.ToString());
                await client.GetAsync($"/Trace/Trace/{testId}");
            }

            var spanName = TraceController.GetMessage(nameof(TraceController.Trace), testId);
            var trace    = _polling.GetTrace(spanName, startTime);

            Assert.NotNull(trace);
            Assert.Equal(traceId, trace.TraceId);
            Assert.Equal(2, trace.Spans.Count);
            var span = trace.Spans.First(s => s.Name.StartsWith("/Trace"));

            Assert.Equal(spanId, span.ParentSpanId);
        }
示例#3
0
        public async Task Trace_Header()
        {
            string traceId = TraceIdFactory.Create().NextId();
            ulong  spanId  = SpanIdFactory.Create().NextId();

            string testId    = Utils.GetTestId();
            var    startTime = Timestamp.FromDateTime(DateTime.UtcNow);

            var client = _noBufferLowQps.CreateClient();

            var header = TraceHeaderContext.Create(traceId, spanId, shouldTrace: true);

            client.DefaultRequestHeaders.Add(TraceHeaderContext.TraceHeader, header.ToString());
            var response = await client.GetAsync($"/Trace/Trace/{testId}");

            var spanName = TraceController.GetMessage(nameof(TraceController.Trace), testId);
            var trace    = _polling.GetTrace(spanName, startTime);

            Assert.NotNull(trace);
            Assert.Equal(traceId, trace.TraceId);
            Assert.Equal(2, trace.Spans.Count);
            var span = trace.Spans.First(s => s.Name.StartsWith("/Trace"));

            Assert.Equal(spanId, span.ParentSpanId);

            Assert.True(response.Headers.Contains(TraceHeaderContext.TraceHeader));
            var returnedHeader = response.Headers.GetValues(TraceHeaderContext.TraceHeader).Single();
            var headerContext  = TraceHeaderContext.FromHeader(returnedHeader);

            Assert.Equal(traceId, headerContext.TraceId);
            Assert.Equal(spanId, headerContext.SpanId);
            Assert.True(headerContext.ShouldTrace);
        }
示例#4
0
        private IServiceProvider CreateProviderForTraceHeaderContext(string traceHeader)
        {
            var context = new DefaultHttpContext();
            var request = context.Request;

            request.Headers[TraceHeaderContext.TraceHeader] = traceHeader;

            var accessor = new HttpContextAccessor {
                HttpContext = context
            };

            var traceIdFactory = TraceIdFactory.Create();

            Mock <IServiceProvider> mockProvider = new Mock <IServiceProvider>();

            mockProvider.Setup(p => p.GetService(typeof(IHttpContextAccessor))).Returns(accessor);
            mockProvider.Setup(p => p.GetService(typeof(TraceDecisionPredicate))).Returns(
                TraceDecisionPredicate.Default);
            mockProvider.Setup(p => p.GetService(typeof(TraceIdFactory))).Returns(traceIdFactory);
            return(mockProvider.Object);
        }
示例#5
0
        /// <summary>
        /// Create an <see cref="IServiceProvider"/> to be used during tests of
        /// <see cref="CloudTraceExtension.CreateTraceHeaderContext(IServiceProvider)"/>.
        /// It will set up an <see cref="IHttpContextAccessor"/> with the passed in trace header,
        /// a <see cref="ShouldTraceRequest"/> with the passed in should trace function and a
        /// <see cref="TraceIdFactory"/>.
        /// </summary>
        private IServiceProvider CreateProviderForTraceHeaderContext(
            string traceHeader, Func <HttpRequest, bool?> shouldTraceFunc = null)
        {
            var context = new DefaultHttpContext();
            var request = new DefaultHttpRequest(context);

            request.Headers[TraceHeaderContext.TraceHeader] = traceHeader;

            var accessor = new HttpContextAccessor();

            accessor.HttpContext = context;

            var traceIdFactory = TraceIdFactory.Create();

            Mock <IServiceProvider> mockProvider = new Mock <IServiceProvider>();

            mockProvider.Setup(p => p.GetService(typeof(IHttpContextAccessor))).Returns(accessor);
            mockProvider.Setup(p => p.GetService(typeof(ShouldTraceRequest))).Returns(
                new ShouldTraceRequest(shouldTraceFunc));
            mockProvider.Setup(p => p.GetService(typeof(TraceIdFactory))).Returns(traceIdFactory);
            return(mockProvider.Object);
        }
        public async Task Traces_CustomTraceContext()
        {
            var uri     = $"/TraceSamples/{nameof(TraceSamplesController.TraceHelloWorld)}/{_testId}";
            var traceId = TraceIdFactory.Create().NextId();

            using var server = GetTestServer <CustomTraceContextTestApplication.Startup>();
            using var client = server.CreateClient();
            var request = new HttpRequestMessage(HttpMethod.Get, uri)
            {
                Headers = { { "custom_trace_id", traceId } }
            };
            var response = await client.SendAsync(request);

            var trace = s_polling.GetTrace(uri, _startTime);

            TraceEntryVerifiers.AssertParentChildSpan(trace, uri, _testId);
            TraceEntryVerifiers.AssertSpanLabelsContains(
                trace.Spans.First(s => s.Name == uri), TraceEntryData.HttpGetSuccessLabels);
            Assert.False(response.Headers.Contains(TraceHeaderContext.TraceHeader));

            Assert.Equal(traceId, trace.TraceId);
            Assert.True(response.Headers.Contains("custom_trace_id"));
        }
 private static ITraceContext GetTraceContextFromIncomingRequest() =>
 new SimpleTraceContext(TraceIdFactory.Create().NextId(), null, true);
        /// <summary>
        /// Adds the needed services for Google Cloud Tracing. Used with <see cref="UseGoogleTrace"/>.
        /// </summary>
        /// <param name="services">The service collection. Cannot be null.</param>
        /// <param name="projectId">The Google Cloud Platform project ID. Cannot be null.</param>
        /// <param name="config">Optional trace configuration, if unset the default will be used.</param>
        /// <param name="clientTask">Optional task which produces the Trace client, if
        ///     unset the default will be used.</param>
        public static void AddGoogleTrace(
            this IServiceCollection services, string projectId,
            TraceConfiguration config = null, Task <TraceServiceClient> clientTask = null)
        {
            GaxPreconditions.CheckNotNull(services, nameof(services));
            GaxPreconditions.CheckNotNull(projectId, nameof(projectId));

            clientTask = clientTask ?? TraceServiceClient.CreateAsync();
            config     = config ?? TraceConfiguration.Create();

            IConsumer <TraceProto> consumer = ConsumerFactory <TraceProto> .GetConsumer(
                new GrpcTraceConsumer(clientTask), MessageSizer <TraceProto> .GetSize, config.BufferOptions);

            var tracerFactory = new ManagedTracerFactory(projectId, consumer,
                                                         RateLimitingTraceOptionsFactory.Create(config), TraceIdFactory.Create());

            services.AddSingleton <IManagedTracerFactory>(tracerFactory);
            services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();

            services.AddScoped(CreateTraceHeaderContext);
            services.AddScoped(CreateManagedTracer);
        }
        /// <summary>
        /// Adds the needed services for Google Cloud Tracing. Used with <see cref="UseGoogleTrace"/>.
        /// </summary>
        /// <param name="services">The service collection. Cannot be null.</param>
        /// /// <param name="setupAction">Action to set up options. Cannot be null.</param>
        public static void AddGoogleTrace(
            this IServiceCollection services, Action <TraceServiceOptions> setupAction)
        {
            GaxPreconditions.CheckNotNull(services, nameof(services));
            GaxPreconditions.CheckNotNull(setupAction, nameof(setupAction));

            var serviceOptions = new TraceServiceOptions();

            setupAction(serviceOptions);

            var client  = serviceOptions.Client ?? TraceServiceClient.Create();
            var options = serviceOptions.Options ?? TraceOptions.Create();
            var traceFallbackPredicate = serviceOptions.TraceFallbackPredicate ?? TraceDecisionPredicate.Default;
            var projectId = CommonUtils.GetAndCheckProjectId(serviceOptions.ProjectId);

            var consumer = ConsumerFactory <TraceProto> .GetConsumer(
                new GrpcTraceConsumer(client), MessageSizer <TraceProto> .GetSize,
                options.BufferOptions, options.RetryOptions);

            var tracerFactory = new ManagedTracerFactory(projectId, consumer,
                                                         RateLimitingTraceOptionsFactory.Create(options), TraceIdFactory.Create());

            services.AddScoped(CreateTraceHeaderContext);

            services.AddSingleton <IManagedTracerFactory>(tracerFactory);
            services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();

            services.AddSingleton(CreateManagedTracer);
            services.AddSingleton(CreateTraceHeaderPropagatingHandler);
            services.AddSingleton(traceFallbackPredicate);
        }
        /// <summary>
        /// Adds the needed services for Google Cloud Tracing. Used with <see cref="UseGoogleTrace"/>.
        /// </summary>
        /// <param name="services">The service collection. Cannot be null.</param>
        /// <param name="projectId">Optional if running on Google App Engine or Google Compute Engine.
        ///     The Google Cloud Platform project ID. If unspecified and running on GAE or GCE the project ID will be
        ///     detected from the platform.</param>
        /// <param name="config">Optional trace configuration, if unset the default will be used.</param>
        /// <param name="client">Optional Trace client, if unset the default will be used.</param>
        /// <param name="traceFallbackPredicate">Optional function to trace requests. If the trace header is not set
        ///     then this function will be called to determine if a given request should be traced.  This will
        ///     not override trace headers.</param>
        public static void AddGoogleTrace(
            this IServiceCollection services, string projectId = null,
            TraceConfiguration config = null, TraceServiceClient client = null,
            TraceDecisionPredicate traceFallbackPredicate = null)
        {
            GaxPreconditions.CheckNotNull(services, nameof(services));

            client = client ?? TraceServiceClient.Create();
            config = config ?? TraceConfiguration.Create();
            traceFallbackPredicate = traceFallbackPredicate ?? TraceDecisionPredicate.Default;

            projectId = CommonUtils.GetAndCheckProjectId(projectId);

            var consumer = ConsumerFactory <TraceProto> .GetConsumer(
                new GrpcTraceConsumer(client), MessageSizer <TraceProto> .GetSize, config.BufferOptions);

            var tracerFactory = new ManagedTracerFactory(projectId, consumer,
                                                         RateLimitingTraceOptionsFactory.Create(config), TraceIdFactory.Create());

            services.AddScoped(CreateTraceHeaderContext);

            services.AddSingleton <IManagedTracerFactory>(tracerFactory);
            services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();

            services.AddSingleton(CreateManagedTracer);
            services.AddSingleton(CreateTraceHeaderPropagatingHandler);
            services.AddSingleton(traceFallbackPredicate);
        }