{"id":241,"date":"2024-05-30T09:33:34","date_gmt":"2024-05-30T09:33:34","guid":{"rendered":"https:\/\/dotnetconfig.org\/blog\/?p=241"},"modified":"2024-06-04T09:39:29","modified_gmt":"2024-06-04T09:39:29","slug":"integrating-net-configuration-with-prometheus-for-monitoring","status":"publish","type":"post","link":"https:\/\/dotnetconfig.org\/blog\/integrating-net-configuration-with-prometheus-for-monitoring\/","title":{"rendered":"Integrating .NET Configuration with Prometheus for Monitoring"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-242  alignleft\" src=\"https:\/\/dotnetconfig.org\/blog\/wp-content\/uploads\/2024\/06\/OIG3-2.jpeg\" alt=\".NET Configuration with Prometheus for Monitoring\" width=\"623\" height=\"623\" srcset=\"https:\/\/dotnetconfig.org\/blog\/wp-content\/uploads\/2024\/06\/OIG3-2.jpeg 1024w, https:\/\/dotnetconfig.org\/blog\/wp-content\/uploads\/2024\/06\/OIG3-2-300x300.jpeg 300w, https:\/\/dotnetconfig.org\/blog\/wp-content\/uploads\/2024\/06\/OIG3-2-150x150.jpeg 150w, https:\/\/dotnetconfig.org\/blog\/wp-content\/uploads\/2024\/06\/OIG3-2-768x768.jpeg 768w\" sizes=\"auto, (max-width: 623px) 100vw, 623px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Incorporating robust monitoring and alerting mechanisms into your application is crucial for maintaining optimal performance and responding swiftly to potential issues. Integrating .NET Configuration with Prometheus can provide detailed insights into your application\u2019s performance metrics, configuration changes, and overall health.\u00a0<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2><span style=\"font-weight: 400;\">Setting Up Prometheus Monitoring in .NET<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">First, make sure you have Prometheus installed. You can download the binaries from the official Prometheus website. Extract the downloaded tarball, navigate to the directory, and execute the binary:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">.\/prometheus &#8211;config.file=prometheus.yml<\/span><\/p>\n<p><span style=\"font-weight: 400;\">prometheus.yml is the configuration file where you define how Prometheus scrapes metrics from your endpoints.<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2><span style=\"font-weight: 400;\">Installing Prometheus .NET Libraries<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">To get started with .NET Configuration integration with Prometheus, we will use the prometheus-net library. This library simplifies exposing metrics for Prometheus scraping.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">Add the required Prometheus package to your .NET project using NuGet:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">dotnet add package prometheus-net.AspNetCore<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Middleware Configuration in ASP.NET Core<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Configure the middleware to expose the metrics endpoint. Update your Startup.cs (or Program.cs depending on your .NET version) file:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">using Prometheus;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">public class Startup<\/span><\/p>\n<p><span style=\"font-weight: 400;\">{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0public void ConfigureServices(IServiceCollection services)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Add required services here<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0public void Configure(IApplicationBuilder app, IWebHostEnvironment env)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (env.IsDevelopment())<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0app.UseDeveloperExceptionPage();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Prometheus Metrics Middleware<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0app.UseMetricServer();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0app.UseHttpMetrics();<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0app.UseRouting();<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0app.UseEndpoints(endpoints =&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0endpoints.MapControllers();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">With this, your ASP.NET Core application will expose metrics at the \/metrics endpoint, which Prometheus can scrape.<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2><span style=\"font-weight: 400;\">Monitoring .NET Configuration Changes<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Tracking configuration changes in a .NET application is vital for understanding the state of your application. This can be achieved by monitoring your configuration files (like appsettings.json) and exposing these changes as metrics.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">Firstly, create a service to monitor these configurations:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">public class ConfigurationMonitor<\/span><\/p>\n<p><span style=\"font-weight: 400;\">{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0private readonly IConfiguration _configuration;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0private readonly Gauge _configurationReloads;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0public ConfigurationMonitor(IConfiguration configuration)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0_configuration = configuration;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0_configurationReloads = Metrics.CreateGauge(&#8220;configuration_reload_count&#8221;, &#8220;Counts the number of times the configuration has been reloaded.&#8221;);<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0_configuration.GetReloadToken().RegisterChangeCallback(OnConfigurationReloaded, null);<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0private void OnConfigurationReloaded(object state)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0_configurationReloads.Inc();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Additional logic for handling configuration changes<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">You need to inject this service in Startup.cs:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">public void ConfigureServices(IServiceCollection services)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0services.AddSingleton&lt;ConfigurationMonitor&gt;();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Now, every time your configuration changes, the gauge configuration_reload_count will increment and be available in your Prometheus metrics.<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2><span style=\"font-weight: 400;\">Exposing Performance Metrics<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Performance metrics are critical for gauging the efficiency of your application. Utilize Prometheus to measure aspects like request duration, memory usage, and error rates.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">Request Duration<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Enable both HTTP request metrics and custom metrics:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">public void Configure(IApplicationBuilder app, IWebHostEnvironment env)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0app.UseHttpMetrics(options =&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0options.RequestDuration.Enabled = true; \/\/ Measure request duration<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0options.RequestCount.Enabled = true;\u00a0 \u00a0 \/\/ Measure request count<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0options.ErrorCount.Enabled = true;\u00a0 \u00a0 \u00a0 \/\/ Measure error counts<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0});<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\/\/ Other middleware<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0app.UseMetricServer();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0app.UseRouting();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0app.UseEndpoints(endpoints =&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0endpoints.MapControllers();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0});<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Prometheus will now automatically collect metrics about request durations, counts, and errors from your application.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">Custom Metrics<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For more specific performance metrics, creating custom counters, gauges, or histograms may be necessary:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">public class PerformanceMetricsService<\/span><\/p>\n<p><span style=\"font-weight: 400;\">{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0private readonly Counter _requestCounter;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0public PerformanceMetricsService()<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Custom metric for counting specific requests<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0_requestCounter = Metrics.CreateCounter(&#8220;custom_request_count&#8221;, &#8220;Counts specific requests&#8221;);<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0public void RecordRequest()<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0_requestCounter.Inc();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Inject and utilize this service in your controllers as required:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">[ApiController]<\/span><\/p>\n<p><span style=\"font-weight: 400;\">[Route(&#8220;api\/[controller]&#8221;)]<\/span><\/p>\n<p><span style=\"font-weight: 400;\">public class SampleController : ControllerBase<\/span><\/p>\n<p><span style=\"font-weight: 400;\">{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0private readonly PerformanceMetricsService _metricsService;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0public SampleController(PerformanceMetricsService metricsService)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0_metricsService = metricsService;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0[HttpGet]<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0public IActionResult Get()<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0_metricsService.RecordRequest();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return Ok(&#8220;Request successfully recorded.&#8221;);<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Application Health Monitoring<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Application health is crucial for ensuring your services are running correctly. Prometheus and ASP.NET Core\u2019s Health Checks integration can be leveraged to provide proactive monitoring.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">Adding Health Checks<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Start by adding the health checks services in your Startup.cs:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">public void ConfigureServices(IServiceCollection services)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0services.AddHealthChecks()<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.AddCheck(&#8220;self&#8221;, () =&gt; HealthCheckResult.Healthy());<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Next, expose the health endpoint:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">public void Configure(IApplicationBuilder app, IWebHostEnvironment env)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0app.UseRouting();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0app.UseEndpoints(endpoints =&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0endpoints.MapHealthChecks(&#8220;\/healthz&#8221;);<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0endpoints.MapControllers();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0});<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Prometheus Health Check Integration<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Integrate Prometheus to monitor these health check endpoints. In prometheus.yml, add your application\u2019s health check endpoint to the scrape configuration:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">scrape_configs:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0&#8211; job_name: &#8216;your-app-health&#8217;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0metrics_path: &#8216;\/healthz&#8217;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0static_configs:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8211; targets: [&#8216;localhost:5000&#8217;] # Replace with your application&#8217;s address<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Alerting on Configuration and Performance Metrics<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">To enable alerting based on these metrics, you need to configure Prometheus&#8217; Alertmanager.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">Create alert rules in the prometheus.yml:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">rule_files:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0&#8211; &#8216;alert.rules.yml&#8217;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">scrape_configs:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0&#8211; job_name: &#8216;your-app&#8217;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0static_configs:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8211; targets: [&#8216;localhost:5000&#8217;]<\/span><\/p>\n<p><span style=\"font-weight: 400;\">An example of alert.rules.yml:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">groups:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0&#8211; name: example<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0rules:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8211; alert: HighRequestLatency<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0expr: http_request_duration_seconds_bucket{job=&#8221;your-app&#8221;} &gt; 0.5<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0for: 5m<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0labels:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0severity: warning<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0annotations:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0summary: &#8220;High request latency detected in {{ $labels.instance }}&#8221;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0description: &#8220;Request latency is above 0.5 seconds for more than 5 minutes.&#8221;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8211; alert: ConfigurationChanged<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0expr: configuration_reload_count &gt; 10<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0for: 1m<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0labels:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0severity: info<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0annotations:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0summary: &#8220;Frequent configuration reloads&#8221;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0description: &#8220;Configuration has been reloaded more than 10 times in the past minute.&#8221;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Configure the Alertmanager to handle these alerts by specifying the route and receivers in alertmanager.yml:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">route:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0group_by: [&#8216;alertname&#8217;]<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0receiver: &#8216;webhook&#8217;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">receivers:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0&#8211; name: &#8216;webhook&#8217;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0webhook_configs:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8211; url: &#8216;http:\/\/example.com\/alert&#8217;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Make sure to point Prometheus to your Alertmanager instance:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">alerting:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0alertmanagers:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0&#8211; static_configs:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0&#8211; targets:\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8211; localhost:9093<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Combining .NET Configuration with Prometheus monitoring provides comprehensive insights into your application\u2019s health, performance metrics, and configuration changes. Implement the above steps to ensure systematic monitoring and alerting, allowing you to maintain efficient operations and preemptively address potential issues.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Incorporating robust monitoring and alerting mechanisms into your application is crucial for maintaining optimal performance and responding swiftly to potential issues. Integrating .NET Configuration with Prometheus can provide detailed insights into your application\u2019s performance metrics, configuration changes, and overall health.\u00a0 &nbsp; Setting Up Prometheus Monitoring in .NET First, make sure you have Prometheus installed. You [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-241","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/dotnetconfig.org\/blog\/wp-json\/wp\/v2\/posts\/241","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dotnetconfig.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dotnetconfig.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dotnetconfig.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dotnetconfig.org\/blog\/wp-json\/wp\/v2\/comments?post=241"}],"version-history":[{"count":2,"href":"https:\/\/dotnetconfig.org\/blog\/wp-json\/wp\/v2\/posts\/241\/revisions"}],"predecessor-version":[{"id":244,"href":"https:\/\/dotnetconfig.org\/blog\/wp-json\/wp\/v2\/posts\/241\/revisions\/244"}],"wp:attachment":[{"href":"https:\/\/dotnetconfig.org\/blog\/wp-json\/wp\/v2\/media?parent=241"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dotnetconfig.org\/blog\/wp-json\/wp\/v2\/categories?post=241"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dotnetconfig.org\/blog\/wp-json\/wp\/v2\/tags?post=241"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}