ASP.NET Core Middleware Response Formatters
App Metric's Middleware supports pluggable formatters which provide the ability to serialize metric and health check data depending on your requirements. This allows the Metrics
and Health
endpoints Content-Types
to be customized.
By allowing for example the /metrics
endpoint to return metrics in a TSDB specific format, it enables a pull based collection approach rather than push via a reporter.
Similar formatting options can also be used with the Text File Reporter
if using a collection agent to flush metrics or the HTTP Reporter
to push metrics in the required format to a custom HTTP collection endpoint.
Available Formatters
Implementing a Custom Formatter
Other than the custom serialization code, to wire up a custom formatter to plugin to App Metrics you just need to implement a couple of interfaces, IHealthResponseWriter
if required, and IMetricsResponseWriter
.
As a guide, we can look at how to implement a custom JSON formatter:
Note
For brevity, the code snippets don't include the serialization code, just the required infrastructure code to plug the formatter into App Metrics Middleware.
Implement the IMetricsResponseWriter
interface.
public class CustomJsonMetricsResponseWriter : IMetricsResponseWriter
{
private readonly IMetricDataSerializer _serializer;
public CustomJsonMetricsResponseWriter(IMetricDataSerializer serializer)
{
_serializer = serializer ?? throw new ArgumentNullException(nameof(serializer));
}
public string ContentType => "application/vnd.app.metrics.v1.custom.metrics+json";
public Task WriteAsync(HttpContext context, MetricsDataValueSource metricsData, CancellationToken token = default(CancellationToken))
{
var json = _serializer.Serialize(metricsData);
return context.Response.WriteAsync(json, token);
}
}
Implement the IHealthResponseWriter
interface.
public class CustomJsonHealthResponseWriter : IHealthResponseWriter
{
private readonly IHealthStatusSerializer _serializer;
public CustomJsonHealthResponseWriter(IHealthStatusSerializer serializer)
{
_serializer = serializer ?? throw new ArgumentNullException(nameof(serializer));
}
public string ContentType => "application/vnd.app.metrics.v1.custom.health+json";
public Task WriteAsync(HttpContext context, HealthStatus healthStatus, CancellationToken token = default(CancellationToken))
{
var json = _serializer.Serialize(healthStatus);
return context.Response.WriteAsync(json, token);
}
}
Exposing the formatter to the App Metrics configuration API
Add extensions methods on IMetricsHostBuilder
making is easy for users to configure the formatter.
public static class MetricsHostExtensions
{
public static IMetricsHostBuilder AddCustomJsonHealthSerialization(this IMetricsHostBuilder host)
{
host.Services.Replace(ServiceDescriptor.Transient<IHealthResponseWriter, JsonHealthResponseWriter>());
host.Services.Replace(ServiceDescriptor.Transient<IHealthStatusSerializer, HealthStatusSerializer>());
return host;
}
public static IMetricsHostBuilder AddCustomJsonMetricsSerialization(this IMetricsHostBuilder host)
{
host.Services.Replace(ServiceDescriptor.Transient<IMetricsResponseWriter, JsonMetricsResponseWriter>());
host.Services.Replace(ServiceDescriptor.Transient<IMetricDataSerializer, MetricDataSerializer>());
return host;
}
public static IMetricsHostBuilder AddCustomJsonSerialization(this IMetricsHostBuilder host)
{
host.AddJsonHealthSerialization();
host.AddJsonMetricsSerialization();
return host;
}
}
Tip
Implementing a custom metrics text or environment information formatter is the same as above but instead implement the IMetricsTextResponseWriter
or IEnvironmentInfoResponseWriter
interfaces.
Using the Formatter
Modify the application's Startup.cs
to looking like the following:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMetrics()
.AddCustomJsonSerialization()
.AddHealthChecks()
.AddMetricsMiddleware();
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
app.UseMetrics();
}
}
Tip
In the IMetricsHostBuilder
extension method code snippet, you'll notice two additional extension methods, AddCustomJsonMetricsSerialization
and AddCustomJsonHealthSerialization
.
This is useful for applications which want to format health checks differently to metrics for example, such applications can then have a dependency on mulitple formatter packages.