// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env, Database database, KeyStorage keyStorage, ILogger <Startup> logger) { logger.LogInformation("Startup.Configure called"); keyStorage.LoadKeysFromEnvIfNeeded(); if (DotNetRuntimeCollector == null && String.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("DOTNET_DISABLE_EXTENDED_METRICS"))) { // https://github.com/djluck/prometheus-net.DotNetRuntime DotNetRuntimeCollector = DotNetRuntimeStatsBuilder.Customize() // Only 1 in 10 contention events will be sampled .WithContentionStats(sampleRate: SampleEvery.TenEvents) // Only 1 in 100 JIT events will be sampled .WithJitStats(sampleRate: SampleEvery.HundredEvents) // Every event will be sampled (disables sampling) .WithThreadPoolSchedulingStats(sampleRate: SampleEvery.OneEvent) .StartCollecting(); } database.InitializeDatabase(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseSerilogRequestLogging(); //app.UseHttpMetrics(); // doesn't work. Probably because we have our own mapping, and something is missing app.UseEndpoints(Endpoint.All); app.UseEndpoints(endpoints => { endpoints.MapMetrics(); }); app.UseHangfireServer(); app.UseHangfireDashboard(); UserCleanupJob.StartRecurringJob(); }
public void SetUp() { _collector = (DotNetRuntimeStatsCollector)ConfigureBuilder(DotNetRuntimeStatsBuilder.Customize()) .StartCollecting(Prometheus.Metrics.NewCustomRegistry()); MetricProducer = (TMetricProducer)_collector.ServiceProvider.GetServices <IMetricProducer>().Single(x => x is TMetricProducer); // wait for event listener thread to spin up var waitingFor = Stopwatch.StartNew(); var waitFor = TimeSpan.FromSeconds(10); while (!_collector.EventListeners.All(x => x.StartedReceivingEvents)) { Thread.Sleep(10); Console.Write("Waiting for event listeners to be active.. "); if (waitingFor.Elapsed > waitFor) { Assert.Fail($"Waited {waitFor} and still not all event listeners were ready! Event listeners not ready: {string.Join(", ", _collector.EventListeners.Where(x => !x.StartedReceivingEvents))}"); return; } } Console.WriteLine("All event listeners should be active now."); }
public Task StartAsync(CancellationToken cancellationToken) { if (!_options.Enabled) return Task.CompletedTask; _logger.LogInformation("Configuring prometheus-net.DotNetRuntime"); var builder = DotNetRuntimeStatsBuilder.Default(); if (_options.Verbose) { builder = DotNetRuntimeStatsBuilder.Customize() .WithContentionStats(CaptureLevel.Informational) .WithGcStats(CaptureLevel.Verbose) .WithThreadPoolStats(CaptureLevel.Informational) .WithExceptionStats(CaptureLevel.Errors) .WithJitStats(); } builder.WithErrorHandler(ex => _logger.LogError(ex, "Unexpected exception occurred in prometheus-net.DotNetRuntime")); if (_options.Debug) { _logger.LogInformation("Using debugging metrics"); builder.WithDebuggingMetrics(true); } _logger.LogInformation("Starting prometheus-net.DotNetRuntime"); _metrics = builder.StartCollecting(); return Task.CompletedTask; }
public static IDisposable CreateCollector() { _logger.LogInformation($"Configuring prometheus-net.DotNetRuntime: will recycle event listeners every {_options.RecycleEvery} ({_options.RecycleEvery.TotalSeconds:N0} seconds)."); var builder = DotNetRuntimeStatsBuilder.Default(); if (!_options.UseDefaultMetrics) { builder = DotNetRuntimeStatsBuilder.Customize() .WithContentionStats(CaptureLevel.Informational) .WithGcStats(CaptureLevel.Verbose) .WithThreadPoolStats(CaptureLevel.Informational) .WithExceptionStats(CaptureLevel.Errors) .WithJitStats() .WithKestrelStats(CaptureLevel.Informational); } builder #if NET5_0 .RecycleCollectorsEvery(_options.RecycleEvery) #endif .WithErrorHandler(ex => _logger.LogError(ex, "Unexpected exception occurred in prometheus-net.DotNetRuntime")); if (_options.UseDebuggingMetrics) { _logger.LogInformation("Using debugging metrics."); builder.WithDebuggingMetrics(true); } _logger.LogInformation("Starting prometheus-net.DotNetRuntime..."); return(builder .StartCollecting()); }
public void StartCollecting_Does_Not_Allow_Two_Collectors_To_Run_Simultaneously() { using (DotNetRuntimeStatsBuilder.Customize().StartCollecting()) { Assert.Throws<InvalidOperationException>(() => DotNetRuntimeStatsBuilder.Customize().StartCollecting()); } }
public virtual void ConfigureMetrics(IApplicationBuilder app) { var callsCounter = Metrics.CreateCounter("request_total", "Counts the requests to the Country API endpoints", new CounterConfiguration() { LabelNames = new[] { "method", "endpoint" } }); app.Use((context, next) => { callsCounter.WithLabels(context.Request.Method, context.Request.Path); return(next()); }); var collector = DotNetRuntimeStatsBuilder .Customize() .WithContentionStats() .WithJitStats() .WithThreadPoolSchedulingStats() .WithThreadPoolStats() .WithGcStats() .WithExceptionStats() .StartCollecting(); }
public void StartCollecting_Allows_A_New_Collector_To_Run_After_Disposing_Previous_Collector_For_Each_Registry_Instance() { var registry1 = NewRegistry(); var registry2 = NewRegistry(); using (DotNetRuntimeStatsBuilder.Customize().StartCollecting(registry1)) { using (DotNetRuntimeStatsBuilder.Customize().StartCollecting(registry2)) { } using (DotNetRuntimeStatsBuilder.Customize().StartCollecting(registry2)) { } } using (DotNetRuntimeStatsBuilder.Customize().StartCollecting(registry2)) { using (DotNetRuntimeStatsBuilder.Customize().StartCollecting(registry1)) { } using (DotNetRuntimeStatsBuilder.Customize().StartCollecting(registry1)) { } } }
public void StartCollecting_Does_Not_Allow_Two_Collectors_To_Run_Simultaneously_For_Each_Registry_Instance() { var registry1 = NewRegistry();; var registry2 = NewRegistry();; using (DotNetRuntimeStatsBuilder.Customize().StartCollecting()) { Assert.Throws <InvalidOperationException>(() => DotNetRuntimeStatsBuilder.Customize().StartCollecting()); using (DotNetRuntimeStatsBuilder.Customize().StartCollecting(registry1)) { Assert.Throws <InvalidOperationException>(() => DotNetRuntimeStatsBuilder.Customize().StartCollecting()); Assert.Throws <InvalidOperationException>(() => DotNetRuntimeStatsBuilder.Customize().StartCollecting(registry1)); using (DotNetRuntimeStatsBuilder.Customize().StartCollecting(registry2)) { Assert.Throws <InvalidOperationException>(() => DotNetRuntimeStatsBuilder.Customize().StartCollecting()); Assert.Throws <InvalidOperationException>(() => DotNetRuntimeStatsBuilder.Customize().StartCollecting(registry1)); Assert.Throws <InvalidOperationException>(() => DotNetRuntimeStatsBuilder.Customize().StartCollecting(registry2)); } Assert.Throws <InvalidOperationException>(() => DotNetRuntimeStatsBuilder.Customize().StartCollecting()); Assert.Throws <InvalidOperationException>(() => DotNetRuntimeStatsBuilder.Customize().StartCollecting(registry1)); } Assert.Throws <InvalidOperationException>(() => DotNetRuntimeStatsBuilder.Customize().StartCollecting()); } }
public Startup(IConfiguration configuration) { Configuration = configuration; DotNetRuntimeStatsBuilder.Customize() .WithExceptionStats(CaptureLevel.Errors) .StartCollecting(); }
public void WithCustomCollector_will_not_register_the_same_collector_twice() { var builder = DotNetRuntimeStatsBuilder .Customize() .WithGcStats() .WithCustomCollector(new GcStatsCollector()); Assert.That(builder.StatsCollectors.Count, Is.EqualTo(1)); }
public void StartCollecting_Allows_A_New_Collector_To_Run_After_Disposing_A_Previous_Collector() { using (DotNetRuntimeStatsBuilder.Customize().StartCollecting()) { } using (DotNetRuntimeStatsBuilder.Customize().StartCollecting()) { } }
public void Cannot_Register_Tasks_At_Unsupported_Levels() { var ex = Assert.Throws <UnsupportedCaptureLevelException>(() => DotNetRuntimeStatsBuilder.Customize().WithGcStats(CaptureLevel.Errors)); Assert.That(ex.SpecifiedLevel, Is.EqualTo(CaptureLevel.Errors)); Assert.That(ex.SupportedLevels, Is.EquivalentTo(new [] { CaptureLevel.Verbose, CaptureLevel.Informational })); ex = Assert.Throws <UnsupportedCaptureLevelException>(() => DotNetRuntimeStatsBuilder.Customize().WithThreadPoolStats(CaptureLevel.Verbose)); Assert.That(ex.SpecifiedLevel, Is.EqualTo(CaptureLevel.Verbose)); Assert.That(ex.SupportedLevels, Is.EquivalentTo(new [] { CaptureLevel.Counters, CaptureLevel.Informational })); }
public async Task StartCollecting_Allows_A_New_Collector_To_Run_After_Disposing_A_Previous_Collector() { using (DotNetRuntimeStatsBuilder.Customize().StartCollecting()) { await Assert_Expected_Stats_Are_Present_In_Registry(GetDefaultRegistry()); } using (DotNetRuntimeStatsBuilder.Customize().StartCollecting()) { await Assert_Expected_Stats_Are_Present_In_Registry(GetDefaultRegistry()); } }
public static void Main(string[] args) { DotNetRuntimeStatsBuilder.Customize() .WithThreadPoolStats() .WithContentionStats() .WithGcStats() .WithJitStats() .WithThreadPoolStats() .StartCollecting(); CreateHostBuilder(args).Build().Run(); }
public void WithCustomCollector_will_not_register_the_same_collector_twice() { var expectedCollector = new GcStatsCollector(); var builder = DotNetRuntimeStatsBuilder .Customize() .WithGcStats() .WithCustomCollector(expectedCollector); Assert.That(builder.StatsCollectors.Count, Is.EqualTo(1)); Assert.That(builder.StatsCollectors.TryGetValue(new GcStatsCollector(), out var actualColector), Is.True); Assert.That(actualColector, Is.SameAs(expectedCollector)); }
public static void Main(string[] args) { DotNetRuntimeStatsBuilder.Customize() .WithThreadPoolSchedulingStats() .WithContentionStats() .WithGcStats() .WithJitStats() .WithThreadPoolStats() .WithErrorHandler(ex => Console.WriteLine("ERROR: " + ex.ToString())) //.WithDebuggingMetrics(true); .StartCollecting(); CreateHostBuilder(args).Build().Run(); }
static void Main(string[] args) { var tasks = Enumerable.Range(1, 2_000_000) .Select(_ => Task.Run(() => 1)) .ToArray(); var b = new byte[1024 * 1000]; if (args.Length > 0 && args[0] == "metrics") { var metrics = App.Metrics.AppMetrics.CreateDefaultBuilder().Build(); var collector = DotNetRuntimeStatsBuilder.Customize() .WithContentionStats() .WithThreadPoolStats() .WithThreadPoolSchedulingStats(); if (args.Any(x => x == "jit")) { collector.WithJitStats(); } if (args.Any(x => x == "gc")) { collector.WithGcStats(); } collector .WithDebuggingMetrics(false) .StartCollecting(metrics); } var b2 = new byte[1024 * 1000]; var b3 = new byte[1024 * 1000]; Task.WaitAll(tasks); Console.WriteLine("Done"); // return; BenchmarkRunner.Run <TestBenchmark>( DefaultConfig.Instance .With( Job.Default .With(CoreRuntime.Core31) .WithLaunchCount(1) .WithIterationTime(TimeInterval.FromMilliseconds(200)) .With(Platform.X64) .With(Jit.RyuJit) ) ); }
public static void Main(string[] args) { IDisposable collector = DotNetRuntimeStatsBuilder .Customize() .WithContentionStats() .WithJitStats() .WithThreadPoolSchedulingStats() .WithThreadPoolStats() .WithGcStats() .WithExceptionStats() .StartCollecting(); CreateHostBuilder(args).Build().Run(); collector.Dispose(); }
public static IConveyBuilder AddRuntimeMetrics(this IConveyBuilder builder) { DotNetRuntimeStatsBuilder .Customize() .WithGcStats() .WithThreadPoolStats() .WithThreadPoolSchedulingStats() .StartCollecting(); builder.Services.AddPrometheusCounters(); builder.Services.AddPrometheusAspNetCoreMetrics(); builder.Services.AddPrometheusHttpClientMetrics(); builder.Services.AddPrometheusGrpcClientMetrics(); return(builder); }
private static IEnumerable <ExposedMetric> GetExposedMetric(SourceAndConfig source) { Console.WriteLine($"Getting metrics for {source}.."); // Start collector var registry = new CollectorRegistry(); using var statsCollector = source.ApplyConfig(DotNetRuntimeStatsBuilder.Customize()).StartCollecting(registry); // Wait for metrics to be available (hacky!) Thread.Sleep(1500); // Pull registered collectors var collectors = registry.TryGetFieldValue("_collectors", Flags.InstancePrivate) as ConcurrentDictionary <string, Collector>; return(collectors.Values.Select(c => new ExposedMetric(c, source.Source))); }
public static async Task Main(string[] args) { Log.Logger = new LoggerConfiguration() .ReadFrom.Configuration(Configuration) .WriteTo.Debug() .CreateLogger(); Console.WriteLine("Enabling prometheus-net.DotNetStats..."); DotNetRuntimeStatsBuilder.Customize() .WithThreadPoolSchedulingStats() .WithContentionStats() .WithGcStats() .WithJitStats() .WithThreadPoolStats() .WithExceptionStats() .WithErrorHandler(ex => Log.Error(ex, "DotNetRuntime Error")) //.WithDebuggingMetrics(true); .StartCollecting(); try { var host = CreateHostBuilder(args).Build(); if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT").Equals("Development") && Configuration.GetValue <bool>("UseInMemoryDatabase") == false) { using var serviceScope = host.Services.CreateScope(); var services = serviceScope.ServiceProvider; using var scope = services.GetRequiredService <IServiceScopeFactory>().CreateScope(); await DbMigrationHelper <ApplicationDbContext> .EnsureDatabaseMigratedAsync(scope); } Log.Information($"web api starting at {DateTime.UtcNow}"); host.Run(); } catch (Exception ex) { Log.Fatal(ex, "Host terminated unexpectedly"); return; } finally { Log.CloseAndFlush(); } }
public Task StartAsync(CancellationToken cancellationToken) { if (_enabled) { _collector = DotNetRuntimeStatsBuilder .Customize() .WithContentionStats() .WithJitStats() .WithThreadPoolStats() .WithThreadPoolStats() .WithGcStats() .WithExceptionStats() .StartCollecting(); } return(Task.CompletedTask); }
public static IDisposable EnableCollector(Prometheus config) { if (config.Enabled) { return(DotNetRuntimeStatsBuilder .Customize() .WithContentionStats() .WithJitStats() .WithThreadPoolStats() .WithGcStats() .WithExceptionStats() //.WithDebuggingMetrics(true) .WithErrorHandler(ex => Log.Error(ex, "Unexpected exception occurred in prometheus-net.DotNetRuntime")) .StartCollecting()); } return(null); }
public static void Main(string[] args) { if (Environment.GetEnvironmentVariable("NOMON") == null) { Console.WriteLine("Enabling prometheus-net.DotNetStats..."); DotNetRuntimeStatsBuilder.Customize() .WithThreadPoolSchedulingStats() .WithContentionStats() .WithGcStats() .WithJitStats() .WithThreadPoolStats() .WithErrorHandler(ex => Console.WriteLine("ERROR: " + ex.ToString())) //.WithDebuggingMetrics(true); .StartCollecting(); } CreateWebHostBuilder(args).Build().Run(); }
public PrometheusMetricsProvider AddDotNetRuntimeStats( SampleEvery contentionSampleRate = SampleEvery.TenEvents, SampleEvery jitSampleRate = SampleEvery.HundredEvents, SampleEvery threadScheduleSampleRate = SampleEvery.OneEvent) { if (_collector == null) { _collector = DotNetRuntimeStatsBuilder .Customize() .WithContentionStats(contentionSampleRate) .WithJitStats(jitSampleRate) .WithThreadPoolSchedulingStats(null, threadScheduleSampleRate) .WithThreadPoolStats() .WithGcStats() .StartCollecting(); } return(this); }
private PrometheusReporter(string host, string port, string @namespace, CustomMetrics?customMetrics) { _namespace = @namespace; _host = host; _port = int.Parse(port); _server = new MetricServer(hostname: _host, port: _port, url: "metrics/"); _counters = new Dictionary <string, Counter>(); _gauges = new Dictionary <string, Gauge>(); _histograms = new Dictionary <string, Histogram>(); _dotnetCollector = DotNetRuntimeStatsBuilder .Customize() .WithContentionStats() .WithThreadPoolSchedulingStats() .WithThreadPoolStats() .WithGcStats() .WithExceptionStats(); _systemMetrics = new ServiceCollection(); ImportCustomMetrics(customMetrics); }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } var metrics = app.ApplicationServices.GetService <IMetrics>(); metrics.Measure.Counter.Increment(new CounterOptions() { Name = "test-counter", Context = "some-context" }); if (Environment.GetEnvironmentVariable("NOMON") == null) { Console.WriteLine("Enabling prometheus-net.DotNetStats..."); DotNetRuntimeStatsBuilder.Customize(metrics) .WithThreadPoolSchedulingStats() .WithContentionStats() .WithGcStats() .WithJitStats() .WithThreadPoolStats() .WithErrorHandler(ex => Console.WriteLine("ERROR: " + ex.ToString())) .WithDebuggingMetrics(true) .StartCollecting(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseEndpoints(endpoints => { // Mapping of endpoints goes here: endpoints.MapControllers(); }); }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseWebAssemblyDebugging(); } else { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseBlazorFrameworkFiles(); app.UseStaticFiles(); app.UseRouting(); app.UseHttpMetrics(); IDisposable collector = DotNetRuntimeStatsBuilder .Customize() .WithContentionStats() .WithJitStats() .WithThreadPoolSchedulingStats() .WithThreadPoolStats() .WithGcStats() .WithExceptionStats() .StartCollecting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapDefaultControllerRoute(); endpoints.MapRazorPages(); endpoints.MapControllers(); endpoints.MapFallbackToFile("index.html"); endpoints.MapMetrics(); }); }
public void StartCollecting_Allows_Multiple_Collectors_For_Non_Default_Registries() { #if PROMV2 var registry1 = new DefaultCollectorRegistry(); var registry2 = new DefaultCollectorRegistry(); #elif PROMV3 var registry1 = Metrics.NewCustomRegistry(); var registry2 = Metrics.NewCustomRegistry(); #endif using (DotNetRuntimeStatsBuilder.Customize().StartCollecting()) { using (DotNetRuntimeStatsBuilder.Customize().StartCollecting(registry1)) { using (DotNetRuntimeStatsBuilder.Customize().StartCollecting(registry2)) { } } } }
static async Task RunExperiment(bool collectorEnabled) { if (!collectorEnabled) { Console.WriteLine(".NET runtime metric collection is DISABLED"); await RunForcedGcLoop(); } Console.WriteLine(".NET runtime metric collection is ENABLED"); using var collector = DotNetRuntimeStatsBuilder.Customize() .WithContentionStats(SampleEvery.OneEvent) .WithJitStats(SampleEvery.OneEvent) .WithThreadPoolSchedulingStats(sampleRate: SampleEvery.OneEvent) .WithThreadPoolStats() .WithGcStats() .StartCollecting(); await RunForcedGcLoop(); }