示例#1
0
        public void MeterProvider_SetDefaultTwice_Throws()
        {
            var meterProvider = Sdk.CreateMeterProviderBuilder().Build();

            MeterProvider.SetDefault(meterProvider);
            Assert.Throws <InvalidOperationException>(() => MeterProvider.SetDefault(meterProvider));
        }
        /// <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);
        }
示例#3
0
        /// <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);
        }
示例#4
0
        public void MeterProvider_SetDefault()
        {
            var meterProvider = Sdk.CreateMeterProviderBuilder().Build();

            MeterProvider.SetDefault(meterProvider);

            var defaultMeter = MeterProvider.Default.GetMeter(string.Empty);

            Assert.NotNull(defaultMeter);
            Assert.IsType <MeterSdk>(defaultMeter);

            Assert.NotSame(defaultMeter, MeterProvider.Default.GetMeter("named meter"));

            var counter = defaultMeter.CreateDoubleCounter("ctr");

            Assert.IsType <DoubleCounterMetricSdk>(counter);
        }
        public void MeterProvider_UpdateDefault_CachedTracer()
        {
            var defaultMeter = MeterProvider.Default.GetMeter(string.Empty);
            var noOpCounter  = defaultMeter.CreateDoubleCounter("ctr");

            Assert.IsType <NoOpCounterMetric <double> >(noOpCounter);

            MeterProvider.SetDefault(Sdk.CreateMeterProvider(b => { }));
            var counter = defaultMeter.CreateDoubleCounter("ctr");

            Assert.IsType <DoubleCounterMetricSdk>(counter);

            var newdefaultMeter = MeterProvider.Default.GetMeter(string.Empty);

            Assert.NotSame(defaultMeter, newdefaultMeter);
            Assert.IsType <MeterSdk>(newdefaultMeter);
        }
示例#6
0
        internal static async Task <object> RunAsync(int port, int pushIntervalInSecs, int totalDurationInMins)
        {
            System.Console.WriteLine($"OpenTelemetry Prometheus Exporter is making metrics available at http://localhost:{port}/metrics/");

            /*
             * Following is sample prometheus.yml config. Adjust port,interval as needed.
             *
             * scrape_configs:
             # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
             # - job_name: 'OpenTelemetryTest'
             #
             # metrics_path defaults to '/metrics'
             # scheme defaults to 'http'.
             #
             #  static_configs:
             #  - targets: ['localhost:9184']
             */

            // Create and Setup Prometheus Exporter
            var promOptions = new PrometheusExporterOptions()
            {
                Url = $"http://localhost:{port}/metrics/"
            };
            var promExporter      = new PrometheusExporter(promOptions);
            var metricsHttpServer = new PrometheusExporterMetricsHttpServer(promExporter);

            metricsHttpServer.Start();

            // Create Processor (called Batcher in Metric spec, this is still not decided)
            var processor = new UngroupedBatcher();

            // Application which decides to enable OpenTelemetry metrics
            // would setup a MeterProvider and make it default.
            // All meters from this factory will be configured with the common processing pipeline.
            MeterProvider.SetDefault(Sdk.CreateMeterProviderBuilder()
                                     .SetProcessor(processor)
                                     .SetExporter(promExporter)
                                     .SetPushInterval(TimeSpan.FromSeconds(pushIntervalInSecs))
                                     .Build());

            // The following shows how libraries would obtain a MeterProvider.
            // MeterProvider is the entry point, which provides Meter.
            // If user did not set the Default MeterProvider (shown in earlier lines),
            // all metric operations become no-ops.
            var meterProvider = MeterProvider.Default;
            var meter         = meterProvider.GetMeter("MyMeter");

            // the rest is purely from Metrics API.
            var testCounter  = meter.CreateInt64Counter("MyCounter");
            var testMeasure  = meter.CreateInt64Measure("MyMeasure");
            var testObserver = meter.CreateInt64Observer("MyObservation", CallBackForMyObservation);
            var labels1      = new List <KeyValuePair <string, string> >();

            labels1.Add(new KeyValuePair <string, string>("dim1", "value1"));

            var labels2 = new List <KeyValuePair <string, string> >();

            labels2.Add(new KeyValuePair <string, string>("dim1", "value2"));
            var defaultContext = default(SpanContext);

            Stopwatch sw = Stopwatch.StartNew();

            while (sw.Elapsed.TotalMinutes < totalDurationInMins)
            {
                testCounter.Add(defaultContext, 100, meter.GetLabelSet(labels1));

                testMeasure.Record(defaultContext, 100, meter.GetLabelSet(labels1));
                testMeasure.Record(defaultContext, 500, meter.GetLabelSet(labels1));
                testMeasure.Record(defaultContext, 5, meter.GetLabelSet(labels1));
                testMeasure.Record(defaultContext, 750, meter.GetLabelSet(labels1));

                // Obviously there is no testObserver.Oberve() here, as Observer instruments
                // have callbacks that are called by the Meter automatically at each collection interval.

                await Task.Delay(1000);

                var remaining = (totalDurationInMins * 60) - sw.Elapsed.TotalSeconds;
                System.Console.WriteLine("Running and emitting metrics. Remaining time:" + (int)remaining + " seconds");
            }

            // Stopping
            metricsHttpServer.Stop();
            System.Console.WriteLine("Metrics server shutdown.");
            System.Console.WriteLine("Press Enter key to exit.");
            return(null);
        }
