Added metrics to Webhook API (total events, errors)
This commit is contained in:
parent
a83fdbbe7a
commit
a64e16f681
|
@ -4,16 +4,19 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Wave.Data;
|
||||
using Wave.Data.Api.Mailtrap;
|
||||
using Wave.Utilities.Metrics;
|
||||
|
||||
namespace Wave.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("/api/[controller]")]
|
||||
public class WebhookController(ILogger<WebhookController> logger, ApplicationDbContext context) : ControllerBase {
|
||||
public class WebhookController(ILogger<WebhookController> logger, ApplicationDbContext context, ApiMetrics metrics)
|
||||
: ControllerBase {
|
||||
[HttpPost("mailtrap/{apiKey}")]
|
||||
[Authorize("EmailApi", AuthenticationSchemes = "ApiKeyInRoute")]
|
||||
public async Task<IActionResult> Mailtrap(Webhook webhook, string apiKey) {
|
||||
foreach (var webhookEvent in webhook.Events) {
|
||||
metrics.WebhookEventReceived("Mailtrap", webhookEvent.Type.ToString());
|
||||
var subscriber = await context.Set<EmailSubscriber>().FirstOrDefaultAsync(s => s.Email == webhookEvent.Email);
|
||||
|
||||
logger.LogDebug("Received Webhook event {EventType} for {email}",
|
||||
|
@ -24,6 +27,7 @@ public class WebhookController(ILogger<WebhookController> logger, ApplicationDbC
|
|||
"Received webhook event from mailtrap of type {EventType}, " +
|
||||
"but failed to find subscriber with E-Mail {email}.",
|
||||
webhookEvent.Type, webhookEvent.Email);
|
||||
metrics.WebhookEventError("Mailtrap", webhookEvent.Type.ToString(), "unknown email");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -59,6 +63,7 @@ public class WebhookController(ILogger<WebhookController> logger, ApplicationDbC
|
|||
case WebhookEventType.Click:
|
||||
default:
|
||||
logger.LogInformation("Received unsupported event {EventType} for {email}. Skipping.", webhookEvent.Type, webhookEvent.Email);
|
||||
metrics.WebhookEventError("Mailtrap", webhookEvent.Type.ToString(), "unknown type");
|
||||
return Ok();
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
using Serilog;
|
||||
using Serilog.Events;
|
||||
using Serilog.Sinks.Grafana.Loki;
|
||||
using Wave.Utilities.Metrics;
|
||||
|
||||
#region Version Information
|
||||
|
||||
|
@ -275,7 +276,7 @@
|
|||
|
||||
#endregion
|
||||
|
||||
#region Open Telemetry
|
||||
#region Open Telemetry & Metrics
|
||||
|
||||
var features = builder.Configuration.GetSection(nameof(Features)).Get<Features>();
|
||||
if (features?.Telemetry is true) {
|
||||
|
@ -292,7 +293,7 @@
|
|||
.AddMeter("Microsoft.AspNetCore.Http.Connections")
|
||||
.AddMeter("Microsoft.AspNetCore.Http.Routing")
|
||||
.AddMeter("Microsoft.AspNetCore.Diagnostics")
|
||||
|
||||
.AddMeter("Wave.Api")
|
||||
.AddPrometheusExporter());
|
||||
|
||||
// Jaeger etc.
|
||||
|
@ -303,6 +304,8 @@
|
|||
tracing.AddOtlpExporter(options => options.Endpoint = new Uri(otlpUrl));
|
||||
});
|
||||
}
|
||||
|
||||
builder.Services.AddSingleton<ApiMetrics>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
30
Wave/Utilities/Metrics/ApiMetrics.cs
Normal file
30
Wave/Utilities/Metrics/ApiMetrics.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
using System.Diagnostics.Metrics;
|
||||
|
||||
namespace Wave.Utilities.Metrics;
|
||||
|
||||
public class ApiMetrics {
|
||||
private Counter<int> WebhookEventCounter { get; }
|
||||
private Counter<int> WebhookErrorCounter { get; }
|
||||
|
||||
public ApiMetrics(IMeterFactory meterFactory) {
|
||||
var meter = meterFactory.Create("Wave.Api");
|
||||
|
||||
WebhookEventCounter = meter.CreateCounter<int>("wave.webhook.events", "{events}",
|
||||
description: "Counts the incoming webhook events");
|
||||
WebhookErrorCounter = meter.CreateCounter<int>("wave.webhook.errors", "{events}",
|
||||
description: "Counts errors in webhook events");
|
||||
}
|
||||
|
||||
public void WebhookEventReceived(string api, string type) {
|
||||
WebhookEventCounter.Add(1,
|
||||
new KeyValuePair<string, object?>("wave.webhook.event_type", type),
|
||||
new KeyValuePair<string, object?>("wave.webhook.api", api));
|
||||
}
|
||||
|
||||
public void WebhookEventError(string api, string type, string reason) {
|
||||
WebhookErrorCounter.Add(1,
|
||||
new KeyValuePair<string, object?>("wave.webhook.event_type", type),
|
||||
new KeyValuePair<string, object?>("wave.webhook.api", api),
|
||||
new KeyValuePair<string, object?>("wave.error.reason", reason));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue