Example #1
0
        private static void CollectMetrics(UngroupedBatcher simpleProcessor)
        {
            var meter       = MeterFactory.Create(simpleProcessor).GetMeter("library1") as MeterSdk;
            var testCounter = meter.CreateInt64Counter("testCounter");

            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);

            for (int i = 0; i < 1000; i++)
            {
                testCounter.Add(defaultContext, 100, meter.GetLabelSet(labels1));
                testCounter.Add(defaultContext, 10, meter.GetLabelSet(labels1));
                testCounter.Add(defaultContext, 200, meter.GetLabelSet(labels2));
                testCounter.Add(defaultContext, 10, meter.GetLabelSet(labels2));

                if (i % 10 == 0)
                {
                    meter.Collect();
                }
            }
        }
Example #2
0
        public async Task E2ETestMetricsHttpServerAsync()
        {
            var promOptions = new PrometheusExporterOptions()
            {
                Url = "http://localhost:9184/metrics/"
            };
            var promExporter    = new PrometheusExporter(promOptions);
            var simpleProcessor = new UngroupedBatcher();

            var metricsHttpServer = new PrometheusExporterMetricsHttpServer(promExporter);

            try
            {
                metricsHttpServer.Start();
                CollectMetrics(simpleProcessor, promExporter);
            }
            finally
            {
                await Task.Delay(WaitDuration);

                var client   = new HttpClient();
                var response = await client.GetAsync("http://localhost:9184/metrics/");

                Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                var responseText = response.Content.ReadAsStringAsync().Result;
                this.output.WriteLine($"Response from metrics API is \n {responseText}");
                this.ValidateResponse(responseText);
                metricsHttpServer.Stop();
            }
        }
Example #3
0
        internal static object Run()
        {
            var promOptions = new PrometheusExporterOptions()
            {
                Url = "http://localhost:9184/metrics/"
            };
            var promExporter    = new PrometheusExporter(promOptions);
            var simpleProcessor = new UngroupedBatcher(promExporter, TimeSpan.FromSeconds(5));
            var meter           = MeterFactory.Create(simpleProcessor).GetMeter("library1");
            var testCounter     = meter.CreateInt64Counter("testCounter");

            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 httpServer     = new PrometheusExporterMetricsHttpServer(promExporter);
            var defaultContext = default(SpanContext);

            try
            {
                httpServer.Start();

                for (int i = 0; i < 1000; i++)
                {
                    testCounter.Add(defaultContext, 100, meter.GetLabelSet(labels1));
                    testCounter.Add(defaultContext, 10, meter.GetLabelSet(labels1));
                    testCounter.Add(defaultContext, 200, meter.GetLabelSet(labels2));
                    testCounter.Add(defaultContext, 10, meter.GetLabelSet(labels2));

                    if (i % 10 == 0)
                    {
                        // Collect is called here explicitly as there is
                        // no controller implementation yet.
                        // TODO: There should be no need to cast to MeterSdk.
                        (meter as MeterSdk).Collect();
                    }

                    Task.Delay(1000).Wait();
                }
            }
            finally
            {
                Task.Delay(3000).Wait();
                httpServer.Stop();
            }

            return(null);
        }
Example #4
0
        public void E2ETest1()
        {
            var promOptions = new PrometheusExporterOptions()
            {
                Url = "http://localhost:9184/metrics/"
            };
            var promExporter    = new PrometheusExporter(promOptions);
            var simpleProcessor = new UngroupedBatcher(promExporter);
            var meter           = MeterFactory.Create(simpleProcessor).GetMeter("library1") as MeterSdk;
            var testCounter     = meter.CreateInt64Counter("testCounter");

            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 metricsHttpServer = new PrometheusExporterMetricsHttpServer(promExporter);

            try
            {
                metricsHttpServer.Start();

                var defaultContext = default(SpanContext);

                for (int i = 0; i < 1000; i++)
                {
                    testCounter.Add(defaultContext, 100, meter.GetLabelSet(labels1));
                    testCounter.Add(defaultContext, 10, meter.GetLabelSet(labels1));
                    testCounter.Add(defaultContext, 200, meter.GetLabelSet(labels2));
                    testCounter.Add(defaultContext, 10, meter.GetLabelSet(labels2));

                    if (i % 10 == 0)
                    {
                        meter.Collect();
                    }

                    // Change delay to higher value to manually check Promtheus.
                    // These tests are just to temporarily validate export to prometheus.
                    // Task.Delay(100).Wait();
                }
            }
            finally
            {
                Task.Delay(100).Wait();
                metricsHttpServer.Stop();
            }
        }
