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