Reputation: 842
How can I use prometheus-net in a regular ASP.NET 4.7.1 application ? In .Net Core is quite easy, but I cannot find a nice way of reporting the metrics to Grafana in 4.7.1
The ideal would be to have path /metrics
where the metrics are reported.
I tried to create a rough test controller to run the MetricServer
but I get an error.
// horrible test code
[RoutePrefix("metrics")]
public class MetricsController : ApiController
{
static readonly MetricServer _server = new MetricServer(7777);
static MetricsController()
{
_server.Start();
}
[Route("")]
public async Task<IHttpActionResult> Get()
{
using (var client = new HttpClient())
{
var metrics = await client.GetAsync("http://localhost:7777/metrics");
return Content(HttpStatusCode.OK, await metrics.Content.ReadAsStringAsync(),null, metrics.Content.Headers.ContentType.ToString());
}
}
}
System.Net.HttpListenerException: 'Access is denied'
Upvotes: 7
Views: 9407
Reputation: 6261
With ASP.NET Framework, you can also create a stand-alone HttpHandler
to provide your metrics endpoint.
First create the handler (typically store in App_Code
directory):
/// <summary>
/// Prometheus metrics scraping endpoint.
/// </summary>
public class MetricsHandler : HttpTaskAsyncHandler
{
public override async Task ProcessRequestAsync(HttpContext context)
{
// Uses pattern from Prometheus.MetricServer
var response = context.Response;
try
{
try
{
await Metrics.DefaultRegistry.CollectAndExportAsTextAsync(context.Response.OutputStream);
}
catch (ScrapeFailedException ex)
{
response.StatusCode = 503;
if (!string.IsNullOrWhiteSpace(ex.Message))
{
using (var streamWriter = new StreamWriter(response.OutputStream))
{
streamWriter.Write(ex.Message);
}
}
}
}
catch (Exception ex)
{
if (!(ex is OperationCanceledException))
{
try
{
response.StatusCode = 500;
}
catch
{
}
}
}
}
}
Then register your handler in web.config
:
<system.webServer>
<handlers>
<add name="MetricsHandler" verb="*" path="metrics" type="<your-namespace>.MetricsHandler, <your-assembly-name>" resourceType="Unspecified" />
</handlers>
</system.webServer>
To get my handler code I looked at the Prometheus MetricServer
implementation, combined with Rocklan's answer.
Upvotes: 1
Reputation: 8130
There is another way to do this. Instead of creating a new MetricServer
at startup and calling it, you can just collect the metrics yourself by calling CollectAndExportAsTextAsync
.
Just create a WebApi controller that looks something like this:
public class MetricsController : ApiController
{
[Route("metrics")]
[HttpGet]
public async Task<HttpResponseMessage> AppMetrics()
{
using (MemoryStream ms = new MemoryStream())
{
await Metrics.DefaultRegistry.CollectAndExportAsTextAsync(ms);
ms.Position = 0;
using (StreamReader sr = new StreamReader(ms))
{
var allmetrics = await sr.ReadToEndAsync();
return new HttpResponseMessage()
{
Content = new StringContent(allmetrics, Encoding.UTF8, "text/plain")
};
}
}
}
}
Or you can just use my NuGet package that also gives you HTTP metrics and some SQL ones too - https://www.nuget.org/packages/prometheus-net.AspNet/
Upvotes: 6
Reputation: 635
MetricServer.Start()
may throw an access denied exception on Windows if your user does not have the right to open a web server on the specified port. You can use the netsh command to grant yourself the required permissions:
netsh http add urlacl url=http://+:7777/metrics user=DOMAIN\user
Upvotes: 3