Пример #1
0
        public void PrometheusExporterTest1()
        {
            var promOptions = new PrometheusExporterOptions()
            {
                Url = "http://localhost:9184/metrics/"
            };
            List <Metric <long> > metrics = new List <Metric <long> >();
            var promExporter      = new PrometheusExporter(promOptions);
            var metricsHttpServer = new PrometheusExporterMetricsHttpServer(promExporter);

            try
            {
                metricsHttpServer.Start();
                var label1 = new List <KeyValuePair <string, string> >();
                label1.Add(new KeyValuePair <string, string>("dim1", "value1"));
                metrics.Add(new Metric <long>("ns", "metric1", "desc", label1, AggregationType.LongSum));
                metrics.Add(new Metric <long>("ns", "metric1", "desc", label1, AggregationType.LongSum));
                metrics.Add(new Metric <long>("ns", "metric1", "desc", label1, AggregationType.LongSum));

                promExporter.ExportAsync(metrics, CancellationToken.None);
            }
            finally
            {
                // Change delay to higher value to manually check Promtheus.
                // These tests are just to temporarily validate export to prometheus.
                Task.Delay(10).Wait();
                metricsHttpServer.Stop();
            }
        }
Пример #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();
            }
        }
Пример #3
0
        internal static object Run()
        {
            var promOptions = new PrometheusExporterOptions()
            {
                Url = "http://localhost:9184/metrics/"
            };
            Metric <long> metric       = new Metric <long>("sample");
            var           promExporter = new PrometheusExporter <long>(promOptions, metric);

            try
            {
                promExporter.Start();
                List <KeyValuePair <string, string> > label1 = new List <KeyValuePair <string, string> >();
                label1.Add(new KeyValuePair <string, string>("dim1", "value1"));
                var labelSet1 = new LabelSet(label1);
                metric.GetOrCreateMetricTimeSeries(labelSet1).Add(100);
                Task.Delay(30000).Wait();
                metric.GetOrCreateMetricTimeSeries(labelSet1).Add(200);
                Console.WriteLine("Look at metrics in Prometheus console!");
                Console.ReadLine();
            }
            finally
            {
                promExporter.Stop();
            }

            return(null);
        }
Пример #4
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);
        }
Пример #5
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();
            }
        }
Пример #6
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 static MeterProviderBuilder AddPrometheusExporter(this MeterProviderBuilder builder, Action <PrometheusExporterOptions> configure = null)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            var options = new PrometheusExporterOptions();

            configure?.Invoke(options);
            var exporter            = new PrometheusExporter(options);
            var pullMetricProcessor = new PullMetricProcessor(exporter, false);

            exporter.MakePullRequest = pullMetricProcessor.PullRequest;

            var metricsHttpServer = new PrometheusExporterMetricsHttpServer(exporter);

            metricsHttpServer.Start();
            return(builder.AddMetricProcessor(pullMetricProcessor));
        }
Пример #8
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);
            }
        }
Пример #9
0
        public void PrometheusExporterTest1()
        {
            var promOptions = new PrometheusExporterOptions()
            {
                Url = "http://localhost:9184/metrics/"
            };
            Metric <long> metric       = new Metric <long>("sample");
            var           promExporter = new PrometheusExporter <long>(promOptions, metric);

            try
            {
                promExporter.Start();
                List <KeyValuePair <string, string> > label1 = new List <KeyValuePair <string, string> >();
                label1.Add(new KeyValuePair <string, string>("dim1", "value1"));
                var labelSet1 = new LabelSet(label1);
                metric.GetOrCreateMetricTimeSeries(labelSet1).Add(100);
                metric.GetOrCreateMetricTimeSeries(labelSet1).Add(200);
            }
            finally
            {
                Task.Delay(10000).Wait();
                promExporter.Stop();
            }
        }
Пример #10
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();
            }
        }
Пример #11
0
 public MetricsHttpServer(IViewManager viewManager, PrometheusExporterOptions options, CancellationToken token)
 {
     this.viewManager = viewManager;
     this.token       = token;
     this.httpListener.Prefixes.Add(options.Url);
 }
        static IServiceCollection AddSampleOpenTelemetry(this IServiceCollection services, SampleAppOptions sampleAppOptions, IConfiguration configuration, Action <TracerBuilder> traceBuilder = null)
        {
            var openTelemetryConfigSection = configuration.GetSection("OpenTelemetry");
            var jaegerConfigSection        = openTelemetryConfigSection.GetSection("Jaeger");

            services.Configure <JaegerExporterOptions>(jaegerConfigSection);

            var zipkinConfigSection = openTelemetryConfigSection.GetSection("Zipkin");

            services.Configure <ZipkinTraceExporterOptions>(zipkinConfigSection);

            // setup open telemetry
            services.AddOpenTelemetry((sp, builder) =>
            {
                var serviceName = OpenTelemetryExtensions.TracerServiceName;

                var exporterCount = 0;

                if (zipkinConfigSection.Exists())
                {
                    var zipkinOptions = sp.GetService <IOptions <ZipkinTraceExporterOptions> >();
                    if (zipkinOptions.Value != null && zipkinOptions.Value.Endpoint != null)
                    {
                        // To start zipkin:
                        // docker run -d -p 9411:9411 openzipkin/zipkin
                        exporterCount++;

                        builder.UseZipkin(o =>
                        {
                            o.Endpoint    = zipkinOptions.Value.Endpoint;
                            o.ServiceName = serviceName;
                        });

                        Console.WriteLine("Using OpenTelemetry Zipkin exporter");
                    }
                }


                if (!string.IsNullOrWhiteSpace(sampleAppOptions.ApplicationInsightsForOpenTelemetryInstrumentationKey))
                {
                    exporterCount++;

                    builder.UseApplicationInsights(o =>
                    {
                        o.InstrumentationKey = sampleAppOptions.ApplicationInsightsForOpenTelemetryInstrumentationKey;
                        o.TelemetryInitializers.Add(new CloudRoleTelemetryInitializer());
                    });

                    Console.WriteLine("Using OpenTelemetry ApplicationInsights exporter");
                }

                if (jaegerConfigSection.Exists())
                {
                    // Running jaeger with docker
                    // docker run -d --name jaeger \
                    //  -e COLLECTOR_ZIPKIN_HTTP_PORT=19411 \
                    //  -p 5775:5775/udp \
                    //  -p 6831:6831/udp \
                    //  -p 6832:6832/udp \
                    //  -p 5778:5778 \
                    //  -p 16686:16686 \
                    //  -p 14268:14268 \
                    //  -p 19411:19411 \
                    //  jaegertracing/all-in-one
                    var jaegerOptions = sp.GetService <IOptions <JaegerExporterOptions> >();
                    if (jaegerOptions.Value != null && !string.IsNullOrWhiteSpace(jaegerOptions.Value.AgentHost))
                    {
                        exporterCount++;

                        builder.UseJaeger(o =>
                        {
                            o.ServiceName   = serviceName;
                            o.AgentHost     = jaegerOptions.Value.AgentHost;
                            o.AgentPort     = jaegerOptions.Value.AgentPort;
                            o.MaxPacketSize = jaegerOptions.Value.MaxPacketSize;
                            o.ProcessTags   = jaegerOptions.Value.ProcessTags;
                        });

                        Console.WriteLine("Using OpenTelemetry Jaeger exporter");
                    }
                }

                if (exporterCount == 0)
                {
                    throw new Exception("No sink for open telemetry was configured");
                }

                builder
                .SetSampler(new AlwaysSampleSampler())
                .AddDependencyCollector(config =>
                {
                    config.SetHttpFlavor = true;
                })
                .AddRequestCollector()
                .SetResource(new Resource(new Dictionary <string, object>
                {
                    { "service.name", serviceName }
                }));

                traceBuilder?.Invoke(builder);
            });


            var prometheusConfigSection = openTelemetryConfigSection.GetSection("Prometheus");

            if (prometheusConfigSection.Exists())
            {
                var prometheusExporterOptions = new PrometheusExporterOptions();
                prometheusConfigSection.Bind(prometheusExporterOptions);

                if (!string.IsNullOrWhiteSpace(prometheusExporterOptions.Url))
                {
                    var prometheusExporter = new PrometheusExporter(prometheusExporterOptions);
                    services.AddSingleton(prometheusExporter);

                    // Add start/stop lifetime support
                    services.AddHostedService <PromotheusExporterHostedService>();

                    Console.WriteLine($"Using OpenTelemetry Prometheus exporter in '{prometheusExporterOptions.Url}'");
                }
            }

            return(services);
        }
Пример #13
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);
        }
Пример #14
0
        private static MeterProviderBuilder AddPrometheusExporter(MeterProviderBuilder builder, PrometheusExporterOptions options, Action <PrometheusExporterOptions> configure = null)
        {
            configure?.Invoke(options);

            var exporter = new PrometheusExporter(options);
            var reader   = new BaseExportingMetricReader(exporter);

            reader.TemporalityPreference = MetricReaderTemporalityPreference.Cumulative;

            return(builder.AddReader(reader));
        }
Пример #15
0
 public MetricsHttpServer(List <Metric> metrics, PrometheusExporterOptions options, CancellationToken token)
 {
     this.Metrics = metrics;
     this.token   = token;
     this.httpListener.Prefixes.Add(options.Url);
 }
Пример #16
0
        static IServiceCollection AddSampleOpenTelemetry(this IServiceCollection services, IConfiguration configuration, Action <TracerBuilder> traceBuilder = null)
        {
            // setup open telemetry
            services.AddOpenTelemetry(builder =>
            {
                var serviceName = OpenTelemetryExtensions.TracerServiceName;

                var exporterCount = 0;

                // To start zipkin:
                // docker run -d -p 9411:9411 openzipkin/zipkin
                var zipkinUrl = configuration.GetZipkinUrl();
                if (!string.IsNullOrWhiteSpace(zipkinUrl))
                {
                    exporterCount++;

                    builder.UseZipkin(o =>
                    {
                        o.Endpoint    = new Uri(zipkinUrl);
                        o.ServiceName = serviceName;
                    });
                }

                var appInsightsKey = configuration.GetApplicationInsightsInstrumentationKeyForOpenTelemetry();
                if (!string.IsNullOrWhiteSpace(appInsightsKey))
                {
                    exporterCount++;

                    builder.UseApplicationInsights(o =>
                    {
                        o.InstrumentationKey = appInsightsKey;
                        o.TelemetryInitializers.Add(new CloudRoleTelemetryInitializer());
                    });
                }

                // Running jaeger with docker
                // docker run -d--name jaeger \
                //  -e COLLECTOR_ZIPKIN_HTTP_PORT = 19411 \
                //  -p 5775:5775 / udp \
                //  -p 6831:6831 / udp \
                //  -p 6832:6832 / udp \
                //  -p 5778:5778 \
                //  -p 16686:16686 \
                //  -p 14268:14268 \
                //  -p 19411:19411 \
                //  jaegertracing/all -in-one:1.15
                var jaegerHost = configuration.GetJaegerHost();
                if (!string.IsNullOrWhiteSpace(jaegerHost))
                {
                    exporterCount++;

                    builder.UseJaeger(o =>
                    {
                        o.ServiceName = serviceName;
                        o.AgentHost   = jaegerHost;
                        o.AgentPort   = 6831;
                        // o.AgentPort = 14268;
                        o.MaxPacketSize = 1000;
                    });
                }

                if (exporterCount == 0)
                {
                    throw new Exception("No sink for open telemetry was configured");
                }

                builder.SetSampler(new AlwaysSampleSampler());
                builder.AddDependencyCollector(config =>
                {
                    config.SetHttpFlavor = true;
                });
                builder.AddRequestCollector(o =>
                {
                });
                builder.SetResource(new Resource(new Dictionary <string, object>
                {
                    { "service.name", serviceName }
                }));

                traceBuilder?.Invoke(builder);
            });

            if (!string.IsNullOrWhiteSpace(configuration.GetPrometheusExportURL()))
            {
                var prometheusExporterOptions = new PrometheusExporterOptions()
                {
                    Url = configuration.GetPrometheusExportURL(),
                };

                var prometheusExporter = new PrometheusExporter(prometheusExporterOptions);
                services.AddSingleton(prometheusExporter);


                // Add start/stop lifetime support
                services.AddHostedService <PromotheusExporterHostedService>();
            }

            return(services);
        }