Example #5
0
        public async Task E2ETestMiddleware()
        {
            var promOptions = new PrometheusExporterOptions {
                Url = "/metrics"
            };
            var promExporter    = new PrometheusExporter(promOptions);
            var simpleProcessor = new UngroupedBatcher();

            var builder = new WebHostBuilder()
                          .Configure(app =>
            {
                app.UsePrometheus();
            })
                          .ConfigureServices(services =>
            {
                services.AddSingleton(promOptions);
                services.AddSingleton(promExporter);     // Temporary till we figure out metrics configuration
            });

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

            try
            {
                CollectMetrics(simpleProcessor, promExporter);
            }
            finally
            {
                var response = await client.GetAsync("/foo");

                Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);

                await Task.Delay(WaitDuration);

                response = await client.GetAsync("/metrics");

                Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                var responseText = await response.Content.ReadAsStringAsync();

                this.output.WriteLine($"Response from metrics API is \n {responseText}");
                this.ValidateResponse(responseText);
            }
        }
        public Task StartAsync(CancellationToken cancellationToken)
        {
            var interval        = TimeSpan.FromSeconds(5);
            var simpleProcessor = new UngroupedBatcher(exporter, interval);

            this.meterFactory = MeterFactory.Create(simpleProcessor);

            foreach (var initializer in initializers)
            {
                initializer.Initialize(meterFactory);
            }

            this.timer = new Timer(CollectMetrics, meterFactory, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);

            exporter.Start();

            this.timer.Change(interval, interval);

            return(Task.CompletedTask);
        }
Example #7
0
        public async Task E2ETestMiddleware()
        {
            var promOptions = new PrometheusExporterOptions()
            {
                Url = "/metrics"
            };
            var promExporter    = new PrometheusExporter(promOptions);
            var simpleProcessor = new UngroupedBatcher(promExporter, new System.TimeSpan(100));

            var builder = new WebHostBuilder()
                          .Configure(app =>
            {
                app.UsePrometheus();
            })
                          .ConfigureServices(services =>
            {
                services.AddSingleton(promOptions);
                services.AddSingleton(promExporter);     //Temporary till we figure out metrics configuration
            });

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

            try
            {
                CollectMetrics(simpleProcessor);
            }
            finally
            {
                var response = await client.GetAsync("/foo");

                Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);

                Task.Delay(200).Wait();
                response = await client.GetAsync("/metrics");

                Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                Assert.Contains("testCounter{dim1=\"value1\"}", response.Content.ReadAsStringAsync().Result);
                Assert.Contains("testCounter{dim1=\"value2\"}", response.Content.ReadAsStringAsync().Result);
            }
        }
Example #8
0
        private static void CollectMetrics(UngroupedBatcher simpleProcessor, MetricExporter exporter)
        {
            var meter = MeterFactory.Create(mb =>
            {
                mb.SetMetricProcessor(simpleProcessor);
                mb.SetMetricExporter(exporter);
                mb.SetMetricPushInterval(TimeSpan.FromMilliseconds(metricPushIntervalMsec));
            }).GetMeter("library1");

            var testCounter = meter.CreateInt64Counter("testCounter");
            var testMeasure = meter.CreateInt64Measure("testMeasure");

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

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

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

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


            var defaultContext = default(SpanContext);

            for (int i = 0; i < 10; i++)
            {
                testCounter.Add(defaultContext, 100, meter.GetLabelSet(labels1));
                testCounter.Add(defaultContext, 10, meter.GetLabelSet(labels1));
                testCounter.Add(defaultContext, 200, meter.GetLabelSet(labels2));
                testCounter.Add(defaultContext, 10, meter.GetLabelSet(labels2));

                testMeasure.Record(defaultContext, 10, meter.GetLabelSet(labels1));
                testMeasure.Record(defaultContext, 100, meter.GetLabelSet(labels1));
                testMeasure.Record(defaultContext, 5, meter.GetLabelSet(labels1));
                testMeasure.Record(defaultContext, 500, meter.GetLabelSet(labels1));
            }
        }
Example #9
0
        public void E2ETestMetricsHttpServer()
        {
            var promOptions = new PrometheusExporterOptions()
            {
                Url = "http://localhost:9184/metrics/"
            };
            var promExporter    = new PrometheusExporter(promOptions);
            var simpleProcessor = new UngroupedBatcher(promExporter);

            var metricsHttpServer = new PrometheusExporterMetricsHttpServer(promExporter);

            try
            {
                metricsHttpServer.Start();
                CollectMetrics(simpleProcessor);
            }
            finally
            {
                // Change delay to higher value to manually check Promtheus.
                // These tests are just to temporarily validate export to prometheus.
                Task.Delay(100).Wait();
                metricsHttpServer.Stop();
            }
        }
Example #10
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);
        }
Example #11
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();
        }