Skip to content

Commit dd9103f

Browse files
committed
Feature/monitoring
1 parent 28761a8 commit dd9103f

30 files changed

Lines changed: 2085 additions & 832 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ launch_*
1515
gen/
1616
cardano-chain-gen/test/testfiles/temp/
1717
/secp256k1/
18+
monitoring/data/
1819

1920
# Vim
2021
*.swp
@@ -31,4 +32,4 @@ result*
3132
/.vscode
3233

3334
# MacOS
34-
.DS_Store
35+
.DS_Store

cardano-chain-gen/test/Test/Cardano/Db/Mock/Config.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,9 @@ emptyMetricsSetters =
410410
, metricsSetDbSlotHeight = \_ -> pure ()
411411
, metricsSetDbEpochSyncDuration = \_ -> pure ()
412412
, metricsSetDbEpochSyncNumber = \_ -> pure ()
413+
, metricsSetDbBlocksPerSecond = \_ -> pure ()
414+
, metricsSetInsertDuration = \_ -> pure ()
415+
, metricsSetCacheHitRate = \_ _ -> pure ()
413416
}
414417

415418
withFullConfig ::

cardano-db-sync/src/Cardano/DbSync/Database.hs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import Cardano.Prelude hiding (atomically)
2323
import Cardano.Slotting.Slot (SlotNo (..), WithOrigin (..))
2424
import Control.Concurrent.Class.MonadSTM.Strict
2525
import Control.Monad.Extra (whenJust)
26+
import Data.Time.Clock (diffUTCTime, getCurrentTime)
2627
import Ouroboros.Network.Block (BlockNo (..), Point (..))
2728
import Ouroboros.Network.Point (blockPointHash, blockPointSlot)
2829

@@ -126,7 +127,21 @@ runActions syncEnv actions = do
126127
lift $ atomically $ putTMVar resultVar (points, blockNo)
127128
dbEvent Continue ys
128129
(ys, zs) -> do
130+
-- Record start time and block count for performance metrics
131+
startTime <- liftIO getCurrentTime
132+
let blockCount = length ys
133+
134+
-- Process blocks
129135
ExceptT $ insertListBlocks syncEnv ys
136+
137+
-- Calculate and record blocks per second
138+
when (blockCount > 0) $ do
139+
endTime <- liftIO getCurrentTime
140+
let duration = realToFrac $ diffUTCTime endTime startTime
141+
when (duration > 0) $ do
142+
let blocksPerSecond = fromIntegral blockCount / duration
143+
liftIO $ setDbBlocksPerSecond (envMetricSetters syncEnv) blocksPerSecond
144+
130145
if null zs
131146
then pure Continue
132147
else dbEvent Continue zs

cardano-db-sync/src/Cardano/DbSync/Default.hs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import qualified Data.ByteString.Short as SBS
2121
import Data.List (span)
2222
import qualified Data.Set as Set
2323
import qualified Data.Strict.Maybe as Strict
24+
import Data.Time.Clock (diffUTCTime, getCurrentTime)
2425
import Ouroboros.Consensus.Cardano.Block (HardForkBlock (..))
2526
import qualified Ouroboros.Consensus.HardFork.Combinator as Consensus
2627
import Ouroboros.Network.Block (blockHash, blockNo, getHeaderFields, headerFieldBlockNo, unBlockNo)
@@ -42,6 +43,7 @@ import Cardano.DbSync.Error (SyncNodeError (..), mkSyncNodeCallStack)
4243
import Cardano.DbSync.Ledger.State (applyBlockAndSnapshot, defaultApplyResult)
4344
import Cardano.DbSync.Ledger.Types (ApplyResult (..))
4445
import Cardano.DbSync.LocalStateQuery
46+
import Cardano.DbSync.Metrics (setInsertDuration)
4547
import Cardano.DbSync.Rollback
4648
import Cardano.DbSync.Types
4749
import Cardano.DbSync.Util
@@ -151,6 +153,9 @@ insertBlock ::
151153
Bool ->
152154
ExceptT SyncNodeError DB.DbM ()
153155
insertBlock syncEnv cblk applyRes firstAfterRollback tookSnapshot = do
156+
-- Start timing for insert duration metric
157+
startTime <- liftIO getCurrentTime
158+
154159
!epochEvents <- liftIO $ atomically $ generateNewEpochEvents syncEnv (apSlotDetails applyRes)
155160
let !applyResult = applyRes {apEvents = sort $ epochEvents <> apEvents applyRes}
156161
let !details = apSlotDetails applyResult
@@ -206,6 +211,11 @@ insertBlock syncEnv cblk applyRes firstAfterRollback tookSnapshot = do
206211
do
207212
lift $ DB.deleteConsumedTxOut tracer txOutVariantType (getSafeBlockNoDiff syncEnv)
208213
commitOrIndexes withinTwoMin withinHalfHour
214+
215+
-- Record insert duration metric
216+
endTime <- liftIO getCurrentTime
217+
let duration = realToFrac $ diffUTCTime endTime startTime
218+
liftIO $ setInsertDuration (envMetricSetters syncEnv) duration
209219
where
210220
tracer = getTrace syncEnv
211221
txOutVariantType = getTxOutVariantType syncEnv

