feat(backend): start work on metrics

This commit is contained in:
sam 2024-07-13 17:23:52 +02:00
parent fa49030b06
commit 16f230b97d
Signed by: sam
GPG key ID: B4EF20DDE721CAA1
6 changed files with 53 additions and 4 deletions

View file

@ -10,6 +10,7 @@ public class Config
public string MediaBaseUrl { get; set; } = null!;
public string Address => $"http://{Host}:{Port}";
public string? MetricsAddress => Logging.MetricsPort != null ? $"http://{Host}:{Logging.MetricsPort}" : null;
public LoggingConfig Logging { get; init; } = new();
public DatabaseConfig Database { get; init; } = new();
@ -27,6 +28,7 @@ public class Config
public bool SentryTracing { get; init; } = false;
public double SentryTracesSampleRate { get; init; } = 0.0;
public bool LogQueries { get; init; } = false;
public int? MetricsPort { get; init; }
}
public class DatabaseConfig

View file

@ -1,3 +1,6 @@
using App.Metrics;
using App.Metrics.AspNetCore;
using App.Metrics.Formatters.Prometheus;
using Foxnouns.Backend.Database;
using Foxnouns.Backend.Jobs;
using Foxnouns.Backend.Middleware;
@ -6,6 +9,7 @@ using Microsoft.EntityFrameworkCore;
using NodaTime;
using Serilog;
using Serilog.Events;
using IClock = NodaTime.IClock;
namespace Foxnouns.Backend.Extensions;
@ -29,6 +33,7 @@ public static class WebApplicationExtensions
.MinimumLevel.Override("Microsoft.AspNetCore.Hosting", LogEventLevel.Warning)
.MinimumLevel.Override("Microsoft.AspNetCore.Mvc", LogEventLevel.Warning)
.MinimumLevel.Override("Microsoft.AspNetCore.Routing", LogEventLevel.Warning)
.MinimumLevel.Override("Hangfire", LogEventLevel.Information)
.WriteTo.Console();
if (config.Logging.SeqLogUrl != null)
@ -52,6 +57,36 @@ public static class WebApplicationExtensions
return config;
}
public static WebApplicationBuilder AddMetrics(this WebApplicationBuilder builder)
{
var config = builder.Configuration.Get<Config>() ?? new();
var metrics = AppMetrics.CreateDefaultBuilder()
.OutputMetrics.AsPrometheusPlainText()
.Build();
builder.Services.AddSingleton(metrics);
builder.Services.AddSingleton<IMetrics>(metrics);
builder.WebHost
.ConfigureMetrics(metrics)
.UseMetrics(opts =>
{
opts.EndpointOptions = options =>
{
// Metrics must listen on a separate port for security reasons. If no metrics port is set, disable the endpoint entirely.
options.MetricsEndpointEnabled = config.Logging.MetricsPort != null;
options.EnvironmentInfoEndpointEnabled = config.Logging.MetricsPort != null;
options.MetricsTextEndpointEnabled = false;
options.MetricsEndpointOutputFormatter = metrics.OutputMetricsFormatters
.OfType<MetricsPrometheusTextOutputFormatter>().First();
};
})
.UseMetricsWebTracking()
.ConfigureAppMetricsHostingConfiguration(opts => { opts.AllEndpointsPort = config.Logging.MetricsPort; });
return builder;
}
public static IConfigurationBuilder AddConfiguration(this IConfigurationBuilder builder)
{
var file = Environment.GetEnvironmentVariable("FOXNOUNS_CONFIG_FILE") ?? "config.ini";

View file

@ -6,6 +6,9 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="App.Metrics" Version="4.3.0" />
<PackageReference Include="App.Metrics.AspNetCore.All" Version="4.3.0" />
<PackageReference Include="App.Metrics.Prometheus" Version="4.3.0" />
<PackageReference Include="EFCore.NamingConventions" Version="8.0.3"/>
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.14" />
<PackageReference Include="Hangfire.Core" Version="1.8.14" />

View file

@ -0,0 +1,6 @@
namespace Foxnouns.Backend;
public static class Metrics
{
}

View file

@ -21,7 +21,7 @@ var builder = WebApplication.CreateBuilder(args);
var config = builder.AddConfiguration();
builder.AddSerilog();
builder.AddSerilog().AddMetrics();
builder.WebHost
.UseSentry(opts =>
@ -75,9 +75,9 @@ builder.Services
.Build());
builder.Services.AddHangfire(c => c.UseSentry().UseRedisStorage(config.Jobs.Redis, new RedisStorageOptions
{
Prefix = "foxnouns_"
}))
{
Prefix = "foxnouns_"
}))
.AddHangfireServer(options => { options.WorkerCount = config.Jobs.Workers; });
var app = builder.Build();
@ -103,6 +103,7 @@ app.UseHangfireDashboard("/hangfire", new DashboardOptions
app.Urls.Clear();
app.Urls.Add(config.Address);
if (config.MetricsAddress != null) app.Urls.Add(config.MetricsAddress);
// Fire off the periodic tasks loop in the background
_ = new Timer(_ =>

View file

@ -20,6 +20,8 @@ SentryTracing = true
SentryTracesSampleRate = 1.0
; Whether to log SQL queries. Note that this is very verbose. Defaults to false.
LogQueries = false
; The port the /metrics endpoint will listen on. If not set, metrics will be disabled.
MetricsPort = 5001
[Database]
; The database URL in ADO.NET format.