Skip to content

Commit 0096575

Browse files
authored
feat: Add email send operation metrics (#2311)
## What kind of change does this PR introduce? This PR adds two new metrics, `gotrue_email_send_operations_counter_total` and `gotrue_email_send_errors_counter_total`, for tracking email send operations and errors respectively. The purpose of these metrics is to track email delivery independently of the various API handlers that may send email within Auth. ## What is the current behavior? Users who want to track email sending operations in Auth must use indirect metrics like HTTP status codes to determine whether an email was successfully sent. ## What is the new behavior? The `gotrue_email_send_operations_counter_total` counter will increment each time Auth attempts to send an email after performing validation and checking rate limits. The `gotrue_email_send_errors_counter_total` counter will increment each time an email send attempt fails.
1 parent a486ada commit 0096575

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

internal/api/mail.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/supabase/auth/internal/hooks/v0hooks"
1010
mail "github.com/supabase/auth/internal/mailer"
1111
"github.com/supabase/auth/internal/mailer/validateclient"
12+
"github.com/supabase/auth/internal/observability"
1213
"go.opentelemetry.io/otel/attribute"
1314
"go.opentelemetry.io/otel/metric"
1415

@@ -26,6 +27,8 @@ import (
2627

2728
var (
2829
EmailRateLimitExceeded error = errors.New("email rate limit exceeded")
30+
emailSendCounter = observability.ObtainMetricCounter("global_auth_email_send_operations_total", "Number of email send operations")
31+
emailErrorsCounter = observability.ObtainMetricCounter("global_auth_email_send_errors_total", "Number of email send errors")
2932
)
3033

3134
type GenerateLinkParams struct {
@@ -865,6 +868,10 @@ func (a *API) sendEmail(r *http.Request, tx *storage.Connection, u *models.User,
865868
return a.hooksMgr.InvokeHook(tx, r, &input, &output)
866869
}
867870

871+
// Increment email send operations here, since this metric is meant to count number of mail
872+
// send operations rather than simply number of attempts to send mail
873+
emailSendCounter.Add(ctx, 1, metric.WithAttributes(attribute.String("type", params.emailActionType)))
874+
868875
mr := a.Mailer()
869876
var err error
870877
switch params.emailActionType {
@@ -902,10 +909,15 @@ func (a *API) sendEmail(r *http.Request, tx *storage.Connection, u *models.User,
902909
case errors.Is(err, validateclient.ErrInvalidEmailAddress),
903910
errors.Is(err, validateclient.ErrInvalidEmailFormat),
904911
errors.Is(err, validateclient.ErrInvalidEmailDNS):
912+
913+
emailErrorsCounter.Add(ctx, 1, metric.WithAttributes(attribute.String("type", params.emailActionType)))
905914
return apierrors.NewBadRequestError(
906915
apierrors.ErrorCodeEmailAddressInvalid,
907916
"Email address %q is invalid",
908917
u.GetEmail())
918+
case err != nil:
919+
emailErrorsCounter.Add(ctx, 1, metric.WithAttributes(attribute.String("type", params.emailActionType)))
920+
return err
909921
default:
910922
return err
911923
}

0 commit comments

Comments
 (0)