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