Table of Contents

Class AiProviderHealthTracker

Namespace
MailFathom.Infrastructure.Observability
Assembly
MailFathom.Infrastructure.dll

Holds what the last call to each AI provider established, and publishes both states as one instrument.

public sealed class AiProviderHealthTracker : IAiProviderHealthRecorder, IAiProviderHealthReader
Inheritance
AiProviderHealthTracker
Implements
Inherited Members

Remarks

One tracker for both roles, with the role as a key rather than as a second class. That is what makes the two states independently observable without being independently implemented: a reader asks for one role and receives that role's answer, and the gauge below carries one measurement per role so a dashboard can show either without the other hiding it.

The gauge reports a number rather than a name, because an instrument's value has to be one. It publishes the state's own enumeration value, whose members are allocated once and never reordered, so a recording rule written against 2 keeps meaning "unavailable" for as long as the series exists.

A transition is logged as well as measured, because a metric answers what the state is now and an operator reading afterwards needs to know when it changed and to what. Only a change is logged: every provider call records, and a line per call would put the log's volume on the mailbox's size rather than on anything an operator would act on. The one change that is not logged is a first call that succeeded, which restores nothing.

Nothing here is mail or derived from it. The only tag is the role, one of two constants, and the only values are a state and the moment it was observed — which is also a cardinality rule, since anything per endpoint or per request would open a time series that grows with the deployment. The log lines carry the same two things and no credential, endpoint address, request, or provider response text.

Constructors

AiProviderHealthTracker(TimeProvider, ILogger<AiProviderHealthTracker>)

Initializes a tracker that has observed nothing yet, and the instrument it publishes through.

Methods

Read(AiProviderRole)

Reads the state of one provider.

RecordMisconfigured(AiProviderRole)

Records that a call failed for a reason no later attempt changes until somebody acts.

RecordServed(AiProviderRole)

Records that a call to the provider produced an answer.

RecordUnavailable(AiProviderRole)

Records that a call failed for a reason a later attempt may not meet.