-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Some curated and opinionated packages for building Haskell services. -- -- A library of curated and opinionated packages for building Haskell -- serivces, with some preferred pattern. Services expose metrics using -- prometheus and log events via contravariant logging. @package prodapi @version 0.1.0.0 module Paths_prodapi version :: Version getBinDir :: IO FilePath getLibDir :: IO FilePath getDynLibDir :: IO FilePath getDataDir :: IO FilePath getLibexecDir :: IO FilePath getDataFileName :: FilePath -> IO FilePath getSysconfDir :: IO FilePath module Prod.Echo type EchoApi (segment :: Symbol) a = Summary "returns the input" :> "echo" :> segment :> ReqBody '[JSON] a :> Post '[JSON] a handleEcho :: (FromJSON a, ToJSON a) => a -> Handler a module Prod.MimeTypes data HTML data PNG data SVG data GraphPictureData GraphPictureData :: !ByteString -> IO ByteString -> IO ByteString -> GraphPictureData [graphvizInput] :: GraphPictureData -> !ByteString [serializedPng] :: GraphPictureData -> IO ByteString [serializedSvg] :: GraphPictureData -> IO ByteString instance Servant.API.ContentTypes.MimeRender Prod.MimeTypes.PNG Prod.MimeTypes.GraphPictureData instance Servant.API.ContentTypes.MimeRender Servant.API.ContentTypes.PlainText Prod.MimeTypes.GraphPictureData instance Servant.API.ContentTypes.MimeRender Prod.MimeTypes.SVG Prod.MimeTypes.GraphPictureData instance Servant.API.ContentTypes.Accept Prod.MimeTypes.SVG instance Servant.API.ContentTypes.Accept Prod.MimeTypes.PNG instance Servant.API.ContentTypes.Accept Prod.MimeTypes.HTML module Prod.Prometheus handlePrometheus :: CORSAllowOrigin -> Server PrometheusApi type PrometheusApi = Summary "Prometheus metrics" :> "metrics" :> Get '[PlainText] (Headers '[Header "Access-Control-Allow-Origin" CORSAllowOrigin] PrometheusResult) newtype CORSAllowOrigin CORSAllowOrigin :: Text -> CORSAllowOrigin newtype PrometheusResult PrometheusResult :: ByteString -> PrometheusResult [toLBS] :: PrometheusResult -> ByteString initPrometheus :: IO GHCMetrics inc :: MonadIO m => (a -> Vector Text Counter) -> Text -> a -> m () obs :: MonadIO m => (a -> Summary) -> Double -> a -> m () timeIt :: MonadIO m => (a -> Summary) -> a -> m b -> m b instance Web.Internal.HttpApiData.ToHttpApiData Prod.Prometheus.CORSAllowOrigin instance Servant.API.ContentTypes.MimeRender Servant.API.ContentTypes.PlainText Prod.Prometheus.PrometheusResult module Prod.Tracer newtype Tracer m a Tracer :: (a -> m ()) -> Tracer m a [runTracer] :: Tracer m a -> a -> m () -- | Disable Tracing. silent :: Applicative m => Tracer m a -- | Filter by dynamically testing values. traceIf :: Applicative m => (a -> Bool) -> Tracer m a -> Tracer m a -- | If you are given two tracers and want to pass both. Composition occurs -- in sequence. traceBoth :: Applicative m => Tracer m a -> Tracer m a -> Tracer m a -- | A tracer that prints emitted events. tracePrint :: (MonadIO m, Show a) => Tracer m a -- | A tracer that prints emitted to some handle. traceHPrint :: (MonadIO m, Show a) => Handle -> Tracer m a -- | A tracer that puts some ByteString to some handle. traceHPut :: MonadIO m => Handle -> Tracer m ByteString -- | A conversion encoding values to JSON. encodeJSON :: ToJSON a => Tracer m ByteString -> Tracer m a -- | Pulls a value to complete a trace when a trace occurs. -- -- This function allows to combines pushed values with pulled values. -- Hence, performing some scheduling between behaviours. Typical usage -- would be to annotate a trace with a background value, or perform data -- augmentation in a pipelines of traces. -- -- Note that if you rely on this function you need to pay attention of -- the blocking effect of pulls: the traced value c is not -- forwarded until a value b is available. pulls :: Monad m => (c -> m b) -> Tracer m b -> Tracer m c -- | The class of contravariant functors. -- -- Whereas in Haskell, one can think of a Functor as containing or -- producing values, a contravariant functor is a functor that can be -- thought of as consuming values. -- -- As an example, consider the type of predicate functions a -> -- Bool. One such predicate might be negative x = x < 0, -- which classifies integers as to whether they are negative. However, -- given this predicate, we can re-use it in other situations, providing -- we have a way to map values to integers. For instance, we can -- use the negative predicate on a person's bank balance to work -- out if they are currently overdrawn: -- --
--   newtype Predicate a = Predicate { getPredicate :: a -> Bool }
--   
--   instance Contravariant Predicate where
--     contramap :: (a' -> a) -> (Predicate a -> Predicate a')
--     contramap f (Predicate p) = Predicate (p . f)
--                                            |   `- First, map the input...
--                                            `----- then apply the predicate.
--   
--   overdrawn :: Predicate Person
--   overdrawn = contramap personBankBalance negative
--   
-- -- Any instance should be subject to the following laws: -- -- -- -- Note, that the second law follows from the free theorem of the type of -- contramap and the first law, so you need only check that the -- former condition holds. class () => Contravariant (f :: Type -> Type) contramap :: Contravariant f => (a' -> a) -> f a -> f a' -- | Replace all locations in the output with the same value. The default -- definition is contramap . const, but this may -- be overridden with a more efficient version. (>$) :: Contravariant f => b -> f b -> f a infixl 4 >$ -- | A Divisible contravariant functor is the contravariant analogue -- of Applicative. -- -- Continuing the intuition that Contravariant functors consume -- input, a Divisible contravariant functor also has the ability -- to be composed "beside" another contravariant functor. -- -- Serializers provide a good example of Divisible contravariant -- functors. To begin let's start with the type of serializers for -- specific types: -- --
--   newtype Serializer a = Serializer { runSerializer :: a -> ByteString }
--   
-- -- This is a contravariant functor: -- --
--   instance Contravariant Serializer where
--     contramap f s = Serializer (runSerializer s . f)
--   
-- -- That is, given a serializer for a (s :: Serializer -- a), and a way to turn bs into as (a mapping -- f :: b -> a), we have a serializer for b: -- contramap f s :: Serializer b. -- -- Divisible gives us a way to combine two serializers that focus on -- different parts of a structure. If we postulate the existance of two -- primitive serializers - string :: Serializer String and -- int :: Serializer Int, we would like to be able to combine -- these into a serializer for pairs of Strings and -- Ints. How can we do this? Simply run both serializers and -- combine their output! -- --
--   data StringAndInt = StringAndInt String Int
--   
--   stringAndInt :: Serializer StringAndInt
--   stringAndInt = Serializer $ \(StringAndInt s i) ->
--     let sBytes = runSerializer string s
--         iBytes = runSerializer int i
--     in sBytes <> iBytes
--   
-- -- divide is a generalization by also taking a contramap -- like function to split any a into a pair. This conveniently -- allows you to target fields of a record, for instance, by extracting -- the values under two fields and combining them into a tuple. -- -- To complete the example, here is how to write stringAndInt -- using a Divisible instance: -- --
--   instance Divisible Serializer where
--     conquer = Serializer (const mempty)
--   
--     divide toBC bSerializer cSerializer = Serializer $ \a ->
--       case toBC a of
--         (b, c) ->
--           let bBytes = runSerializer bSerializer b
--               cBytes = runSerializer cSerializer c
--           in bBytes <> cBytes
--   
--   stringAndInt :: Serializer StringAndInt
--   stringAndInt =
--     divide (\(StringAndInt s i) -> (s, i)) string int
--   
class Contravariant f => Divisible (f :: Type -> Type) divide :: Divisible f => (a -> (b, c)) -> f b -> f c -> f a -- | Conquer acts as an identity for combining Divisible functors. conquer :: Divisible f => f a -- | A Decidable contravariant functor is the contravariant analogue -- of Alternative. -- -- Noting the superclass constraint that f must also be -- Divisible, a Decidable functor has the ability to "fan -- out" input, under the intuition that contravariant functors consume -- input. -- -- In the discussion for Divisible, an example was demonstrated -- with Serializers, that turn as into -- ByteStrings. Divisible allowed us to serialize the -- product of multiple values by concatenation. By making our -- Serializer also Decidable- we now have the ability -- to serialize the sum of multiple values - for example different -- constructors in an ADT. -- -- Consider serializing arbitrary identifiers that can be either -- Strings or Ints: -- --
--   data Identifier = StringId String | IntId Int
--   
-- -- We know we have serializers for Strings and Ints, -- but how do we combine them into a Serializer for -- Identifier? Essentially, our Serializer needs to -- scrutinise the incoming value and choose how to serialize it: -- --
--   identifier :: Serializer Identifier
--   identifier = Serializer $ \identifier ->
--     case identifier of
--       StringId s -> runSerializer string s
--       IntId i -> runSerializer int i
--   
-- -- It is exactly this notion of choice that Decidable encodes. -- Hence if we add an instance of Decidable for -- Serializer... -- --
--   instance Decidable Serializer where
--     lose f = Serializer $ \a -> absurd (f a)
--     choose split l r = Serializer $ \a ->
--       either (runSerializer l) (runSerializer r) (split a)
--   
-- -- Then our identifier Serializer is -- --
--   identifier :: Serializer Identifier
--   identifier = choose toEither string int where
--     toEither (StringId s) = Left s
--     toEither (IntId i) = Right i
--   
class Divisible f => Decidable (f :: Type -> Type) -- | Acts as identity to choose. lose :: Decidable f => (a -> Void) -> f a choose :: Decidable f => (a -> Either b c) -> f b -> f c -> f a instance Data.Functor.Contravariant.Contravariant (Prod.Tracer.Tracer m) instance GHC.Base.Applicative m => Data.Functor.Contravariant.Divisible.Divisible (Prod.Tracer.Tracer m) instance GHC.Base.Applicative m => Data.Functor.Contravariant.Divisible.Decidable (Prod.Tracer.Tracer m) module Prod.Reports type ReportsApi a = Summary "receives and acknowledge some reports" :> "reports" :> ReqBody '[JSON] (Report a) :> Post '[JSON] Int -- | Some minimal report wrapper. Has low expectations on the client. data Report a Report :: Int -> Int -> [a] -> Report a [posixTime] :: Report a -> Int [backoff] :: Report a -> Int [events] :: Report a -> [a] -- | Count and drop reports. countReports :: Runtime a -> Report a -> Handler Int -- | A default runtime for the dropReports route. data Runtime a initRuntime :: Tracer IO (Report a) -> IO (Runtime a) instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Prod.Reports.Report a) instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Prod.Reports.Report a) module Prod.Health type HealthApi = GetLivenessApi :<|> GetReadinessApi :<|> DrainApi type GetReadinessApi = Summary "Health readiness probe." :> "health" :> "ready" :> Get '[JSON] Readiness handleHealth :: Runtime -> Server HealthApi data Liveness Alive :: Liveness newtype Reason Reason :: Text -> Reason data Readiness Ready :: Readiness Ill :: Set Reason -> Readiness completeReadiness :: Runtime -> IO Readiness data Runtime Runtime :: IO Liveness -> IO Readiness -> IORef (Set Reason) -> Tracer IO Track -> Runtime [liveness] :: Runtime -> IO Liveness [readiness] :: Runtime -> IO Readiness [conditions] :: Runtime -> IORef (Set Reason) [tracer] :: Runtime -> Tracer IO Track alwaysReadyRuntime :: Tracer IO Track -> IO Runtime withLiveness :: IO Liveness -> Runtime -> Runtime withReadiness :: IO Readiness -> Runtime -> Runtime data Track Afflict :: CallStack -> Reason -> Track Cure :: CallStack -> Reason -> Track instance Data.Aeson.Types.FromJSON.FromJSON Prod.Health.Reason instance Data.Aeson.Types.ToJSON.ToJSON Prod.Health.Reason instance GHC.Show.Show Prod.Health.Reason instance GHC.Classes.Ord Prod.Health.Reason instance GHC.Classes.Eq Prod.Health.Reason instance GHC.Generics.Generic Prod.Health.Readiness instance GHC.Show.Show Prod.Health.Readiness instance GHC.Classes.Ord Prod.Health.Readiness instance GHC.Classes.Eq Prod.Health.Readiness instance GHC.Show.Show Prod.Health.Track instance Data.Aeson.Types.ToJSON.ToJSON Prod.Health.Readiness instance Data.Aeson.Types.FromJSON.FromJSON Prod.Health.Readiness instance Data.Aeson.Types.ToJSON.ToJSON Prod.Health.Liveness module Prod.Status type StatusApi a = "status" :> Get '[HTML, JSON] (Status a) -- | Type to render a status page. type RenderStatus a = Status a -> Html () defaultStatusPage :: forall a. (a -> Html ()) -> RenderStatus a -- | Section with metrics. metricsSection :: MetricsJSurl -> RenderStatus a versionsSection :: [(String, Version)] -> RenderStatus a -- | Like defaultStatusPage but uses a type-class-defined to pass the -- application-status rendering. statusPage :: ToHtml a => RenderStatus a handleStatus :: Runtime -> IO a -> RenderStatus a -> Handler (Status a) data Status a Status :: !Identification -> !Liveness -> !Readiness -> !a -> RenderStatus a -> Status a [identification] :: Status a -> !Identification [liveness] :: Status a -> !Liveness [readiness] :: Status a -> !Readiness [appStatus] :: Status a -> !a [renderer] :: Status a -> RenderStatus a newtype Identification Identification :: Text -> Identification this :: Identification instance Data.Aeson.Types.ToJSON.ToJSON Prod.Status.Identification instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Prod.Status.Status a) instance Servant.API.ContentTypes.MimeRender Prod.MimeTypes.HTML (Prod.Status.Status a) module Prod.App -- | Application. app :: (HasServer api '[], ToJSON status) => Init -> IO status -> RenderStatus status -> Server api -> Proxy api -> Application -- | Application. appWithContext :: (HasServer api context, HasContextEntry (context .++ DefaultErrorFormatters) ErrorFormatters, ToJSON status) => Init -> IO status -> RenderStatus status -> Server api -> Proxy api -> Context context -> Application -- | Initializes internal data. initialize :: Runtime -> IO Init -- | Opaque proof of initialization. data Init data Runtime Runtime :: IO Liveness -> IO Readiness -> IORef (Set Reason) -> Tracer IO Track -> Runtime [liveness] :: Runtime -> IO Liveness [readiness] :: Runtime -> IO Readiness [conditions] :: Runtime -> IORef (Set Reason) [tracer] :: Runtime -> Tracer IO Track alwaysReadyRuntime :: Tracer IO Track -> IO Runtime module Prod.Background -- | A value that is coupled to an async in charge of updating the value. data BackgroundVal a -- | Fantom type for annotating Int. type MicroSeconds n = n -- | Starts a background task continuously updating a value. background :: Tracer IO (Track a) -> b -> a -> (b -> IO (a, b)) -> IO (BackgroundVal a) -- | Starts a background task continuously updating a value at a periodic -- interval. This is implemented by interspersing a threadDelay before -- the task and calling background and hiding the 'state-passing' -- arguments. backgroundLoop :: Tracer IO (Track a) -> a -> IO a -> MicroSeconds Int -> IO (BackgroundVal a) -- | Kills the watchdog by killing the underlying async. kill :: (HasCallStack, MonadIO m) => BackgroundVal a -> m () link :: BackgroundVal a -> BackgroundVal b -> IO () -- | Kills the watchdog by killing the underlying async. readBackgroundVal :: MonadIO m => BackgroundVal a -> m a data Track r Init :: r -> Track r RunStart :: Track r RunDone :: r -> r -> Track r Kill :: CallStack -> Track r instance GHC.Base.Functor Prod.Background.Track instance GHC.Show.Show r => GHC.Show.Show (Prod.Background.Track r) instance GHC.Base.Functor Prod.Background.BackgroundVal -- | Module for performing service (endpoints) discovery. module Prod.Discovery data Track a BackgroundTrack :: Track (Result a) -> Track a data Result a NotAsked :: Result a Asked :: UTCTime -> Result a Found :: UTCTime -> a -> Result a toMaybe :: Result a -> Maybe a data Discovery a Discovery :: BackgroundVal (Result a) -> Discovery a readCurrent :: Discovery a -> IO (Result a) type Host = Text data DNSTrack a DNSTrack :: Text -> Host -> Track a -> DNSTrack a dnsA :: Tracer IO (DNSTrack [Host]) -> Host -> IO (Discovery [Host]) dnsAAAA :: Tracer IO (DNSTrack [Host]) -> Host -> IO (Discovery [Host]) dig :: Tracer IO (Track [Host]) -> String -> String -> IO (Discovery [Host]) dnsDiscoveryGauge :: Vector Label3 Gauge dnsDiscoveryCounter :: Vector Label3 Counter cmdOut :: forall a. Tracer IO (Track a) -> String -> [String] -> ByteString -> Maybe (MicroSeconds Int) -> a -> (a -> ByteString -> a) -> (a -> a -> IO ()) -> IO (Discovery a) instance GHC.Base.Functor Prod.Discovery.Result instance GHC.Show.Show a => GHC.Show.Show (Prod.Discovery.Result a) instance GHC.Base.Functor Prod.Discovery.Track instance GHC.Show.Show a => GHC.Show.Show (Prod.Discovery.Track a) instance GHC.Base.Functor Prod.Discovery.Discovery instance GHC.Base.Functor Prod.Discovery.DNSTrack instance GHC.Show.Show a => GHC.Show.Show (Prod.Discovery.DNSTrack a) module Prod.Healthcheck type Host = Text type Port = Int type Error = Text data Track HealthCheckStarted :: Host -> Port -> Track HealthCheckFinished :: Host -> Port -> Check -> Track BackgroundTrack :: Host -> Port -> Track CheckSummary -> Track data Check Success :: UTCTime -> Readiness -> Check Failed :: UTCTime -> Error -> Check resultTime :: Check -> UTCTime isSuccess :: Check -> Bool getReadiness :: ClientM Readiness check :: Manager -> Host -> Port -> IO (Either Error Check) data CheckSummary CheckSummary :: Maybe Check -> [Either Error Check] -> CheckSummary [lastReady] :: CheckSummary -> Maybe Check [recentChecks] :: CheckSummary -> [Either Error Check] -- | Predicate to tell if a Summary contains a long-enough check history to -- be considered. healthChecked :: CheckSummary -> Bool -- | Predicate to tell if a Summary contains no recent successful -- healthcheck. neverHealthy :: CheckSummary -> Bool -- | Predicate to tell if the most recent summary exists and is successful. recentlyHealthy :: CheckSummary -> Bool emptyCheckSummary :: CheckSummary updateSummary :: Either Error Check -> CheckSummary -> CheckSummary type CheckMap = Map (Host, Port) (BackgroundVal CheckSummary) emptyCheckMap :: CheckMap initBackgroundCheck :: SpaceCounters -> Manager -> Tracer IO (Track CheckSummary) -> (Host, Port) -> IO (BackgroundVal CheckSummary) terminateBackgroundCheck :: BackgroundVal CheckSummary -> IO () data Space Space :: Manager -> IORef CheckMap -> ((Host, Port) -> IO (BackgroundVal CheckSummary)) -> ((Host, Port) -> IO ()) -> Space [spacehttpManager] :: Space -> Manager [backgroundChecks] :: Space -> IORef CheckMap [requestCheck] :: Space -> (Host, Port) -> IO (BackgroundVal CheckSummary) [cancelCheck] :: Space -> (Host, Port) -> IO () clearSpace :: Space -> IO () data Counters Counters :: !Vector Text Counter -> !Vector Text Counter -> !Vector Text Counter -> Counters [healthcheck_added] :: Counters -> !Vector Text Counter [healthcheck_removed] :: Counters -> !Vector Text Counter [healthcheck_count] :: Counters -> !Vector Text Counter newCounters :: IO Counters type WithSpaceCounter = (Counter -> IO ()) -> IO () data SpaceCounters SpaceCounters :: WithSpaceCounter -> WithSpaceCounter -> WithSpaceCounter -> SpaceCounters [ns_healthcheck_added] :: SpaceCounters -> WithSpaceCounter [ns_healthcheck_removed] :: SpaceCounters -> WithSpaceCounter [ns_healthcheck_count] :: SpaceCounters -> WithSpaceCounter namespaceCounters :: Namespace -> Counters -> SpaceCounters initSpace :: SpaceCounters -> Manager -> Tracer IO Track -> IO Space setChecks :: Space -> [(Host, Port)] -> IO () cancelDeadChecks :: Space -> IO () -- | Helper to build a Tracer to update hosts to check based on -- DNS-discovered answers. Note that the DNSTrack only gives Host, so you -- need to fmap the port. setChecksFromDNSDiscovery :: Space -> DNSTrack [(Host, Port)] -> IO () -- | Same as setChecksFromDNSDiscovery but only adding new checks. -- You should clear checks of permanently invalid backends. addChecksFromDNSDiscovery :: Space -> DNSTrack [(Host, Port)] -> IO () type SummaryMap = Map (Host, Port) (CheckSummary) readCheckMap :: CheckMap -> IO SummaryMap readBackgroundChecks :: Space -> IO SummaryMap -- | Returns the set of (Host,Port) that are healthy in a given SummaryMap. -- -- Healthiness consists in having the latest healthcheck as healthy. healthyKeys :: SummaryMap -> [(Host, Port)] -- | Returns the set of (Host,Port) that have no recent successful activity -- provided there is enough health-checking history. deadKeys :: SummaryMap -> [(Host, Port)] safeHead :: [a] -> Maybe a type Namespace = Text type Namespaced a = (Namespace, a) data Runtime Runtime :: Counters -> Manager -> Tracer IO (Namespaced Track) -> IORef (Map Namespace Space) -> Runtime [counters] :: Runtime -> Counters [httpManager] :: Runtime -> Manager [tracer] :: Runtime -> Tracer IO (Namespaced Track) [spaces] :: Runtime -> IORef (Map Namespace Space) initRuntime :: Tracer IO (Namespaced Track) -> IO Runtime readSpaces :: Runtime -> IO (Map Namespace SummaryMap) registerSpace :: Runtime -> Namespace -> IO Space withSpace :: Runtime -> Namespace -> (Space -> IO a) -> IO a -- | Only create a space (no registration). initRuntimeSpace :: Runtime -> Namespace -> IO Space instance GHC.Generics.Generic Prod.Healthcheck.Check instance GHC.Show.Show Prod.Healthcheck.Check instance GHC.Generics.Generic Prod.Healthcheck.CheckSummary instance GHC.Show.Show Prod.Healthcheck.CheckSummary instance GHC.Show.Show Prod.Healthcheck.Track instance Data.Aeson.Types.ToJSON.ToJSON Prod.Healthcheck.CheckSummary instance Data.Aeson.Types.FromJSON.FromJSON Prod.Healthcheck.CheckSummary instance Data.Aeson.Types.ToJSON.ToJSON Prod.Healthcheck.Check instance Data.Aeson.Types.FromJSON.FromJSON Prod.Healthcheck.Check module Prod.Watchdog data Track r BackgroundTrack :: Track (WatchdogResult r) -> Track r data WatchdogResult a Skipped :: WatchdogResult a Success :: a -> WatchdogResult a Failed :: WatchdogResult a data Watchdog a Watchdog :: BackgroundVal (WatchdogResult a) -> Tracer IO (Track a) -> Watchdog a [backgroundVal] :: Watchdog a -> BackgroundVal (WatchdogResult a) [tracer] :: Watchdog a -> Tracer IO (Track a) watchdog :: Label label => Vector label Counter -> Tracer IO (Track a) -> (WatchdogResult a -> label) -> MicroSeconds Int -> IO (WatchdogResult a) -> IO (Watchdog a) -- | Basic watchdog with a vector metric. The input vector label is set -- with success|failed|skipped depending on the WatchdogResult. basicWatchdog :: Vector Label1 Counter -> Tracer IO (Track a) -> MicroSeconds Int -> IO (WatchdogResult a) -> IO (Watchdog a) basicLabel :: WatchdogResult a -> Label1 data FileTouchTrack r FileTouchTrack :: FilePath -> Track r -> FileTouchTrack r -- | Touches a file periodically, using setModificationTime. If the file -- does not exists when the watchdog is initialized, then it is created -- empty. fileTouchWatchdog :: FilePath -> Tracer IO (FileTouchTrack UTCTime) -> MicroSeconds Int -> IO (Watchdog UTCTime) fileTouchWatchdogCounter :: Vector Label2 Counter instance GHC.Classes.Eq a => GHC.Classes.Eq (Prod.Watchdog.WatchdogResult a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Prod.Watchdog.WatchdogResult a) instance GHC.Show.Show a => GHC.Show.Show (Prod.Watchdog.WatchdogResult a) instance GHC.Show.Show r => GHC.Show.Show (Prod.Watchdog.Track r) instance GHC.Show.Show r => GHC.Show.Show (Prod.Watchdog.FileTouchTrack r)