Ho fatto un esperimento e provato in locale sembra funzionare. Mi chiedo se qualcuno vede delle controindicazioni che ad una mia prima analisi non ho visto.
Ho creato un file CS con una classe statica contenente alcune variabili ed i metodi per incrementarle
public static class Metrica
{
private static readonly DateTime _startupUtc = DateTime.UtcNow;
private static readonly long _startupUnix =
DateTimeOffset.UtcNow.ToUnixTimeSeconds();
private static long _totalRequests;
private static long _totalErrors;
public static void IncrementRequests()
{
Interlocked.Increment(ref _totalRequests);
}.....
public static string GetMetricaPrometheus()
{
StringBuilder sb = new StringBuilder();
sb.Append("# HELP app_info Application information\n");
sb.Append("# TYPE app_info gauge\n");
sb.Append("app_info{application=\"testapp\"} 1\n");
sb.Append("# HELP application_start_time_seconds Application start time\n");
sb.Append("# TYPE application_start_time_seconds gauge\n");
sb.Append("application_start_time_seconds " + _startupUnix + "\n");
sb.Append("# HELP application_uptime_seconds Application uptime in seconds\n");
sb.Append("# TYPE application_uptime_seconds gauge\n");
sb.Append("application_uptime_seconds " + UptimeSeconds + "\n");
sb.Append("# HELP requests_total Total requests\n");
sb.Append("# TYPE requests_total counter\n");
sb.Append("requests_total " + TotalRequests + "\n");
sb.Append("# HELP errors_total Total errors\n");
sb.Append("# TYPE errors_total counter\n");
sb.Append("errors_total " + TotalErrors + "\n");
return sb.ToString();
}
questa classe la importo come libreria e richiamo le funzioni di incremento nei metodi che voglio conteggiare login errori .....
e fino a qui credo non ci siano problemi Interlocked.Increment dovrebbe risolvere i problemi di multi concorrenza
poi ho inserito una seconda classe sempre usando il file cs e questa mi da qualche dubbio
public class MetricsHandler : IHttpHandler
{
public void ProcessRequest(HttpContext ctx)
{
ctx.Response.ContentType = "text/plain";
ctx.Response.Write(Metrica.GetMetricaPrometheus());
}
public bool IsReusable
{
get { return false; }
}
}
importo la libreria senza metodi mi basta che finisca nel progetto.
e poi agendo nel web config
<handlers>
<add name="Metrica"
path="metrica"
verb="GET"
type="Metricaprometheus.MetricsHandler" />
</handlers>
questa cosa apre un endpoint richiamabile che risponde con i dati in formato testo.
Ho provato con un applicazione web normale e con un web service ed in entrambi i casi sono riuscito ad avere il secondo endpoint da richiamare per avere i miei contatori in formato prometheus.
Poi è bastato collegare prometheus + grafana per formattare la dashboard con i grafici ...
Ovviamente serve rendere inaccessibili dall'esterno la chiamata cosi come è fatta non richiede autenticazione. Ma al netto di passare o meno un meccanismo di autenticazione il dubbio che ho è che possa rompere qualcosa di inatteso.
Qualcuno ha già provato cose simili ? una soluzione migliore ?