/// <summary>add MagicOnion Telemetry.</summary>
        public static IMagicOnionServerBuilder AddOpenTelemetry(this IMagicOnionServerBuilder builder,
                                                                MagicOnionOpenTelemetryOptions options,
                                                                Action <MagicOnionOpenTelemetryOptions, MagicOnionOpenTelemetryMeterFactoryOption> configureMeterProvider,
                                                                Action <MagicOnionOpenTelemetryOptions, IServiceProvider, TracerProviderBuilder> configureTracerProvider)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            builder.Services.AddSingleton(options);

            // configure MeterFactory
            if (configureMeterProvider != null)
            {
                var meterFactoryOption = new MagicOnionOpenTelemetryMeterFactoryOption();
                configureMeterProvider(options, meterFactoryOption);

                MeterProvider.SetDefault(Sdk.CreateMeterProviderBuilder()
                                         .SetProcessor(meterFactoryOption.MetricProcessor)
                                         .SetExporter(meterFactoryOption.MetricExporter)
                                         .SetPushInterval(meterFactoryOption.MetricPushInterval)
                                         .Build());

                builder.Services.AddSingleton(meterFactoryOption.MetricExporter);
                if (meterFactoryOption.MeterLogger != null)
                {
                    builder.Services.AddSingleton <IMagicOnionLogger>(meterFactoryOption.MeterLogger.Invoke(MeterProvider.Default));
                }
            }

            // configure TracerFactory
            if (configureTracerProvider != null)
            {
                if (string.IsNullOrEmpty(options.MagicOnionActivityName))
                {
                    throw new NullReferenceException(nameof(options.MagicOnionActivityName));
                }

                builder.Services.AddOpenTelemetryTracing((provider, builder) =>
                {
                    // ActivitySourceName must match to TracerName.
                    builder.AddSource(options.MagicOnionActivityName);
                    configureTracerProvider?.Invoke(options, provider, builder);
                });

                // Avoid directly register ActivitySource to Singleton for easier identification.
                var activitySource            = new ActivitySource(options.MagicOnionActivityName);
                var magicOnionActivitySources = new MagicOnionActivitySources(activitySource);
                builder.Services.AddSingleton(magicOnionActivitySources);
            }

            return(builder);
        }
        /// <summary>add MagicOnion Telemetry.</summary>
        public static IServiceCollection AddMagicOnionOpenTelemetry(this IServiceCollection services,
                                                                    MagicOnionOpenTelemetryOptions options,
                                                                    Action <MagicOnionOpenTelemetryOptions, MagicOnionOpenTelemetryMeterFactoryOption> configureMeterProvider,
                                                                    Action <MagicOnionOpenTelemetryOptions, IServiceProvider, TracerProviderBuilder> configureTracerProvider)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            services.AddSingleton(options);

            // configure MeterFactory
            if (configureMeterProvider != null)
            {
                var meterFactoryOption = new MagicOnionOpenTelemetryMeterFactoryOption();
                configureMeterProvider(options, meterFactoryOption);

                MeterProvider.SetDefault(Sdk.CreateMeterProviderBuilder()
                                         .SetProcessor(meterFactoryOption.MetricProcessor)
                                         .SetExporter(meterFactoryOption.MetricExporter)
                                         .SetPushInterval(meterFactoryOption.MetricPushInterval)
                                         .Build());

                services.AddSingleton(meterFactoryOption.MetricExporter);
                services.AddSingleton(MeterProvider.Default);
            }

            // configure TracerFactory
            if (configureTracerProvider != null)
            {
                if (string.IsNullOrEmpty(options.ActivitySourceName))
                {
                    throw new NullReferenceException(nameof(options.ActivitySourceName));
                }

                var tracerFactory = services.AddOpenTelemetryTracerProvider((provider, builder) =>
                {
                    // ActivitySourceName must match to TracerName.
                    builder.AddSource(options.ActivitySourceName);
                    configureTracerProvider(options, provider, builder);
                });
                services.AddSingleton(tracerFactory);
                services.AddSingleton(new ActivitySource(options.ActivitySourceName));
            }

            return(services);
        }