cardano-db-sync/src/Cardano/DbSync/Era/Cardano/Util.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,15 @@ insertEpochSyncTime ::
3535
UTCTime ->
3636
ExceptT SyncNodeError DB.DbM ()
3737
insertEpochSyncTime epochNo syncState epochStats endTime = do
38+
currentTime <- liftIO Time.getCurrentTime
3839
void
3940
. lift
4041
$ DB.insertEpochSyncTime
4142
$ DB.EpochSyncTime
4243
{ DB.epochSyncTimeNo = unEpochNo epochNo - 1
4344
, DB.epochSyncTimeSeconds = ceiling (realToFrac (Time.diffUTCTime endTime (elsStartTime epochStats)) :: Double)
4445
, DB.epochSyncTimeState = syncState
46+
, DB.epochSyncTimeSyncedAt = Just currentTime
4547
}
4648

4749
initEpochStatistics :: MonadIO m => m (StrictTVar IO EpochStatistics)

cardano-db-sync/src/Cardano/DbSync/Era/Universal/Insert/LedgerEvent.hs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import Cardano.Slotting.Slot (EpochNo (..))
1919

2020
import Cardano.DbSync.Api
2121
import Cardano.DbSync.Api.Types (EpochStatistics (..), InsertOptions (..), SyncEnv (..), UnicodeNullSource, formatUnicodeNullSource)
22-
import Cardano.DbSync.Cache.Types (textShowCacheStats)
22+
import Cardano.DbSync.Cache.Types (CacheStatistics (..), textShowCacheStats)
2323
import Cardano.DbSync.Era.Cardano.Util (insertEpochSyncTime, resetEpochStatistics)
2424
import qualified Cardano.DbSync.Era.Shelley.Generic as Generic
2525
import Cardano.DbSync.Era.Universal.Adjust (adjustEpochRewards)
@@ -31,7 +31,7 @@ import Cardano.DbSync.Types
3131

3232
import Cardano.DbSync.Error (SyncNodeError)
3333
import Cardano.DbSync.Ledger.Types
34-
import Cardano.DbSync.Metrics (setDbEpochSyncDuration, setDbEpochSyncNumber)
34+
import Cardano.DbSync.Metrics (setCacheHitRate, setDbEpochSyncDuration, setDbEpochSyncNumber)
3535
import Control.Concurrent.Class.MonadSTM.Strict (readTVarIO, writeTVar)
3636
import Control.Monad.Extra (whenJust)
3737
import qualified Data.Map.Strict as Map
@@ -96,6 +96,17 @@ insertNewEpochLedgerEvents syncEnv applyRes currentEpochNo@(EpochNo curEpoch) =
9696
liftIO $ setDbEpochSyncDuration metricSetters (epochDurationSeconds (elsStartTime epochStats) currentTime)
9797
liftIO $ setDbEpochSyncNumber metricSetters (fromIntegral $ unEpochNo en - 1)
9898

