/// <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>
        /// <remarks>
        /// If <see cref="RetryOptions.ExceptionHandling"/> is set to <see cref="ExceptionHandling.Propagate"/>
        /// and the <see cref="RequestDelegate"/> executed by this middleware throws ad exception and this
        /// diagnostics library also throws an exception trying to report it and <see cref="AggregateException"/>
        /// with both exceptions will be thrown.  Otherwise only the exception from the <see cref="RequestDelegate"/>
        /// will be thrown.
        /// </remarks>
        public static IServiceCollection 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 = Project.GetAndCheckProjectId(serviceOptions.ProjectId);

            var consumer      = ManagedTracer.CreateConsumer(client, options);
            var tracerFactory = ManagedTracer.CreateTracerFactory(projectId, consumer, options);

            services.AddScoped(CreateTraceHeaderContext);

            services.AddSingleton(tracerFactory);

            // Only add the HttpContextAccessor if it's not already added.
            // This is needed to get the `TraceHeaderContext`. See `CreateTraceHeaderContext`.
            services.TryAddSingleton <IHttpContextAccessor, HttpContextAccessor>();

            services.AddSingleton(ManagedTracer.CreateDelegatingTracer(() => ContextTracerManager.GetCurrentTracer()));
            services.AddSingleton(new TraceHeaderPropagatingHandler(() => ContextTracerManager.GetCurrentTracer()));
            return(services.AddSingleton(traceFallbackPredicate));
        }
        /// <summary>
        /// Adds the needed services for Google Cloud Tracing. Used with <see cref="UseGoogleTrace"/>.
        /// </summary>
        /// <param name="services">The service collection. Must not be null.</param>
        /// <param name="setupAction">Action to set up options. Must not be null.</param>
        /// <remarks>
        /// If <see cref="RetryOptions.ExceptionHandling"/> is set to <see cref="ExceptionHandling.Propagate"/>
        /// and the <see cref="RequestDelegate"/> executed by this middleware throws ad exception and this
        /// diagnostics library also throws an exception trying to report it and <see cref="AggregateException"/>
        /// with both exceptions will be thrown.  Otherwise only the exception from the <see cref="RequestDelegate"/>
        /// will be thrown.
        /// </remarks>
        public static IServiceCollection 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 = Project.GetAndCheckProjectId(serviceOptions.ProjectId);

            var consumer      = ManagedTracer.CreateConsumer(client, options);
            var tracerFactory = ManagedTracer.CreateTracerFactory(projectId, consumer, options);

            services.AddScoped(CreateTraceHeaderContext);
            services.AddSingleton(tracerFactory);
            services.AddHttpContextAccessor();
            services.AddSingleton(ManagedTracer.CreateDelegatingTracer(ContextTracerManager.GetCurrentTracer));

            // On .Net Standard 2.0 or higher, we can use the System.Net.Http.IHttpClientFactory defined in Microsoft.Extensions.Http,
            // for which we need a DelagatingHandler with no InnerHandler set. This is the recommended way.
            // It should be registered as follows.
            services.AddTransient(sp => new UnchainedTraceHeaderPropagatingHandler(ContextTracerManager.GetCurrentTracer));
            // This is to be used for explicitly creating an HttpClient instance. Valid for all platforms.
            services.AddSingleton(new TraceHeaderPropagatingHandler(ContextTracerManager.GetCurrentTracer));

            return(services.AddSingleton(traceFallbackPredicate));
        }
Example #3
0
        /// <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>
        /// <remarks>
        /// If <see cref="RetryOptions.ExceptionHandling"/> is set to <see cref="ExceptionHandling.Propagate"/>
        /// and the <see cref="RequestDelegate"/> executed by this middleware throws ad exception and this
        /// diagnostics library also throws an exception trying to report it and <see cref="AggregateException"/>
        /// with both exceptions will be thrown.  Otherwise only the exception from the <see cref="RequestDelegate"/>
        /// will be thrown.
        /// </remarks>
        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 = Project.GetAndCheckProjectId(serviceOptions.ProjectId);

            var consumer      = ManagedTracer.CreateConsumer(client, options);
            var tracerFactory = ManagedTracer.CreateTracerFactory(projectId, consumer, options);

            services.AddScoped(CreateTraceHeaderContext);

            services.AddSingleton <Func <TraceHeaderContext, IManagedTracer> >(tracerFactory);
            services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();

            services.AddSingleton(CreateManagedTracer);
            services.AddSingleton(CreateTraceHeaderPropagatingHandler);
            services.AddSingleton(traceFallbackPredicate);
        }
Example #4
0
        private CloudTrace(string projectId, TraceOptions options        = null, TraceServiceClient client = null,
                           TraceDecisionPredicate traceFallbackPredicate = null)
        {
            GaxPreconditions.CheckNotNull(projectId, nameof(projectId));

            // Create the default values if not set.
            client  = client ?? TraceServiceClient.Create();
            options = options ?? TraceOptions.Create();
            _traceFallbackPredicate = traceFallbackPredicate ?? TraceDecisionPredicate.Default;

            _consumer      = ManagedTracer.CreateConsumer(client, options);
            _tracerFactory = ManagedTracer.CreateTracerFactory(projectId, _consumer, options);
        }
Example #5
0
        public void CreateDelegatingTracer()
        {
            var    mockTracer = new Mock <IManagedTracer>();
            string traceId    = Guid.NewGuid().ToString("N");

            mockTracer.Setup(p => p.GetCurrentTraceId()).Returns(traceId);

            var tracer = ManagedTracer.CreateDelegatingTracer(() => mockTracer.Object);

            Assert.IsType <DelegatingTracer>(tracer);
            Assert.Equal(traceId, tracer.GetCurrentTraceId());
            mockTracer.Verify();
        }
Example #6
0
        /// <summary>
        /// Creates a singleton <see cref="IManagedTracer"/> that is a <see cref="DelegatingTracer"/>.
        /// The <see cref="DelegatingTracer"/> will use an <see cref="IHttpContextAccessor"/> under the hood
        /// to get the current tracer which is set by the <see cref="ContextTracerManager"/>.
        /// </summary>
        internal static IManagedTracer CreateManagedTracer(IServiceProvider provider)
        {
            var accessor = provider.GetServiceCheckNotNull <IHttpContextAccessor>();

            return(ManagedTracer.CreateDelegatingTracer(() => ContextTracerManager.GetCurrentTracer(accessor)));
        }