示例#7
0
 public void MeterProvider_SetDefaultNull()
 {
     Assert.Throws <ArgumentNullException>(() => MeterProvider.SetDefault(null));
 }
 public void MeterProvider_SetDefaultTwice_Throws()
 {
     MeterProvider.SetDefault(Sdk.CreateMeterProvider(b => { }));
     Assert.Throws <InvalidOperationException>(() => MeterProvider.SetDefault(Sdk.CreateMeterProvider(b => { })));
 }
示例#9
0
        static async Task Main(string[] args)
        {
            var config                  = new ConfigurationBuilder().AddEnvironmentVariables().Build();
            var exporterEndpoint        = config.GetValue <string>("MeterExporterEndpoint", "http://localhost:9184/metrics/");
            var exporterHostingEndpoint = config.GetValue <string>("MeterExporterHostingEndpoint", "http://localhost:9184/metrics/");
            var tracerEndpoint          = config.GetValue <string>("TracerExporterEndpoint", "http://localhost:9411/api/v2/spans");

            // MetricsServer for Prometheus pull model
            var exporter = new PrometheusExporter(new PrometheusExporterOptions()
            {
                Url = exporterEndpoint
            });
            var metricsServer = new PrometheusExporterMetricsHttpServerCustom(exporter, exporterHostingEndpoint);

            metricsServer.Start();
            Console.WriteLine($"Started Metrics Server on {exporterEndpoint}");

            /*
             * Following is sample prometheus.yml config. Adjust port,interval as needed.
             * scrape_configs:
             # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
             # - job_name: 'OpenTelemetryTest'
             # metrics_path defaults to '/metrics'
             # scheme defaults to 'http'.
             #  static_configs:
             #  - targets: ['localhost:9184']
             */

            // Metrics (factory is cacheable)
            var processor   = new UngroupedBatcher();
            var spanContext = default(SpanContext);

            MeterProvider.SetDefault(Sdk.CreateMeterProviderBuilder()
                                     .SetProcessor(processor)
                                     .SetExporter(exporter)
                                     .SetPushInterval(TimeSpan.FromSeconds(10))
                                     .Build());
            var meterProvider = MeterProvider.Default;
            var meter         = meterProvider.GetMeter("Sample");
            var counter       = meter.CreateInt64Counter("sample/measure/initialize");

            var labels1 = new List <KeyValuePair <string, string> >();

            labels1.Add(new KeyValuePair <string, string>("dim1", "value1"));

            var labels2 = new List <KeyValuePair <string, string> >();

            labels2.Add(new KeyValuePair <string, string>("dim2", "value2"));

            // TracerServer for Zipkin push model (in case you won't run on docker)
            // $ docker run --rm -p 9411:9411 openzipkin/zipkin
            // Tracer (factory is cacheable)
            using var tracerFactory = Sdk.CreateTracerProviderBuilder()
                                      .AddSource("Samples.SampleClient", "Samples.SampleServer")
                                      .AddZipkinExporter(o =>
            {
                o.ServiceName = "front-zipkin";
                o.Endpoint    = new Uri(tracerEndpoint);
            })
                                      .Build();
            using var backEndTracerFactory = Sdk.CreateTracerProviderBuilder()
                                             .AddSource("Samples.SampleServer.Redis", "Samples.SampleServer.Db")
                                             .AddZipkinExporter(o =>
            {
                o.ServiceName = "backend-zipkin";
                o.Endpoint    = new Uri(tracerEndpoint);
            })
                                             .Build();
            Console.WriteLine($"Started Tracer Server on {tracerEndpoint}");

            // Execute http://0.0.0.0:19999
            using var sample = new InstrumentationWithActivitySource();
            sample.Start();

            var sw = Stopwatch.StartNew();

            while (sw.Elapsed.TotalMinutes < 10)
            {
                // metrics
                counter.Add(spanContext, 100, meter.GetLabelSet(labels1));

                await Task.Delay(1000);

                var remaining = (10 * 60) - sw.Elapsed.TotalSeconds;
                Console.WriteLine("Running and emitting metrics. Remaining time:" + (int)remaining + " seconds");
            }

            metricsServer.Stop();
        }