module Ecluse.Telemetry.Reporters (
DeferredMetrics,
newDeferredMetrics,
installMetrics,
deferredBreakerReporter,
deferredRefreshReporter,
deferredMirrorEnqueueFailure,
breakerStateOf,
) where
import Ecluse.Core.Breaker (Breaker (..), BreakerReporter (..))
import Ecluse.Core.Credential.Refresh (RefreshReporter (..))
import Ecluse.Core.Telemetry.Metrics (
BreakerSource,
BreakerState,
CredentialResult (RefreshFailed, Refreshed),
Provider,
)
import Ecluse.Core.Telemetry.Metrics qualified as Metric
import Ecluse.Telemetry.Instruments (
Metrics,
recordBreakerState,
recordCredentialRefresh,
recordCredentialTokenTtl,
recordMirrorEnqueueFailure,
)
newtype DeferredMetrics = DeferredMetrics (IORef (Maybe Metrics))
newDeferredMetrics :: IO DeferredMetrics
newDeferredMetrics :: IO DeferredMetrics
newDeferredMetrics = IORef (Maybe Metrics) -> DeferredMetrics
DeferredMetrics (IORef (Maybe Metrics) -> DeferredMetrics)
-> IO (IORef (Maybe Metrics)) -> IO DeferredMetrics
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Metrics -> IO (IORef (Maybe Metrics))
forall (m :: * -> *) a. MonadIO m => a -> m (IORef a)
newIORef Maybe Metrics
forall a. Maybe a
Nothing
installMetrics :: DeferredMetrics -> Metrics -> IO ()
installMetrics :: DeferredMetrics -> Metrics -> IO ()
installMetrics (DeferredMetrics IORef (Maybe Metrics)
ref) = IORef (Maybe Metrics) -> Maybe Metrics -> IO ()
forall (m :: * -> *) a. MonadIO m => IORef a -> a -> m ()
writeIORef IORef (Maybe Metrics)
ref (Maybe Metrics -> IO ())
-> (Metrics -> Maybe Metrics) -> Metrics -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Metrics -> Maybe Metrics
forall a. a -> Maybe a
Just
withDeferredMetrics :: DeferredMetrics -> (Metrics -> IO ()) -> IO ()
withDeferredMetrics :: DeferredMetrics -> (Metrics -> IO ()) -> IO ()
withDeferredMetrics (DeferredMetrics IORef (Maybe Metrics)
ref) Metrics -> IO ()
record = IORef (Maybe Metrics) -> IO (Maybe Metrics)
forall (m :: * -> *) a. MonadIO m => IORef a -> m a
readIORef IORef (Maybe Metrics)
ref IO (Maybe Metrics) -> (Maybe Metrics -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= IO () -> (Metrics -> IO ()) -> Maybe Metrics -> IO ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe IO ()
forall (f :: * -> *). Applicative f => f ()
pass Metrics -> IO ()
record
deferredBreakerReporter :: DeferredMetrics -> BreakerSource -> BreakerReporter
deferredBreakerReporter :: DeferredMetrics -> BreakerSource -> BreakerReporter
deferredBreakerReporter DeferredMetrics
deferred BreakerSource
source =
(Breaker -> IO ()) -> BreakerReporter
BreakerReporter ((Breaker -> IO ()) -> BreakerReporter)
-> (Breaker -> IO ()) -> BreakerReporter
forall a b. (a -> b) -> a -> b
$ \Breaker
breaker ->
DeferredMetrics -> (Metrics -> IO ()) -> IO ()
withDeferredMetrics DeferredMetrics
deferred ((Metrics -> IO ()) -> IO ()) -> (Metrics -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Metrics
metrics ->
Metrics -> BreakerSource -> BreakerState -> IO ()
forall (m :: * -> *).
MonadIO m =>
Metrics -> BreakerSource -> BreakerState -> m ()
recordBreakerState Metrics
metrics BreakerSource
source (Breaker -> BreakerState
breakerStateOf Breaker
breaker)
deferredRefreshReporter :: DeferredMetrics -> Provider -> RefreshReporter
deferredRefreshReporter :: DeferredMetrics -> Provider -> RefreshReporter
deferredRefreshReporter DeferredMetrics
deferred Provider
provider =
RefreshReporter
{ onRefreshSucceeded :: Maybe Int -> IO ()
onRefreshSucceeded = CredentialResult -> Maybe Int -> IO ()
report CredentialResult
Refreshed
, onRefreshFailed :: Maybe Int -> IO ()
onRefreshFailed = CredentialResult -> Maybe Int -> IO ()
report CredentialResult
RefreshFailed
}
where
report :: CredentialResult -> Maybe Int -> IO ()
report :: CredentialResult -> Maybe Int -> IO ()
report CredentialResult
result Maybe Int
mTtlSeconds =
DeferredMetrics -> (Metrics -> IO ()) -> IO ()
withDeferredMetrics DeferredMetrics
deferred ((Metrics -> IO ()) -> IO ()) -> (Metrics -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Metrics
metrics -> do
Metrics -> Provider -> CredentialResult -> IO ()
forall (m :: * -> *).
MonadIO m =>
Metrics -> Provider -> CredentialResult -> m ()
recordCredentialRefresh Metrics
metrics Provider
provider CredentialResult
result
Maybe Int -> (Int -> IO ()) -> IO ()
forall (f :: * -> *) a.
Applicative f =>
Maybe a -> (a -> f ()) -> f ()
whenJust Maybe Int
mTtlSeconds (Metrics -> Provider -> Int -> IO ()
forall (m :: * -> *).
MonadIO m =>
Metrics -> Provider -> Int -> m ()
recordCredentialTokenTtl Metrics
metrics Provider
provider)
deferredMirrorEnqueueFailure :: DeferredMetrics -> IO ()
deferredMirrorEnqueueFailure :: DeferredMetrics -> IO ()
deferredMirrorEnqueueFailure DeferredMetrics
deferred =
DeferredMetrics -> (Metrics -> IO ()) -> IO ()
withDeferredMetrics DeferredMetrics
deferred Metrics -> IO ()
forall (m :: * -> *). MonadIO m => Metrics -> m ()
recordMirrorEnqueueFailure
breakerStateOf :: Breaker -> BreakerState
breakerStateOf :: Breaker -> BreakerState
breakerStateOf = \case
Closed{} -> BreakerState
Metric.Closed
Breaker
HalfOpen -> BreakerState
Metric.HalfOpen
Open{} -> BreakerState
Metric.Open