99+
-- Calculate and set cache hit rates
100+
let cacheStats = elsCaches epochStats
101+
hitRate hits queries = if queries == 0 then 0.0 else fromIntegral hits / fromIntegral queries
102+
liftIO $ setCacheHitRate metricSetters "stake" (hitRate (credsHits cacheStats) (credsQueries cacheStats))
103+
liftIO $ setCacheHitRate metricSetters "pools" (hitRate (poolsHits cacheStats) (poolsQueries cacheStats))
104+
liftIO $ setCacheHitRate metricSetters "datum" (hitRate (datumHits cacheStats) (datumQueries cacheStats))
105+
liftIO $ setCacheHitRate metricSetters "multi_assets" (hitRate (multiAssetsHits cacheStats) (multiAssetsQueries cacheStats))
106+
liftIO $ setCacheHitRate metricSetters "prev_block" (hitRate (prevBlockHits cacheStats) (prevBlockQueries cacheStats))
107+
liftIO $ setCacheHitRate metricSetters "address" (hitRate (addressHits cacheStats) (addressQueries cacheStats))
108+
liftIO $ setCacheHitRate metricSetters "tx_ids" (hitRate (txIdsHits cacheStats) (txIdsQueries cacheStats))
109+
99110
-- Log comprehensive epoch statistics
100111
liftIO . logInfo tracer $
101112
mconcat

cardano-db-sync/src/Cardano/DbSync/Metrics.hs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ module Cardano.DbSync.Metrics (
99
setDbSlotHeight,
1010
setDbEpochSyncDuration,
1111
setDbEpochSyncNumber,
12+
setDbBlocksPerSecond,
13+
setInsertDuration,
14+
setCacheHitRate,
1215
makeMetrics,
1316
withMetricSetters,
1417
withMetricsServer,
@@ -41,6 +44,24 @@ data Metrics = Metrics
4144
-- ^ The duration of the last epoch sync in seconds.
4245
, mDbEpochSyncNumber :: !Gauge
4346
-- ^ The number of the last epoch that was synced.
47+
, mDbBlocksPerSecond :: !Gauge
48+
-- ^ The number of blocks being processes per second.
49+
, mInsertDuration :: !Gauge
50+
-- ^ The duration of the last insert operation in seconds.
51+
, mCacheStakeHitRate :: !Gauge
52+
-- ^ Cache hit rate for stake cache.
53+
, mCachePoolsHitRate :: !Gauge
54+
-- ^ Cache hit rate for pools cache.
55+
, mCacheDatumHitRate :: !Gauge
56+
-- ^ Cache hit rate for datum cache.
57+
, mCacheMultiAssetsHitRate :: !Gauge
58+
-- ^ Cache hit rate for multi_assets cache.
59+
, mCachePrevBlockHitRate :: !Gauge
60+
-- ^ Cache hit rate for prev_block cache.
61+
, mCacheAddressHitRate :: !Gauge
62+
-- ^ Cache hit rate for address cache.
63+
, mCacheTxIdsHitRate :: !Gauge
64+
-- ^ Cache hit rate for tx_ids cache.
4465
}
4566

4667
-- This enables us to be much more flexibile with what we actually measure.
@@ -61,6 +82,20 @@ withMetricSetters prometheusPort action =
6182
Gauge.set duration $ mDbEpochSyncDuration metrics
6283
, metricsSetDbEpochSyncNumber = \epochNo ->
6384
Gauge.set (fromIntegral epochNo) $ mDbEpochSyncNumber metrics
85+
, metricsSetDbBlocksPerSecond = \bps ->
86+
Gauge.set bps $ mDbBlocksPerSecond metrics
87+
, metricsSetInsertDuration = \duration ->
88+
Gauge.set duration $ mInsertDuration metrics
89+
, metricsSetCacheHitRate = \cacheName hitRate ->
90+
case cacheName of
91+
"stake" -> Gauge.set hitRate $ mCacheStakeHitRate metrics
92+
"pools" -> Gauge.set hitRate $ mCachePoolsHitRate metrics
93+
"datum" -> Gauge.set hitRate $ mCacheDatumHitRate metrics
94+
"multi_assets" -> Gauge.set hitRate $ mCacheMultiAssetsHitRate metrics
95+
"prev_block" -> Gauge.set hitRate $ mCachePrevBlockHitRate metrics
96+
"address" -> Gauge.set hitRate $ mCacheAddressHitRate metrics
97+
"tx_ids" -> Gauge.set hitRate $ mCacheTxIdsHitRate metrics
98+
_ -> pure ()
6499
}
65100

