diff --git a/cardano-db-sync-extended/app/cardano-db-sync-extended.hs b/cardano-db-sync-extended/app/cardano-db-sync-extended.hs index 3ee8a7bd5..edde88307 100644 --- a/cardano-db-sync-extended/app/cardano-db-sync-extended.hs +++ b/cardano-db-sync-extended/app/cardano-db-sync-extended.hs @@ -6,6 +6,7 @@ import Cardano.Prelude import Cardano.Config.Git.Rev (gitRev) import Cardano.DbSync (runDbSyncNode) +import Cardano.DbSync.Metrics (withMetricSetters) import Cardano.DbSync.Plugin.Extended (extendedDbSyncNodePlugin) import Cardano.Sync.Config @@ -29,7 +30,11 @@ main = do cmd <- Opt.execParser opts case cmd of CmdVersion -> runVersionCommand - CmdRun params -> runDbSyncNode extendedDbSyncNodePlugin params + CmdRun params -> do + prometheusPort <- dncPrometheusPort <$> readSyncNodeConfig (enpConfigFile params) + + withMetricSetters prometheusPort $ \metricsSetters -> + runDbSyncNode metricsSetters extendedDbSyncNodePlugin params -- ------------------------------------------------------------------------------------------------- diff --git a/cardano-db-sync/app/cardano-db-sync.hs b/cardano-db-sync/app/cardano-db-sync.hs index f49a7d763..2460b50bc 100644 --- a/cardano-db-sync/app/cardano-db-sync.hs +++ b/cardano-db-sync/app/cardano-db-sync.hs @@ -6,6 +6,7 @@ import Cardano.Prelude import Cardano.Config.Git.Rev (gitRev) import Cardano.DbSync (defDbSyncNodePlugin, runDbSyncNode) +import Cardano.DbSync.Metrics (withMetricSetters) import Cardano.Sync.Config import Cardano.Sync.Config.Types @@ -29,7 +30,11 @@ main = do cmd <- Opt.execParser opts case cmd of CmdVersion -> runVersionCommand - CmdRun params -> runDbSyncNode defDbSyncNodePlugin params + CmdRun params -> do + prometheusPort <- dncPrometheusPort <$> readSyncNodeConfig (enpConfigFile params) + + withMetricSetters prometheusPort $ \metricsSetters -> + runDbSyncNode metricsSetters defDbSyncNodePlugin params -- ------------------------------------------------------------------------------------------------- diff --git a/cardano-db-sync/src/Cardano/DbSync.hs b/cardano-db-sync/src/Cardano/DbSync.hs index 11d2c3581..228ac1447 100644 --- a/cardano-db-sync/src/Cardano/DbSync.hs +++ b/cardano-db-sync/src/Cardano/DbSync.hs @@ -26,7 +26,7 @@ import Cardano.Prelude hiding (Nat, option, (%)) import Control.Monad.Trans.Maybe (MaybeT (..)) -import Cardano.Api (SlotNo (..)) +import Cardano.Slotting.Slot (EpochNo (..), SlotNo (..)) import Cardano.BM.Trace (Trace) @@ -37,20 +37,24 @@ import Cardano.DbSync.Plugin.Default (defDbSyncNodePlugin) import Cardano.DbSync.Rollback (unsafeRollback) import Cardano.Sync.Database (runDbThread) -import Cardano.Sync (Block (..), SyncDataLayer (..), SyncNodePlugin (..), +import Cardano.Sync (Block (..), MetricSetters, SyncDataLayer (..), SyncNodePlugin (..), configureLogging, runSyncNode) import Cardano.Sync.Config.Types (ConfigFile (..), GenesisFile (..), LedgerStateDir (..), MigrationDir (..), NetworkName (..), SocketPath (..), SyncCommand (..), SyncNodeParams (..)) import Cardano.Sync.Tracing.ToObjectOrphans () +import Control.Monad.Extra (whenJust) + import Database.Persist.Postgresql (withPostgresqlConn) import Database.Persist.Sql (SqlBackend) +import Ouroboros.Network.Block (BlockNo (..)) + -runDbSyncNode :: (SqlBackend -> SyncNodePlugin) -> SyncNodeParams -> IO () -runDbSyncNode mkPlugin params = do +runDbSyncNode :: MetricSetters -> (SqlBackend -> SyncNodePlugin) -> SyncNodeParams -> IO () +runDbSyncNode metricsSetters mkPlugin params = do -- Read the PG connection info pgConfig <- DB.readPGPassFileEnv Nothing @@ -65,11 +69,10 @@ runDbSyncNode mkPlugin params = do DB.runIohkLogging trce $ withPostgresqlConn connectionString $ \backend -> lift $ do -- For testing and debugging. - case enpMaybeRollback params of - Just slotNo -> void $ unsafeRollback trce slotNo - Nothing -> pure () + whenJust (enpMaybeRollback params) $ \ slotNo -> + void $ unsafeRollback trce slotNo - runSyncNode (mkSyncDataLayer trce backend) trce (mkPlugin backend) + runSyncNode (mkSyncDataLayer trce backend) metricsSetters trce (mkPlugin backend) params (insertValidateGenesisDist backend) runDbThread -- ------------------------------------------------------------------------------------------------- @@ -82,11 +85,13 @@ mkSyncDataLayer trce backend = , sdlGetLatestBlock = runMaybeT $ do block <- MaybeT $ DB.runDbNoLogging DB.queryLatestBlock + -- The EpochNo, SlotNo and BlockNo can only be zero for the Byron + -- era, but we need to make the types match, hence `fromMaybe`. pure $ Block { bHash = DB.blockHash block - , bEpochNo = DB.blockEpochNo block - , bSlotNo = DB.blockSlotNo block - , bBlockNo = DB.blockBlockNo block + , bEpochNo = EpochNo . fromMaybe 0 $ DB.blockEpochNo block + , bSlotNo = SlotNo . fromMaybe 0 $ DB.blockSlotNo block + , bBlockNo = BlockNo . fromMaybe 0 $ DB.blockBlockNo block } , sdlGetLatestSlotNo = SlotNo <$> DB.runDbNoLogging DB.queryLatestSlotNo } diff --git a/cardano-db-sync/src/Cardano/DbSync/Metrics.hs b/cardano-db-sync/src/Cardano/DbSync/Metrics.hs index 4ebe1cf8f..b15f17fcf 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Metrics.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Metrics.hs @@ -4,27 +4,56 @@ module Cardano.DbSync.Metrics ( Metrics (..) , makeMetrics + , withMetricSetters , withMetricsServer ) where import Cardano.Prelude +import Cardano.Slotting.Slot (SlotNo (..)) + +import Cardano.Sync.Types (MetricSetters (..)) + +import Ouroboros.Network.Block (BlockNo (..)) + import System.Metrics.Prometheus.Concurrent.RegistryT (RegistryT (..), registerGauge, runRegistryT, unRegistryT) import System.Metrics.Prometheus.Http.Scrape (serveMetricsT) import System.Metrics.Prometheus.Metric.Gauge (Gauge) - +import qualified System.Metrics.Prometheus.Metric.Gauge as Gauge data Metrics = Metrics - { mDbHeight :: !Gauge - , mNodeHeight :: !Gauge - , mQueuePre :: !Gauge - , mQueuePost :: !Gauge - , mQueuePostWrite :: !Gauge + { mNodeBlockHeight :: !Gauge + -- ^ The block tip number of the remote node. + , mDbQueueLength :: !Gauge + -- ^ The number of @DbAction@ remaining for the database. + , mDbBlockHeight :: !Gauge + -- ^ The block tip number in the database. + , mDbSlotHeight :: !Gauge + -- ^ The slot tip number in the database. } +-- This enables us to be much more flexibile with what we actually measure. +withMetricSetters :: Int -> (MetricSetters -> IO a) -> IO a +withMetricSetters prometheusPort action = + withMetricsServer prometheusPort $ \metrics -> do + action $ + MetricSetters + { metricsSetNodeBlockHeight = \ (BlockNo nodeHeight) -> + Gauge.set (fromIntegral nodeHeight) $ mNodeBlockHeight metrics + , metricsSetDbQueueLength = \ queuePostWrite -> + Gauge.set (fromIntegral queuePostWrite) $ mDbQueueLength metrics + , metricsSetDbBlockHeight = \ (BlockNo blockNo) -> + Gauge.set (fromIntegral blockNo) $ mDbBlockHeight metrics + , metricsSetDbSlotHeight = \ (SlotNo slotNo) -> + Gauge.set (fromIntegral slotNo) $ mDbSlotHeight metrics + } + withMetricsServer :: Int -> (Metrics -> IO a) -> IO a withMetricsServer port action = do + -- Using both `RegistryT` and `bracket` here is overkill. Unfortunately the + -- Prometheus API requires the use of a `Registry` and this seems to be the + -- least sucky way of doing it. (metrics, registry) <- runRegistryT $ (,) <$> makeMetrics <*> RegistryT ask bracket (async $ runReaderT (unRegistryT $ serveMetricsT port []) registry) @@ -34,9 +63,7 @@ withMetricsServer port action = do makeMetrics :: RegistryT IO Metrics makeMetrics = Metrics - <$> registerGauge "db_block_height" mempty - <*> registerGauge "remote_tip_height" mempty - <*> registerGauge "action_queue_length_pre" mempty - <*> registerGauge "action_queue_length_post" mempty - <*> registerGauge "action_queue_length_post_write" mempty - + <$> registerGauge "cardano_db_sync_node_block_height" mempty + <*> registerGauge "cardano_db_sync_db_queue_length" mempty + <*> registerGauge "cardano_db_sync_db_block_height" mempty + <*> registerGauge "cardano_db_sync_db_slot_height" mempty diff --git a/cardano-sync/cardano-sync.cabal b/cardano-sync/cardano-sync.cabal index e7f415469..d8bab97b8 100644 --- a/cardano-sync/cardano-sync.cabal +++ b/cardano-sync/cardano-sync.cabal @@ -45,7 +45,6 @@ library Cardano.Sync.Error Cardano.Sync.LedgerState - Cardano.Sync.Metrics Cardano.Sync.Era.Byron.Util Cardano.Sync.Era.Cardano.Util @@ -57,6 +56,7 @@ library Cardano.Sync.Era.Shelley.Generic.StakeCred Cardano.Sync.Era.Shelley.Generic.StakeDist + Cardano.Sync.Metrics Cardano.Sync.Plugin Cardano.Sync.StateQuery @@ -97,7 +97,6 @@ library , ouroboros-consensus-shelley , ouroboros-network , ouroboros-network-framework - , prometheus , shelley-spec-ledger , stm , text diff --git a/cardano-sync/src/Cardano/Sync.hs b/cardano-sync/src/Cardano/Sync.hs index b3ddf5cab..9da125b48 100644 --- a/cardano-sync/src/Cardano/Sync.hs +++ b/cardano-sync/src/Cardano/Sync.hs @@ -19,8 +19,9 @@ module Cardano.Sync , SocketPath (..) , SyncDataLayer (..) + , MetricSetters (..) + , nullMetricSetters , Block (..) - , Meta (..) , SyncEnv (..) , configureLogging @@ -39,6 +40,8 @@ import qualified Cardano.Chain.Genesis as Byron import Cardano.Client.Subscription (subscribe) import qualified Cardano.Crypto as Crypto +import Cardano.Slotting.Slot (SlotNo (..), WithOrigin (..)) + import Cardano.Sync.Api import Cardano.Sync.Config import Cardano.Sync.Database (DbAction (..), DbActionQueue, lengthDbActionQueue, @@ -52,8 +55,6 @@ import Cardano.Sync.Tracing.ToObjectOrphans () import Cardano.Sync.Types import Cardano.Sync.Util -import Cardano.Slotting.Slot (WithOrigin (..), withOrigin) - import qualified Codec.CBOR.Term as CBOR import Control.Monad.Trans.Except.Exit (orDie) @@ -103,7 +104,6 @@ import qualified Ouroboros.Network.Snocket as Snocket import Ouroboros.Network.Subscription (SubscriptionTrace) import System.Directory (createDirectoryIfMissing) -import qualified System.Metrics.Prometheus.Metric.Gauge as Gauge type InsertValidateGenesisFunction @@ -115,20 +115,21 @@ type InsertValidateGenesisFunction type RunDBThreadFunction = Trace IO Text -> SyncEnv + -> MetricSetters -> SyncNodePlugin - -> Metrics -> DbActionQueue -> IO () runSyncNode :: SyncDataLayer + -> MetricSetters -> Trace IO Text -> SyncNodePlugin -> SyncNodeParams -> InsertValidateGenesisFunction -> RunDBThreadFunction -> IO () -runSyncNode dataLayer trce plugin enp insertValidateGenesisDist runDBThreadFunction = +runSyncNode dataLayer metricsSetters trce plugin enp insertValidateGenesisDist runDBThreadFunction = withIOManager $ \iomgr -> do let configFile = enpConfigFile enp @@ -152,7 +153,7 @@ runSyncNode dataLayer trce plugin enp insertValidateGenesisDist runDBThreadFunct case genCfg of GenesisCardano _ bCfg _sCfg -> do syncEnv <- ExceptT $ mkSyncEnvFromConfig dataLayer (enpLedgerStateDir enp) genCfg - liftIO $ runSyncNodeNodeClient (dncPrometheusPort enc) syncEnv iomgr trce plugin + liftIO $ runSyncNodeNodeClient metricsSetters syncEnv iomgr trce plugin runDBThreadFunction (cardanoCodecConfig bCfg) (enpSocketPath enp) where cardanoCodecConfig :: Byron.Config -> CodecConfig CardanoBlock @@ -166,7 +167,7 @@ runSyncNode dataLayer trce plugin enp insertValidateGenesisDist runDBThreadFunct -- ------------------------------------------------------------------------------------------------- runSyncNodeNodeClient - :: Int + :: MetricSetters -> SyncEnv -> IOManager -> Trace IO Text @@ -175,17 +176,16 @@ runSyncNodeNodeClient -> CodecConfig CardanoBlock -> SocketPath -> IO () -runSyncNodeNodeClient port env iomgr trce plugin runDBThreadFunction codecConfig (SocketPath socketPath) = do +runSyncNodeNodeClient metricsSetters env iomgr trce plugin runDBThreadFunction codecConfig (SocketPath socketPath) = do queryVar <- newStateQueryTMVar logInfo trce $ "localInitiatorNetworkApplication: connecting to node via " <> textShow socketPath - withMetricsServer port $ \ metrics -> - void $ subscribe - (localSnocket iomgr socketPath) - codecConfig - (envNetworkMagic env) - networkSubscriptionTracers - clientSubscriptionParams - (dbSyncProtocols trce env plugin metrics queryVar runDBThreadFunction) + void $ subscribe + (localSnocket iomgr socketPath) + codecConfig + (envNetworkMagic env) + networkSubscriptionTracers + clientSubscriptionParams + (dbSyncProtocols trce env metricsSetters plugin queryVar runDBThreadFunction) where clientSubscriptionParams = ClientSubscriptionParams @@ -219,15 +219,15 @@ runSyncNodeNodeClient port env iomgr trce plugin runDBThreadFunction codecConfig dbSyncProtocols :: Trace IO Text -> SyncEnv + -> MetricSetters -> SyncNodePlugin - -> Metrics -> StateQueryTMVar CardanoBlock (Interpreter (CardanoEras StandardCrypto)) -> RunDBThreadFunction -> Network.NodeToClientVersion -> ClientCodecs CardanoBlock IO -> ConnectionId LocalAddress -> NodeToClientProtocols 'InitiatorMode BSL.ByteString IO () Void -dbSyncProtocols trce env plugin metrics queryVar runDBThreadFunction version codecs _connectionId = +dbSyncProtocols trce env metricsSetters plugin queryVar runDBThreadFunction version codecs _connectionId = NodeToClientProtocols { localChainSyncProtocol = localChainSyncPtcl , localTxSubmissionProtocol = dummylocalTxSubmit @@ -252,13 +252,13 @@ dbSyncProtocols trce env plugin metrics queryVar runDBThreadFunction version cod actionQueue <- newDbActionQueue race_ - (runDBThreadFunction trce env plugin metrics actionQueue) + (runDBThreadFunction trce env metricsSetters plugin actionQueue) (runPipelinedPeer localChainSyncTracer (cChainSyncCodec codecs) channel (chainSyncClientPeerPipelined - $ chainSyncClient (envDataLayer env) trce env queryVar metrics latestPoints currentTip actionQueue) + $ chainSyncClient (envDataLayer env) metricsSetters trce env queryVar latestPoints currentTip actionQueue) ) atomically $ writeDbActionQueue actionQueue DbFinish @@ -306,26 +306,17 @@ logDbState dataLayer trce = do where showTip :: Block -> Text showTip blk = - case (bSlotNo blk, bBlockNo blk) of - (Just slotNo, Just blkNo) -> toS $ "slot " ++ show slotNo ++ ", block " ++ show blkNo - (Just slotNo, Nothing) -> toS $ "slot " ++ show slotNo - (Nothing, Just blkNo) -> toS $ "block " ++ show blkNo - (Nothing, Nothing) -> "empty (genesis)" + mconcat + [ "slot ", textShow (unSlotNo $ bSlotNo blk) + , ", block ", textShow (unBlockNo $ bBlockNo blk) + ] getCurrentTipBlockNo :: SyncDataLayer -> IO (WithOrigin BlockNo) getCurrentTipBlockNo dataLayer = do - let getLatestBlock = sdlGetLatestBlock dataLayer - maybeTip <- getLatestBlock - + maybeTip <- sdlGetLatestBlock dataLayer case maybeTip of - Just tip -> pure $ convert tip + Just tip -> pure $ At (bBlockNo tip) Nothing -> pure Origin - where - convert :: Block -> WithOrigin BlockNo - convert blk = - case bBlockNo blk of - Just blockno -> At (BlockNo blockno) - Nothing -> Origin -- | 'ChainSyncClient' which traces received blocks and ignores when it -- receives a request to rollbackwar. A real wallet client should: @@ -337,15 +328,15 @@ getCurrentTipBlockNo dataLayer = do -- chainSyncClient :: SyncDataLayer + -> MetricSetters -> Trace IO Text -> SyncEnv -> StateQueryTMVar CardanoBlock (Interpreter (CardanoEras StandardCrypto)) - -> Metrics -> [Point CardanoBlock] -> WithOrigin BlockNo -> DbActionQueue -> ChainSyncClientPipelined CardanoBlock (Point CardanoBlock) (Tip CardanoBlock) IO () -chainSyncClient dataLayer trce env queryVar metrics latestPoints currentTip actionQueue = do +chainSyncClient dataLayer metricsSetters trce env queryVar latestPoints currentTip actionQueue = do ChainSyncClientPipelined $ pure $ -- Notify the core node about the our latest points at which we are -- synchronised. This client is not persistent and thus it just @@ -387,12 +378,16 @@ chainSyncClient dataLayer trce env queryVar metrics latestPoints currentTip acti ClientStNext { recvMsgRollForward = \blk tip -> logException trce "recvMsgRollForward: " $ do - Gauge.set (withOrigin 0 (fromIntegral . unBlockNo) (getTipBlockNo tip)) (mNodeHeight metrics) + + setNodeBlockHeight metricsSetters (getTipBlockNo tip) + details <- getSlotDetails trce env queryVar (cardanoBlockSlotNo blk) newSize <- atomically $ do writeDbActionQueue actionQueue $ mkDbApply blk details lengthDbActionQueue actionQueue - Gauge.set (fromIntegral newSize) $ mQueuePostWrite metrics + + setDbQueueLength metricsSetters newSize + pure $ finish (At (blockNo blk)) tip , recvMsgRollBackward = \point tip -> logException trce "recvMsgRollBackward: " $ do diff --git a/cardano-sync/src/Cardano/Sync/Api.hs b/cardano-sync/src/Cardano/Sync/Api.hs index e22b5fe61..0a1b0b242 100644 --- a/cardano-sync/src/Cardano/Sync/Api.hs +++ b/cardano-sync/src/Cardano/Sync/Api.hs @@ -53,15 +53,15 @@ data SyncDataLayer = SyncDataLayer mkSyncEnv :: SyncDataLayer -> ProtocolInfo IO CardanoBlock -> Shelley.Network -> NetworkMagic -> SystemStart -> LedgerStateDir -> IO SyncEnv mkSyncEnv dataLayer protocolInfo network networkMagic systemStart dir = do - latestSlot <- sdlGetLatestSlotNo dataLayer - ledgerEnv <- mkLedgerEnv protocolInfo dir network latestSlot True - return $ SyncEnv - { envProtocol = SyncProtocolCardano - , envNetworkMagic = networkMagic - , envSystemStart = systemStart - , envDataLayer = dataLayer - , envLedger = ledgerEnv - } + latestSlot <- sdlGetLatestSlotNo dataLayer + ledgerEnv <- mkLedgerEnv protocolInfo dir network latestSlot True + pure $ SyncEnv + { envProtocol = SyncProtocolCardano + , envNetworkMagic = networkMagic + , envSystemStart = systemStart + , envDataLayer = dataLayer + , envLedger = ledgerEnv + } mkSyncEnvFromConfig :: SyncDataLayer -> LedgerStateDir -> GenesisConfig -> IO (Either SyncNodeError SyncEnv) mkSyncEnvFromConfig dataLayer dir genCfg = diff --git a/cardano-sync/src/Cardano/Sync/Database.hs b/cardano-sync/src/Cardano/Sync/Database.hs index 12ca0010a..e8d0fa479 100644 --- a/cardano-sync/src/Cardano/Sync/Database.hs +++ b/cardano-sync/src/Cardano/Sync/Database.hs @@ -18,6 +18,7 @@ import Cardano.Prelude import Cardano.BM.Trace (Trace, logDebug, logError, logInfo) +import Control.Monad.Extra (whenJust) import Control.Monad.Trans.Except.Extra (newExceptT) import Cardano.Sync.Api @@ -29,8 +30,6 @@ import Cardano.Sync.Plugin import Cardano.Sync.Types import Cardano.Sync.Util -import qualified System.Metrics.Prometheus.Metric.Gauge as Gauge - data NextState = Continue | Done @@ -41,10 +40,9 @@ runDbStartup trce plugin = mapM_ (\action -> action trce) $ plugOnStartup plugin runDbThread - :: Trace IO Text -> SyncEnv -> SyncNodePlugin -> Metrics - -> DbActionQueue + :: Trace IO Text -> SyncEnv -> MetricSetters -> SyncNodePlugin -> DbActionQueue -> IO () -runDbThread trce env plugin metrics queue = do +runDbThread trce env metricsSetters plugin queue = do logInfo trce "Running DB thread" logException trce "runDBThread: " loop logInfo trce "Shutting down DB thread" @@ -57,13 +55,10 @@ runDbThread trce env plugin metrics queue = do eNextState <- runExceptT $ runActions trce env plugin xs - let getLatestBlock = sdlGetLatestBlock (envDataLayer env) - mBlkNo <- getLatestBlock - - -- Chain Maybe's. - case bBlockNo =<< mBlkNo of - Nothing -> pure () - Just blkNo -> Gauge.set (fromIntegral blkNo) $ mDbHeight metrics + mBlock <- sdlGetLatestBlock (envDataLayer env) + whenJust mBlock $ \ block -> do + setDbBlockHeight metricsSetters $ bBlockNo block + setDbSlotHeight metricsSetters $ bSlotNo block case eNextState of Left err -> logError trce $ renderSyncNodeError err diff --git a/cardano-sync/src/Cardano/Sync/Metrics.hs b/cardano-sync/src/Cardano/Sync/Metrics.hs index cdd427bb8..d17894151 100644 --- a/cardano-sync/src/Cardano/Sync/Metrics.hs +++ b/cardano-sync/src/Cardano/Sync/Metrics.hs @@ -1,42 +1,28 @@ -{-# LANGUAGE NoImplicitPrelude #-} -{-# LANGUAGE OverloadedStrings #-} - module Cardano.Sync.Metrics - ( Metrics (..) - , makeMetrics - , withMetricsServer + ( setNodeBlockHeight + , setDbQueueLength + , setDbBlockHeight + , setDbSlotHeight ) where -import Cardano.Prelude - -import System.Metrics.Prometheus.Concurrent.RegistryT (RegistryT (..), registerGauge, - runRegistryT, unRegistryT) -import System.Metrics.Prometheus.Http.Scrape (serveMetricsT) -import System.Metrics.Prometheus.Metric.Gauge (Gauge) - - -data Metrics = Metrics - { mDbHeight :: !Gauge - , mNodeHeight :: !Gauge - , mQueuePre :: !Gauge - , mQueuePost :: !Gauge - , mQueuePostWrite :: !Gauge - } - -withMetricsServer :: Int -> (Metrics -> IO a) -> IO a -withMetricsServer port action = do - (metrics, registry) <- runRegistryT $ (,) <$> makeMetrics <*> RegistryT ask - bracket - (async $ runReaderT (unRegistryT $ serveMetricsT port []) registry) - cancel - (const $ action metrics) - -makeMetrics :: RegistryT IO Metrics -makeMetrics = - Metrics - <$> registerGauge "db_block_height" mempty - <*> registerGauge "remote_tip_height" mempty - <*> registerGauge "action_queue_length_pre" mempty - <*> registerGauge "action_queue_length_post" mempty - <*> registerGauge "action_queue_length_post_write" mempty +import Cardano.Slotting.Slot (SlotNo (..), WithOrigin (..), fromWithOrigin) + +import Cardano.Sync.Types + +import Numeric.Natural (Natural) + +import Ouroboros.Network.Block (BlockNo (..)) + + +setNodeBlockHeight :: MetricSetters -> WithOrigin BlockNo -> IO () +setNodeBlockHeight setters woBlkNo = + metricsSetNodeBlockHeight setters (fromWithOrigin (BlockNo 0) woBlkNo) + +setDbQueueLength :: MetricSetters -> Natural -> IO () +setDbQueueLength = metricsSetDbQueueLength + +setDbBlockHeight :: MetricSetters -> BlockNo -> IO () +setDbBlockHeight = metricsSetDbBlockHeight +setDbSlotHeight :: MetricSetters -> SlotNo -> IO () +setDbSlotHeight = metricsSetDbSlotHeight diff --git a/cardano-sync/src/Cardano/Sync/Types.hs b/cardano-sync/src/Cardano/Sync/Types.hs index a9ea658a5..01ef6430f 100644 --- a/cardano-sync/src/Cardano/Sync/Types.hs +++ b/cardano-sync/src/Cardano/Sync/Types.hs @@ -8,18 +8,18 @@ module Cardano.Sync.Types , SlotDetails (..) , SyncState (..) , Block (..) - , Meta (..) + , MetricSetters (..) ) where import Cardano.Prelude hiding (Meta) import Cardano.Sync.Config.Types (CardanoBlock, CardanoProtocol) -import Cardano.Slotting.Slot (EpochNo (..), EpochSize (..)) +import Cardano.Slotting.Slot (EpochNo (..), EpochSize (..), SlotNo (..)) import Data.Time.Clock (UTCTime) -import Ouroboros.Network.Block (Point) +import Ouroboros.Network.Block (BlockNo, Point) type CardanoPoint = Point CardanoBlock @@ -47,22 +47,21 @@ data SyncState -- The hash must be unique! data Block = Block - { bHash :: !ByteString - , bEpochNo :: !(Maybe Word64) - , bSlotNo :: !(Maybe Word64) - , bBlockNo :: !(Maybe Word64) - } deriving (Eq, Show) - --- The startTime must be unique! -data Meta = Meta - { mStartTime :: !UTCTime - , mNetworkName :: !(Maybe Text) - } deriving (Eq, Show) + { bHash :: !ByteString + , bEpochNo :: !EpochNo + , bSlotNo :: !SlotNo + , bBlockNo :: !BlockNo + } deriving (Eq, Show) --- @Word64@ is valid as well. -newtype BlockId = BlockId Int - deriving (Eq, Show) +-- The metrics we use. +-- Kept as a separate struct and do not put into environment because +-- when we need to test functions using this we need to initialize the +-- whole environment and not just pass in the layer. This shows clearly +-- that it needs to remain a separate parameter passed around where needed. +data MetricSetters = MetricSetters + { metricsSetNodeBlockHeight :: BlockNo -> IO () + , metricsSetDbQueueLength :: Natural -> IO () + , metricsSetDbBlockHeight :: BlockNo -> IO () + , metricsSetDbSlotHeight :: SlotNo -> IO () + } --- @Word64@ is valid as well. -newtype MetaId = MetaId Int - deriving (Eq, Show) diff --git a/cardano-sync/src/Cardano/Sync/Util.hs b/cardano-sync/src/Cardano/Sync/Util.hs index 97369a292..7e615feba 100644 --- a/cardano-sync/src/Cardano/Sync/Util.hs +++ b/cardano-sync/src/Cardano/Sync/Util.hs @@ -17,6 +17,7 @@ module Cardano.Sync.Util , textShow , tipBlockNo , traverseMEither + , nullMetricSetters ) where import Cardano.Prelude hiding (catch) @@ -110,6 +111,16 @@ logException tracer txt action = logError tracer $ txt <> textShow e throwIO e +-- | Eequired for testing or when disabling the metrics. +nullMetricSetters :: MetricSetters +nullMetricSetters = + MetricSetters + { metricsSetNodeBlockHeight = const $ pure () + , metricsSetDbQueueLength = const $ pure () + , metricsSetDbBlockHeight = const $ pure () + , metricsSetDbSlotHeight = const $ pure () + } + -- The network code catches all execptions and retries them, even exceptions generated by the -- 'error' or 'panic' function. To actually force the termination of 'db-sync' we therefore -- need a custom panic function that is guaranteed to abort when we want it to.