66101
withMetricsServer :: Int -> (Metrics -> IO a) -> IO a
@@ -83,6 +118,15 @@ makeMetrics =
83118
<*> registerGauge "cardano_db_sync_db_slot_height" mempty
84119
<*> registerGauge "cardano_db_sync_db_epoch_sync_duration_seconds" mempty
85120
<*> registerGauge "cardano_db_sync_db_epoch_sync_number" mempty
121+
<*> registerGauge "cardano_db_sync_blocks_per_second" mempty
122+
<*> registerGauge "cardano_db_sync_insert_duration_seconds" mempty
123+
<*> registerGauge "cardano_db_sync_cache_stake_hit_rate" mempty
124+
<*> registerGauge "cardano_db_sync_cache_pools_hit_rate" mempty
125+
<*> registerGauge "cardano_db_sync_cache_datum_hit_rate" mempty
126+
<*> registerGauge "cardano_db_sync_cache_multi_assets_hit_rate" mempty
127+
<*> registerGauge "cardano_db_sync_cache_prev_block_hit_rate" mempty
128+
<*> registerGauge "cardano_db_sync_cache_address_hit_rate" mempty
129+
<*> registerGauge "cardano_db_sync_cache_tx_ids_hit_rate" mempty
86130

87131
setNodeBlockHeight :: MetricSetters -> WithOrigin BlockNo -> IO ()
88132
setNodeBlockHeight setters woBlkNo =
@@ -102,3 +146,12 @@ setDbEpochSyncDuration = metricsSetDbEpochSyncDuration
102146

103147
setDbEpochSyncNumber :: MetricSetters -> Word64 -> IO ()
104148
setDbEpochSyncNumber = metricsSetDbEpochSyncNumber
149+
150+
setDbBlocksPerSecond :: MetricSetters -> Double -> IO ()
151+
setDbBlocksPerSecond = metricsSetDbBlocksPerSecond
152+
153+
setInsertDuration :: MetricSetters -> Double -> IO ()
154+
setInsertDuration = metricsSetInsertDuration
155+
156+
setCacheHitRate :: MetricSetters -> Text -> Double -> IO ()
157+
setCacheHitRate = metricsSetCacheHitRate

cardano-db-sync/src/Cardano/DbSync/Types.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ data MetricSetters = MetricSetters
139139
, metricsSetDbSlotHeight :: SlotNo -> IO ()
140140
, metricsSetDbEpochSyncDuration :: Double -> IO ()
141141
, metricsSetDbEpochSyncNumber :: Word64 -> IO ()
142+
, metricsSetDbBlocksPerSecond :: Double -> IO ()
143+
, metricsSetInsertDuration :: Double -> IO ()
144+
, metricsSetCacheHitRate :: Text -> Double -> IO ()
142145
}
143146

144147
data SyncState = SyncLagging | SyncFollowing

cardano-db/src/Cardano/Db/Schema/Core/EpochAndProtocol.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ data EpochSyncTime = EpochSyncTime
324324
{ epochSyncTimeNo :: !Word64 -- sqltype=word31type
325325
, epochSyncTimeSeconds :: !Word64 -- sqltype=word63type
326326
, epochSyncTimeState :: !SyncState -- sqltype=syncstatetype
327+
, epochSyncTimeSyncedAt :: !(Maybe UTCTime)
327328
}
328329
deriving (Show, Eq, Generic)
329330

@@ -338,6 +339,7 @@ epochSyncTimeEncoder =
338339
[ epochSyncTimeNo >$< E.param (E.nonNullable $ fromIntegral >$< E.int8)
339340
, epochSyncTimeSeconds >$< E.param (E.nonNullable $ fromIntegral >$< E.int8)
340341
, epochSyncTimeState >$< E.param (E.nonNullable syncStateEncoder)
342+
, epochSyncTimeSyncedAt >$< E.param (E.nullable E.timestamptz)
341343
]
342344

343345
-----------------------------------------------------------------------------------------------------------------------------------

dev-tools/README.md

Lines changed: 0 additions & 110 deletions
This file was deleted.

0 commit comments

Comments
 (0)