diff --git a/bench/locli/locli.cabal b/bench/locli/locli.cabal index e5f1bd3b52d..ba05e6455cd 100644 --- a/bench/locli/locli.cabal +++ b/bench/locli/locli.cabal @@ -152,7 +152,7 @@ executable locli ghc-options: -threaded -Wall -rtsopts - "-with-rtsopts=-T -N7 -A2m -qb -H64m" + "-with-rtsopts=-T -N7 -A2m -c -H64m" build-depends: aeson , cardano-prelude diff --git a/bench/tx-generator/src/Cardano/Benchmarking/Tracer.hs b/bench/tx-generator/src/Cardano/Benchmarking/Tracer.hs index f52fe4db709..4d041aa57e8 100644 --- a/bench/tx-generator/src/Cardano/Benchmarking/Tracer.hs +++ b/bench/tx-generator/src/Cardano/Benchmarking/Tracer.hs @@ -177,6 +177,7 @@ initialTraceConfig = TraceConfig { , tcPeerFrequency = Just 2000 -- Every 2 seconds , tcResourceFrequency = Just 1000 -- Every second , tcMetricsPrefix = Nothing + , tcLedgerMetricsFrequency = Nothing } where setMaxDetail :: Text -> ([Text], [ConfigOption]) diff --git a/cabal.project b/cabal.project index bef93a67ebc..eb3de44ca31 100644 --- a/cabal.project +++ b/cabal.project @@ -14,7 +14,7 @@ repository cardano-haskell-packages -- you need to run if you change them index-state: , hackage.haskell.org 2024-10-10T00:52:24Z - , cardano-haskell-packages 2024-10-30T10:23:17Z + , cardano-haskell-packages 2025-01-02T21:54:55Z packages: cardano-node @@ -68,3 +68,17 @@ allow-newer: -- IMPORTANT -- Do NOT add more source-repository-package stanzas here unless they are strictly -- temporary! Please read the section in CONTRIBUTING about updating dependencies. + +-- exposes getBlockchainTime in NodeKernel +source-repository-package + type: git + location: https://github.com/mgmeier/ouroboros-consensus.git + tag: 509bf8eafcf8ec7e28a1abe587d8913ed8838404 + --sha256: 1klx7x85bkzl83gmjpc2jhihjcvy3vcm75k5f0rxivgwxg4gh3k2 + subdir: + ouroboros-consensus + ouroboros-consensus-cardano + ouroboros-consensus-diffusion + ouroboros-consensus-protocol + sop-extras + strict-sop-core diff --git a/cardano-node/cardano-node.cabal b/cardano-node/cardano-node.cabal index c2f8e5c5873..5223c5d4a29 100644 --- a/cardano-node/cardano-node.cabal +++ b/cardano-node/cardano-node.cabal @@ -1,7 +1,7 @@ cabal-version: 3.0 name: cardano-node -version: 10.1.2 +version: 10.1.4 synopsis: The cardano full node description: The cardano full node. category: Cardano, @@ -111,6 +111,7 @@ library Cardano.Node.Tracing.Tracers.Diffusion Cardano.Node.Tracing.Tracers.ForgingThreadStats Cardano.Node.Tracing.Tracers.KESInfo + Cardano.Node.Tracing.Tracers.LedgerMetrics Cardano.Node.Tracing.Tracers.NodeToClient Cardano.Node.Tracing.Tracers.NodeToNode Cardano.Node.Tracing.Tracers.NodeVersion @@ -119,7 +120,6 @@ library Cardano.Node.Tracing.Tracers.Peer Cardano.Node.Tracing.Tracers.Resources Cardano.Node.Tracing.Tracers.Shutdown - Cardano.Node.Tracing.Tracers.StartLeadershipCheck Cardano.Node.Tracing.Tracers.Startup Cardano.Node.Types Cardano.Tracing.Config @@ -156,7 +156,7 @@ library , cardano-ledger-binary , cardano-ledger-byron -- TODO: remove constraint at next ledger bump - , cardano-ledger-conway ^>= 1.17.2 + , cardano-ledger-conway ^>= 1.17.4 , cardano-ledger-core , cardano-ledger-shelley , cardano-prelude diff --git a/cardano-node/src/Cardano/Node/Protocol/Cardano.hs b/cardano-node/src/Cardano/Node/Protocol/Cardano.hs index caa24132d04..84f312ea522 100644 --- a/cardano-node/src/Cardano/Node/Protocol/Cardano.hs +++ b/cardano-node/src/Cardano/Node/Protocol/Cardano.hs @@ -171,7 +171,7 @@ mkSomeConsensusProtocolCardano NodeByronProtocolConfiguration { shelleyGenesisHash, shelleyBasedLeaderCredentials = shelleyLeaderCredentials } - , Consensus.cardanoProtocolVersion = ProtVer (natVersion @10) 0 + , Consensus.cardanoProtocolVersion = ProtVer (natVersion @10) 2 -- The remaining arguments specify the parameters needed to transition between two eras , Consensus.cardanoLedgerTransitionConfig = Ledger.mkLatestTransitionConfig diff --git a/cardano-node/src/Cardano/Node/Tracing.hs b/cardano-node/src/Cardano/Node/Tracing.hs index 027d988d086..fb3017a2024 100644 --- a/cardano-node/src/Cardano/Node/Tracing.hs +++ b/cardano-node/src/Cardano/Node/Tracing.hs @@ -15,9 +15,9 @@ import Cardano.Node.Startup (NodeInfo, NodeStartupInfo, StartupTrace ( import Cardano.Node.Tracing.StateRep (NodeState) import Cardano.Node.Tracing.Tracers.ConsensusStartupException (ConsensusStartupException (..)) -import Cardano.Node.Tracing.Tracers.Peer (PeerT) +import Cardano.Node.Tracing.Tracers.LedgerMetrics (LedgerMetrics) import Cardano.Node.Tracing.Tracers.NodeVersion (NodeVersionTrace) - +import Cardano.Node.Tracing.Tracers.Peer (PeerT) import qualified Ouroboros.Consensus.Network.NodeToClient as NodeToClient import qualified Ouroboros.Consensus.Network.NodeToNode as NodeToNode import qualified Ouroboros.Consensus.Node.Tracers as Consensus @@ -55,4 +55,5 @@ data Tracers peer localPeer blk p2p = Tracers , nodeStateTracer :: !(Tracer IO NodeState) , resourcesTracer :: !(Tracer IO ResourceStats) , peersTracer :: !(Tracer IO [PeerT blk]) + , ledgerMetricsTracer :: !(Tracer IO LedgerMetrics) } diff --git a/cardano-node/src/Cardano/Node/Tracing/API.hs b/cardano-node/src/Cardano/Node/Tracing/API.hs index cf8f182411b..fb09a851705 100644 --- a/cardano-node/src/Cardano/Node/Tracing/API.hs +++ b/cardano-node/src/Cardano/Node/Tracing/API.hs @@ -18,6 +18,7 @@ import Cardano.Node.Tracing import Cardano.Node.Tracing.DefaultTraceConfig (defaultCardanoConfig) import Cardano.Node.Tracing.StateRep (NodeState (..)) import Cardano.Node.Tracing.Tracers +import Cardano.Node.Tracing.Tracers.LedgerMetrics import Cardano.Node.Tracing.Tracers.Peer (startPeerTracer) import Cardano.Node.Tracing.Tracers.Resources (startResourceTracer) import Cardano.Node.Types @@ -69,6 +70,11 @@ initTraceDispatcher nc p networkMagic nodeKernel p2pMode = do (resourcesTracer tracers) (fromMaybe 1000 (tcResourceFrequency trConfig)) + startLedgerMetricsTracer + (ledgerMetricsTracer tracers) + (fromMaybe 1000 (tcLedgerMetricsFrequency trConfig)) + nodeKernel + startPeerTracer (peersTracer tracers) nodeKernel diff --git a/cardano-node/src/Cardano/Node/Tracing/Consistency.hs b/cardano-node/src/Cardano/Node/Tracing/Consistency.hs index a2e4aa6bb35..d6b8903fd0c 100644 --- a/cardano-node/src/Cardano/Node/Tracing/Consistency.hs +++ b/cardano-node/src/Cardano/Node/Tracing/Consistency.hs @@ -22,13 +22,12 @@ import Cardano.Node.Tracing.Documentation (docTracersFirstPhase) import Cardano.Node.Tracing.Formatting () import qualified Cardano.Node.Tracing.StateRep as SR import Cardano.Node.Tracing.Tracers.BlockReplayProgress -import Cardano.Node.Tracing.Tracers.Consensus import Cardano.Node.Tracing.Tracers.Diffusion () import Cardano.Node.Tracing.Tracers.KESInfo () +import Cardano.Node.Tracing.Tracers.LedgerMetrics (LedgerMetrics) import Cardano.Node.Tracing.Tracers.NodeToClient () import Cardano.Node.Tracing.Tracers.NodeToNode () import Cardano.Node.Tracing.Tracers.NodeVersion (NodeVersionTrace) - import Cardano.Node.Tracing.Tracers.NonP2P () import Cardano.Node.Tracing.Tracers.P2P () import Cardano.Node.Tracing.Tracers.Peer @@ -46,6 +45,7 @@ import Ouroboros.Consensus.MiniProtocol.ChainSync.Client (TraceChainSy import Ouroboros.Consensus.MiniProtocol.ChainSync.Server (TraceChainSyncServerEvent) import Ouroboros.Consensus.MiniProtocol.LocalTxSubmission.Server (TraceLocalTxSubmissionServerEvent (..)) +import Ouroboros.Consensus.Node.Tracers (TraceForgeEvent) import qualified Ouroboros.Consensus.Protocol.Ledger.HotKey as HotKey import qualified Ouroboros.Consensus.Storage.ChainDB as ChainDB import Ouroboros.Network.Block (Point (..), SlotNo, Tip) @@ -128,6 +128,8 @@ getAllNamespaces = (allNamespaces :: [Namespace [PeerT blk]]) resourcesNS = map nsGetTuple (allNamespaces :: [Namespace ResourceStats]) + ledgerMetricsNS = map nsGetTuple + (allNamespaces :: [Namespace LedgerMetrics]) startupNS = map (nsGetTuple . nsReplacePrefix ["Startup"]) (allNamespaces :: [Namespace (StartupTrace blk)]) shutdownNS = map (nsGetTuple . nsReplacePrefix ["Shutdown"]) @@ -180,7 +182,7 @@ getAllNamespaces = mempoolNS = map (nsGetTuple . nsReplacePrefix ["Mempool"]) (allNamespaces :: [Namespace (TraceEventMempool blk)]) forgeNS = map (nsGetTuple . nsReplacePrefix ["Forge", "Loop"]) - (allNamespaces :: [Namespace (ForgeTracerType blk)]) + (allNamespaces :: [Namespace (TraceForgeEvent blk)]) blockchainTimeNS = map (nsGetTuple . nsReplacePrefix ["BlockchainTime"]) (allNamespaces :: [Namespace (TraceBlockchainTimeEvent RelativeTime)]) @@ -371,6 +373,7 @@ getAllNamespaces = stateNS <> peersNS <> resourcesNS + <> ledgerMetricsNS <> startupNS <> shutdownNS <> nodeVersionNS diff --git a/cardano-node/src/Cardano/Node/Tracing/Documentation.hs b/cardano-node/src/Cardano/Node/Tracing/Documentation.hs index e217afba03d..262a5e51877 100644 --- a/cardano-node/src/Cardano/Node/Tracing/Documentation.hs +++ b/cardano-node/src/Cardano/Node/Tracing/Documentation.hs @@ -33,6 +33,7 @@ import Cardano.Node.Tracing.Tracers.Consensus import Cardano.Node.Tracing.Tracers.Diffusion () import Cardano.Node.Tracing.Tracers.ForgingThreadStats (ForgeThreadStats) import Cardano.Node.Tracing.Tracers.KESInfo () +import Cardano.Node.Tracing.Tracers.LedgerMetrics (LedgerMetrics) import Cardano.Node.Tracing.Tracers.NodeToClient () import Cardano.Node.Tracing.Tracers.NodeToNode () import Cardano.Node.Tracing.Tracers.NodeVersion (NodeVersionTrace) @@ -231,6 +232,10 @@ docTracersFirstPhase condConfigFileName = do configureTracers configReflection trConfig [resourcesTr] resourcesTrDoc <- documentTracer (resourcesTr :: Trace IO ResourceStats) + ledgerMetricsTr <- mkCardanoTracer trBase trForward mbTrEKG [] + configureTracers configReflection trConfig [ledgerMetricsTr] + ledgerMetricsTrDoc <- documentTracer (ledgerMetricsTr :: Trace IO LedgerMetrics) + -- Startup tracer startupTr <- mkCardanoTracer trBase trForward mbTrEKG @@ -360,8 +365,7 @@ docTracersFirstPhase condConfigFileName = do ["Forge", "Loop"] configureTracers configReflection trConfig [forgeTr] forgeTrDoc <- documentTracer (forgeTr :: - Trace IO (ForgeTracerType blk)) - + Trace IO (Consensus.TraceForgeEvent blk)) forgeTr' <- mkCardanoTracer trBase trForward mbTrEKG @@ -377,6 +381,8 @@ docTracersFirstPhase condConfigFileName = do blockchainTimeTrDoc <- documentTracer (blockchainTimeTr :: Trace IO (TraceBlockchainTimeEvent RelativeTime)) + + -- Node to client keepAliveClientTr <- mkCardanoTracer @@ -699,6 +705,7 @@ docTracersFirstPhase condConfigFileName = do <> nodeStartupInfoDpDoc <> stateTrDoc <> resourcesTrDoc + <> ledgerMetricsTrDoc <> startupTrDoc <> shutdownTrDoc <> nodeVersionDoc diff --git a/cardano-node/src/Cardano/Node/Tracing/Tracers.hs b/cardano-node/src/Cardano/Node/Tracing/Tracers.hs index b105e66bc08..a83d4e27532 100644 --- a/cardano-node/src/Cardano/Node/Tracing/Tracers.hs +++ b/cardano-node/src/Cardano/Node/Tracing/Tracers.hs @@ -31,6 +31,7 @@ import Cardano.Node.Tracing.Tracers.Consensus import Cardano.Node.Tracing.Tracers.Diffusion () import Cardano.Node.Tracing.Tracers.ForgingThreadStats (forgeThreadStats) import Cardano.Node.Tracing.Tracers.KESInfo +import Cardano.Node.Tracing.Tracers.LedgerMetrics () import Cardano.Node.Tracing.Tracers.NodeToClient () import Cardano.Node.Tracing.Tracers.NodeToNode () import Cardano.Node.Tracing.Tracers.NodeVersion (getNodeVersion) @@ -117,6 +118,9 @@ mkDispatchTracers nodeKernel trBase trForward mbTrEKG trDataPoint trConfig enabl !resourcesTr <- mkCardanoTracer trBase trForward mbTrEKG [] configureTracers configReflection trConfig [resourcesTr] + !ledgerMetricsTr <- mkCardanoTracer trBase trForward mbTrEKG [] + configureTracers configReflection trConfig [ledgerMetricsTr] + !startupTr <- mkCardanoTracer trBase trForward mbTrEKG ["Startup"] configureTracers configReflection trConfig [startupTr] @@ -199,6 +203,7 @@ mkDispatchTracers nodeKernel trBase trForward mbTrEKG trDataPoint trConfig enabl , resourcesTracer = Tracer (traceWith resourcesTr) , peersTracer = Tracer (traceWith peersTr) <> Tracer (traceNodePeers nodePeersDP) + , ledgerMetricsTracer = Tracer (traceWith ledgerMetricsTr) } mkConsensusTracers :: forall blk. @@ -217,7 +222,7 @@ mkConsensusTracers :: forall blk. -> TraceConfig -> NodeKernelData blk -> IO (Consensus.Tracers IO (ConnectionId RemoteAddress) (ConnectionId LocalAddress) blk) -mkConsensusTracers configReflection trBase trForward mbTrEKG _trDataPoint trConfig nodeKernel = do +mkConsensusTracers configReflection trBase trForward mbTrEKG _trDataPoint trConfig _nodeKernel = do !chainSyncClientTr <- mkCardanoTracer trBase trForward mbTrEKG ["ChainSync", "Client"] @@ -301,10 +306,9 @@ mkConsensusTracers configReflection trBase trForward mbTrEKG _trDataPoint trConf ["Mempool"] configureTracers configReflection trConfig [mempoolTr] - !forgeTr <- mkCardanoTracer' + !forgeTr <- mkCardanoTracer trBase trForward mbTrEKG ["Forge", "Loop"] - (forgeTracerTransform nodeKernel) configureTracers configReflection trConfig [forgeTr] !forgeThreadStatsTr <- mkCardanoTracer' @@ -363,9 +367,9 @@ mkConsensusTracers configReflection trBase trForward mbTrEKG _trDataPoint trConf , Consensus.mempoolTracer = Tracer $ traceWith mempoolTr , Consensus.forgeTracer = - Tracer (\(Consensus.TraceLabelCreds _ x) -> traceWith (contramap Left forgeTr) x) + Tracer (\(Consensus.TraceLabelCreds _ x) -> traceWith forgeTr x) <> - Tracer (\(Consensus.TraceLabelCreds _ x) -> traceWith (contramap Left forgeThreadStatsTr) x) + Tracer (\(Consensus.TraceLabelCreds _ x) -> traceWith forgeThreadStatsTr x) , Consensus.blockchainTimeTracer = Tracer $ traceWith blockchainTimeTr , Consensus.keepAliveClientTracer = Tracer $ diff --git a/cardano-node/src/Cardano/Node/Tracing/Tracers/ChainDB.hs b/cardano-node/src/Cardano/Node/Tracing/Tracers/ChainDB.hs index a0ecf536704..985da853e1c 100644 --- a/cardano-node/src/Cardano/Node/Tracing/Tracers/ChainDB.hs +++ b/cardano-node/src/Cardano/Node/Tracing/Tracers/ChainDB.hs @@ -11,6 +11,7 @@ module Cardano.Node.Tracing.Tracers.ChainDB ( withAddedToCurrentChainEmptyLimited + , fragmentChainDensity ) where import Cardano.Logging diff --git a/cardano-node/src/Cardano/Node/Tracing/Tracers/Consensus.hs b/cardano-node/src/Cardano/Node/Tracing/Tracers/Consensus.hs index 0ec5a5db4bc..b687bbde476 100644 --- a/cardano-node/src/Cardano/Node/Tracing/Tracers/Consensus.hs +++ b/cardano-node/src/Cardano/Node/Tracing/Tracers/Consensus.hs @@ -14,10 +14,7 @@ module Cardano.Node.Tracing.Tracers.Consensus ( - TraceStartLeadershipCheckPlus (..) - , ForgeTracerType - , forgeTracerTransform - , initialClientMetrics + initialClientMetrics , calculateBlockFetchClientMetrics , ClientMetrics ) where @@ -30,7 +27,6 @@ import Cardano.Node.Tracing.Era.Shelley () import Cardano.Node.Tracing.Formatting () import Cardano.Node.Tracing.Render import Cardano.Node.Tracing.Tracers.ConsensusStartupException () -import Cardano.Node.Tracing.Tracers.StartLeadershipCheck import Cardano.Protocol.TPraos.OCert (KESPeriod (..)) import Cardano.Slotting.Slot (WithOrigin (..)) import Ouroboros.Consensus.Block @@ -72,7 +68,7 @@ import Ouroboros.Network.TxSubmission.Outbound import Control.Monad (guard) import Control.Monad.Class.MonadTime.SI (Time (..)) -import Data.Aeson (ToJSON, Value (Number, String), toJSON, (.=)) +import Data.Aeson (ToJSON, Value (..), toJSON, (.=)) import qualified Data.Aeson as Aeson import Data.Foldable (Foldable(toList)) import Data.Int (Int64) @@ -1308,100 +1304,6 @@ instance MetaTrace (TraceEventMempool blk) where , Namespace [] ["ManuallyRemovedTxs"] ] --------------------------------------------------------------------------------- --- ForgeTracerType --------------------------------------------------------------------------------- - -instance ( tx ~ GenTx blk - , ConvertRawHash blk - , GetHeader blk - , HasHeader blk - , HasKESInfo blk - , LedgerSupportsProtocol blk - , LedgerSupportsMempool blk - , SerialiseNodeToNodeConstraints blk - , HasTxId (GenTx blk) - , Show (ForgeStateUpdateError blk) - , Show (CannotForge blk) - , LogFormatting (InvalidBlockReason blk) - , LogFormatting (CannotForge blk) - , LogFormatting (ForgeStateUpdateError blk)) - => LogFormatting (ForgeTracerType blk) where - forMachine dtal (Left i) = forMachine dtal i - forMachine dtal (Right i) = forMachine dtal i - forHuman (Left i) = forHumanOrMachine i - forHuman (Right i) = forHumanOrMachine i - asMetrics (Left i) = asMetrics i - asMetrics (Right i) = asMetrics i - -instance MetaTrace (ForgeTracerType blk) where - namespaceFor (Left ev) = - nsCast (namespaceFor ev) - namespaceFor (Right _ev) = - Namespace [] ["StartLeadershipCheckPlus"] - - severityFor (Namespace _ ["StartLeadershipCheckPlus"]) _ = Just - Info - severityFor ns (Just (Left ev')) = - severityFor (nsCast ns) (Just ev') - severityFor ns Nothing = - severityFor (nsCast ns :: Namespace (TraceForgeEvent blk)) Nothing - severityFor _ _ = Nothing - - detailsFor (Namespace _ ["StartLeadershipCheckPlus"]) _ = Just - DNormal - detailsFor ns (Just (Left ev')) = - detailsFor (nsCast ns) (Just ev') - detailsFor ns Nothing = - detailsFor (nsCast ns :: Namespace (TraceForgeEvent blk)) Nothing - detailsFor _ _ = Nothing - - privacyFor (Namespace _ ["StartLeadershipCheckPlus"]) _ = Just - Public - privacyFor ns (Just (Left ev')) = - privacyFor (nsCast ns) (Just ev') - privacyFor ns Nothing = - privacyFor (nsCast ns :: Namespace (TraceForgeEvent blk)) Nothing - privacyFor _ _ = Nothing - - metricsDocFor (Namespace _ ["StartLeadershipCheckPlus"]) = - [ ("Forge.UtxoSize", "") - , ("Forge.DelegMapSize", "") - ] - metricsDocFor ns = - metricsDocFor (nsCast ns :: Namespace (TraceForgeEvent blk)) - - documentFor (Namespace _ ["StartLeadershipCheckPlus"]) = Just $ mconcat - [ "We adopted the block we produced, we also trace the transactions" - , " that were adopted." - ] - documentFor ns = - documentFor (nsCast ns :: Namespace (TraceForgeEvent blk)) - - allNamespaces = - Namespace [] ["StartLeadershipCheckPlus"] - : map nsCast (allNamespaces :: [Namespace (TraceForgeEvent blk)]) - --------------------------------------------------------------------------------- --- TraceStartLeadershipCheck --------------------------------------------------------------------------------- - -instance LogFormatting TraceStartLeadershipCheckPlus where - forMachine _dtal TraceStartLeadershipCheckPlus {..} = - mconcat [ "kind" .= String "TraceStartLeadershipCheck" - , "slot" .= toJSON (unSlotNo tsSlotNo) - , "utxoSize" .= Number (fromIntegral tsUtxoSize) - , "delegMapSize" .= Number (fromIntegral tsDelegMapSize) - , "chainDensity" .= Number (fromRational (toRational tsChainDensity)) - ] - forHuman TraceStartLeadershipCheckPlus {..} = - "Checking for leadership in slot " <> showT (unSlotNo tsSlotNo) - <> " utxoSize " <> showT tsUtxoSize - <> " delegMapSize " <> showT tsDelegMapSize - <> " chainDensity " <> showT tsChainDensity - asMetrics TraceStartLeadershipCheckPlus {..} = - [IntM "utxoSize" (fromIntegral tsUtxoSize), - IntM "delegMapSize" (fromIntegral tsDelegMapSize)] -------------------------------------------------------------------------------- diff --git a/cardano-node/src/Cardano/Node/Tracing/Tracers/ForgingThreadStats.hs b/cardano-node/src/Cardano/Node/Tracing/Tracers/ForgingThreadStats.hs index 21841012203..62fb0e5f2de 100644 --- a/cardano-node/src/Cardano/Node/Tracing/Tracers/ForgingThreadStats.hs +++ b/cardano-node/src/Cardano/Node/Tracing/Tracers/ForgingThreadStats.hs @@ -10,7 +10,6 @@ module Cardano.Node.Tracing.Tracers.ForgingThreadStats ) where import Cardano.Logging -import Cardano.Node.Tracing.Tracers.StartLeadershipCheck (ForgeTracerType) import Cardano.Slotting.Slot (SlotNo (..)) import Ouroboros.Consensus.Node.Tracers import qualified Ouroboros.Consensus.Node.Tracers as Consensus @@ -155,31 +154,30 @@ emptyForgingStats :: ForgingStats emptyForgingStats = ForgingStats mempty 0 0 0 0 forgeThreadStats :: Trace IO ForgingStats - -> IO (Trace IO (ForgeTracerType blk)) + -> IO (Trace IO (TraceForgeEvent blk)) forgeThreadStats tr = - let tr' = contramap unfold tr - in foldCondTraceM calculateThreadStats emptyForgingStats - (\case - Left Consensus.TraceStartLeadershipCheck{} -> True - Left _ -> False - Right _ -> True - ) - tr' + let tr' = contramap unfold tr + in foldCondTraceM calculateThreadStats emptyForgingStats + (\case + Consensus.TraceStartLeadershipCheck{} -> True + _ -> False + ) + tr' calculateThreadStats :: MonadIO m => ForgingStats -> LoggingContext - -> ForgeTracerType blk + -> TraceForgeEvent blk -> m ForgingStats calculateThreadStats stats _context - (Left TraceNodeCannotForge {}) = do + (TraceNodeCannotForge {}) = do mapThreadStats stats (\fts -> (fts { ftsNodeCannotForgeNum = ftsNodeCannotForgeNum fts + 1} , Nothing)) (\fs _ -> (fs { fsNodeCannotForgeNum = fsNodeCannotForgeNum fs + 1 })) calculateThreadStats stats _context - (Left (TraceNodeIsLeader (SlotNo slot'))) = do + (TraceNodeIsLeader (SlotNo slot')) = do let slot = fromIntegral slot' mapThreadStats stats @@ -187,14 +185,14 @@ calculateThreadStats stats _context , ftsLastSlot = slot}, Nothing)) (\fs _ -> (fs { fsNodeIsLeaderNum = fsNodeIsLeaderNum fs + 1 })) calculateThreadStats stats _context - (Left TraceForgedBlock {}) = do + (TraceForgedBlock {}) = do mapThreadStats stats (\fts -> (fts { ftsBlocksForgedNum = ftsBlocksForgedNum fts + 1} , Nothing)) (\fs _ -> (fs { fsBlocksForgedNum = fsBlocksForgedNum fs + 1 })) calculateThreadStats stats _context - (Left (TraceNodeNotLeader (SlotNo slot'))) = do + (TraceNodeNotLeader (SlotNo slot')) = do let slot = fromIntegral slot' mapThreadStats stats diff --git a/cardano-node/src/Cardano/Node/Tracing/Tracers/LedgerMetrics.hs b/cardano-node/src/Cardano/Node/Tracing/Tracers/LedgerMetrics.hs new file mode 100644 index 00000000000..002403abef3 --- /dev/null +++ b/cardano-node/src/Cardano/Node/Tracing/Tracers/LedgerMetrics.hs @@ -0,0 +1,165 @@ +{-# LANGUAGE BangPatterns #-} +{-# LANGUAGE CPP #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE PackageImports #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE ScopedTypeVariables #-} + +{-# OPTIONS_GHC -Wno-redundant-constraints #-} + +module Cardano.Node.Tracing.Tracers.LedgerMetrics + ( LedgerMetrics (..) + , traceLedgerMetrics + , startLedgerMetricsTracer + ) where + +import Cardano.Ledger.BaseTypes (SlotNo (..), StrictMaybe (..)) +import Cardano.Logging hiding (traceWith) +import Cardano.Node.Queries (LedgerQueries (..), NodeKernelData (..), mapNodeKernelDataIO, + nkQueryChain, nkQueryLedger) +import Cardano.Node.Tracing.Tracers.ChainDB (fragmentChainDensity) +import Ouroboros.Consensus.BlockchainTime.API +import Ouroboros.Consensus.HardFork.Combinator +import Ouroboros.Consensus.Ledger.Abstract (IsLedger) +import Ouroboros.Consensus.Ledger.Extended (ledgerState) +import Ouroboros.Consensus.Node (NodeKernel (getBlockchainTime)) +import qualified Ouroboros.Network.AnchoredFragment as AF + +import Control.Concurrent (threadDelay) +import Control.Concurrent.Async (async) +import Control.Monad.Class.MonadAsync (link) +import Control.Monad.STM (atomically, retry) +import "contra-tracer" Control.Tracer (Tracer, traceWith) +import Data.Aeson (Value (Number, String), toJSON, (.=)) + +startLedgerMetricsTracer + :: forall blk + . IsLedger (LedgerState blk) + => LedgerQueries blk + => AF.HasHeader (Header blk) + => AF.HasHeader blk + => Tracer IO LedgerMetrics + -> Int + -> NodeKernelData blk + -> IO () +startLedgerMetricsTracer tr _delayMilliseconds nodeKernelData = do + as <- async ledgerMetricsThread + link as + where + ledgerMetricsThread :: IO () + ledgerMetricsThread = go (-1) where + go slot = do + !query <- waitForDifferentSlot slot + threadDelay $ 700 * 1000 + case query of + SJust slot' -> traceLedgerMetrics nodeKernelData slot' tr >> go slot' + SNothing -> go slot + + waitForDifferentSlot :: SlotNo -> IO (StrictMaybe SlotNo) + waitForDifferentSlot s = do + mapNodeKernelDataIO (\nk -> atomically $ do + mSlot <- getCurrentSlot (getBlockchainTime nk) + case mSlot of + CurrentSlot s' | s' /= s -> return s' + _ -> retry + ) nodeKernelData + +data LedgerMetrics = + LedgerMetrics { + tsSlotNo :: SlotNo + , tsUtxoSize :: Int + , tsDelegMapSize :: Int + , tsDRepCount :: Int + , tsDRepMapSize :: Int + , tsChainDensity :: Double + } + +traceLedgerMetrics :: + ( IsLedger (LedgerState blk) + , LedgerQueries blk +#if __GLASGOW_HASKELL__ >= 906 + , AF.HasHeader blk +#endif + , AF.HasHeader (Header blk)) + => NodeKernelData blk + -> SlotNo + -> Tracer IO LedgerMetrics + -> IO () +traceLedgerMetrics nodeKern slotNo tracer = do + query <- mapNodeKernelDataIO + (\nk -> + (,,,,) + <$> nkQueryLedger (ledgerUtxoSize . ledgerState) nk + <*> nkQueryLedger (ledgerDelegMapSize . ledgerState) nk + <*> nkQueryLedger (ledgerDRepCount . ledgerState) nk + <*> nkQueryLedger (ledgerDRepMapSize . ledgerState) nk + <*> nkQueryChain fragmentChainDensity nk) + nodeKern + case query of + SNothing -> pure () + SJust (utxoSize, delegMapSize, drepCount, drepMapSize, chainDensity) -> + let msg = LedgerMetrics + slotNo + utxoSize + delegMapSize + drepCount + drepMapSize + (fromRational chainDensity) + in traceWith tracer msg + +-------------------------------------------------------------------------------- +-- LedgerMetrics +-------------------------------------------------------------------------------- + +instance LogFormatting LedgerMetrics where + forMachine _dtal LedgerMetrics {..} = + mconcat [ "kind" .= String "LedgerMetrics" + , "slot" .= toJSON (unSlotNo tsSlotNo) + , "utxoSize" .= Number (fromIntegral tsUtxoSize) + , "delegMapSize" .= Number (fromIntegral tsDelegMapSize) + , "drepCount" .= Number (fromIntegral tsDRepCount) + , "drepMapSize" .= Number (fromIntegral tsDRepMapSize) + , "chainDensity" .= Number (fromRational (toRational tsChainDensity)) + ] + forHuman LedgerMetrics {..} = + "Ledger metrics " + <> " utxoSize " <> showT tsUtxoSize + <> " delegMapSize " <> showT tsDelegMapSize + <> " drepCount" <> showT tsDRepCount + <> " drepMapSize" <> showT tsDRepMapSize + <> " chainDensity " <> showT tsChainDensity + asMetrics LedgerMetrics {..} = + [ IntM "utxoSize" (fromIntegral tsUtxoSize) + , IntM "delegMapSize" (fromIntegral tsDelegMapSize) + , IntM "drepCount" (fromIntegral tsDRepCount) + , IntM "drepMapSize" (fromIntegral tsDRepMapSize)] + + +instance MetaTrace LedgerMetrics where + namespaceFor LedgerMetrics {} = Namespace [] ["LedgerMetrics"] + severityFor (Namespace _ ["LedgerMetrics"]) _ = Just Info + severityFor _ _ = Nothing + + metricsDocFor (Namespace _ ["LedgerMetrics"]) = + [ ("utxoSize", "UTxO set size") + , ("delegMapSize", "Delegation map size") + , ("drepCount", "") + , ("drepMapSize", "") + ] + metricsDocFor _ = [] + + documentFor (Namespace _ ["LedgerMetrics"]) = Just $ mconcat + [ "" -- TODO YUP + ] + + documentFor _ = Nothing + + allNamespaces = [Namespace [] ["LedgerMetrics"]] + + + + + + diff --git a/cardano-node/src/Cardano/Node/Tracing/Tracers/StartLeadershipCheck.hs b/cardano-node/src/Cardano/Node/Tracing/Tracers/StartLeadershipCheck.hs deleted file mode 100644 index b3d5bb810a9..00000000000 --- a/cardano-node/src/Cardano/Node/Tracing/Tracers/StartLeadershipCheck.hs +++ /dev/null @@ -1,136 +0,0 @@ -{-# LANGUAGE CPP #-} -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE LambdaCase #-} -{-# LANGUAGE NamedFieldPuns #-} - -module Cardano.Node.Tracing.Tracers.StartLeadershipCheck - ( TraceStartLeadershipCheckPlus (..) - , ForgeTracerType - , forgeTracerTransform - ) where - - -import Cardano.Logging - -import Control.Concurrent.STM (atomically) -import Data.IORef (readIORef) -import Data.Word (Word64) - -import qualified Ouroboros.Network.AnchoredFragment as AF -import Ouroboros.Network.Block (BlockNo (..), blockNo, unBlockNo) -import Ouroboros.Network.NodeToClient (LocalConnectionId) -import Ouroboros.Network.NodeToNode (RemoteAddress) - -import Ouroboros.Consensus.Block (SlotNo (..)) -import Ouroboros.Consensus.HardFork.Combinator -import Ouroboros.Consensus.Ledger.Abstract (IsLedger) -import Ouroboros.Consensus.Ledger.Extended (ExtLedgerState, ledgerState) -import Ouroboros.Consensus.Node (NodeKernel (..)) -import Ouroboros.Consensus.Node.Tracers -import qualified Ouroboros.Consensus.Storage.ChainDB as ChainDB - -import Cardano.Node.Queries (LedgerQueries (..), NodeKernelData (..)) -import Cardano.Slotting.Slot (fromWithOrigin) - -import Cardano.Ledger.BaseTypes (StrictMaybe (..)) - - -type ForgeTracerType blk = Either (TraceForgeEvent blk) - TraceStartLeadershipCheckPlus - -data TraceStartLeadershipCheckPlus = - TraceStartLeadershipCheckPlus { - tsSlotNo :: SlotNo - , tsUtxoSize :: Int - , tsDelegMapSize :: Int - , tsChainDensity :: Double - } - -forgeTracerTransform :: - ( IsLedger (LedgerState blk) - , LedgerQueries blk -#if __GLASGOW_HASKELL__ >= 906 - , AF.HasHeader blk -#endif - , AF.HasHeader (Header blk)) - => NodeKernelData blk - -> Trace IO (ForgeTracerType blk) - -> IO (Trace IO (ForgeTracerType blk)) -forgeTracerTransform nodeKern (Trace tr) = - contramapM (Trace tr) - (\case - (lc, Right (Left slc@(TraceStartLeadershipCheck slotNo))) -> do - query <- mapNodeKernelDataIO - (\nk -> - (,,) - <$> nkQueryLedger (ledgerUtxoSize . ledgerState) nk - <*> nkQueryLedger (ledgerDelegMapSize . ledgerState) nk - <*> nkQueryChain fragmentChainDensity nk) - nodeKern - case query of - SNothing -> pure (lc, Right (Left slc)) - SJust (utxoSize, delegMapSize, chainDensity) -> - let msg = TraceStartLeadershipCheckPlus - slotNo - utxoSize - delegMapSize - (fromRational chainDensity) - in pure (lc, Right (Right msg)) - (lc, Right a) -> - pure (lc, Right a) - (lc, Left control) -> - pure (lc, Left control)) - -nkQueryLedger :: - IsLedger (LedgerState blk) - => (ExtLedgerState blk -> a) - -> NodeKernel IO RemoteAddress LocalConnectionId blk - -> IO a -nkQueryLedger f NodeKernel{getChainDB} = - f <$> atomically (ChainDB.getCurrentLedger getChainDB) - -fragmentChainDensity :: -#if __GLASGOW_HASKELL__ >= 906 - (AF.HasHeader blk, AF.HasHeader (Header blk)) -#else - AF.HasHeader (Header blk) -#endif - => AF.AnchoredFragment (Header blk) -> Rational -fragmentChainDensity frag = calcDensity blockD slotD - where - calcDensity :: Word64 -> Word64 -> Rational - calcDensity bl sl - | sl > 0 = toRational bl / toRational sl - | otherwise = 0 - slotN = unSlotNo $ fromWithOrigin 0 (AF.headSlot frag) - -- Slot of the tip - slot @k@ blocks back. Use 0 as the slot for genesis - -- includes EBBs - slotD = slotN - - unSlotNo (fromWithOrigin 0 (AF.lastSlot frag)) - -- Block numbers start at 1. We ignore the genesis EBB, which has block number 0. - blockD = blockN - firstBlock - blockN = unBlockNo $ fromWithOrigin (BlockNo 1) (AF.headBlockNo frag) - firstBlock = case unBlockNo . blockNo <$> AF.last frag of - -- Empty fragment, no blocks. We have that @blocks = 1 - 1 = 0@ - Left _ -> 1 - -- The oldest block is the genesis EBB with block number 0, - -- don't let it contribute to the number of blocks - Right 0 -> 1 - Right b -> b - -nkQueryChain :: - (AF.AnchoredFragment (Header blk) -> a) - -> NodeKernel IO RemoteAddress LocalConnectionId blk - -> IO a -nkQueryChain f NodeKernel{getChainDB} = - f <$> atomically (ChainDB.getCurrentChain getChainDB) - - -mapNodeKernelDataIO :: - (NodeKernel IO RemoteAddress LocalConnectionId blk -> IO a) - -> NodeKernelData blk - -> IO (StrictMaybe a) -mapNodeKernelDataIO f (NodeKernelData ref) = - readIORef ref >>= traverse f diff --git a/cardano-node/src/Cardano/Tracing/Tracers.hs b/cardano-node/src/Cardano/Tracing/Tracers.hs index 78ea014e3e5..45f3e8efaa9 100644 --- a/cardano-node/src/Cardano/Tracing/Tracers.hs +++ b/cardano-node/src/Cardano/Tracing/Tracers.hs @@ -70,8 +70,8 @@ import Ouroboros.Consensus.Ledger.Abstract (LedgerErr, LedgerState) import Ouroboros.Consensus.Ledger.Extended (ledgerState) import Ouroboros.Consensus.Ledger.Inspect (InspectLedger, LedgerEvent) import Ouroboros.Consensus.Ledger.Query (BlockQuery) -import Ouroboros.Consensus.Ledger.SupportsMempool (ApplyTxErr, GenTx, GenTxId, HasTxs, - LedgerSupportsMempool, ByteSize32 (..)) +import Ouroboros.Consensus.Ledger.SupportsMempool (ApplyTxErr, ByteSize32 (..), GenTx, + GenTxId, HasTxs, LedgerSupportsMempool) import Ouroboros.Consensus.Ledger.SupportsProtocol (LedgerSupportsProtocol) import Ouroboros.Consensus.Mempool (MempoolSize (..), TraceEventMempool (..)) import Ouroboros.Consensus.MiniProtocol.BlockFetch.Server @@ -176,6 +176,7 @@ nullTracersP2P = Tracers , nodeVersionTracer = nullTracer , resourcesTracer = nullTracer , peersTracer = nullTracer + , ledgerMetricsTracer = nullTracer } nullTracersNonP2P :: Tracers peer localPeer blk 'Diffusion.NonP2P @@ -194,6 +195,7 @@ nullTracersNonP2P = Tracers , nodeVersionTracer = nullTracer , resourcesTracer = nullTracer , peersTracer = nullTracer + , ledgerMetricsTracer = nullTracer } indexGCType :: ChainDB.TraceGCEvent a -> Int @@ -360,6 +362,7 @@ mkTracers blockConfig tOpts@(TracingOnLegacy trSel) tr nodeKern ekgDirect enable , nodeStateTracer = nullTracer , resourcesTracer = nullTracer , peersTracer = nullTracer + , ledgerMetricsTracer = nullTracer } where traceForgeEnabledMetric :: Maybe EKGDirect -> StartupTrace blk -> IO () @@ -538,6 +541,7 @@ mkTracers _ _ _ _ _ enableP2P = , nodeVersionTracer = nullTracer , resourcesTracer = nullTracer , peersTracer = nullTracer + , ledgerMetricsTracer = nullTracer } -------------------------------------------------------------------------------- diff --git a/cardano-tracer/src/Cardano/Tracer/MetaTrace.hs b/cardano-tracer/src/Cardano/Tracer/MetaTrace.hs index 9abd834affc..d7c8a685c7f 100644 --- a/cardano-tracer/src/Cardano/Tracer/MetaTrace.hs +++ b/cardano-tracer/src/Cardano/Tracer/MetaTrace.hs @@ -302,6 +302,7 @@ mkTracerTracer defSeverity = do , tcNodeName = Nothing , tcPeerFrequency = Nothing , tcResourceFrequency = Nothing + , tcLedgerMetricsFrequency = Nothing , tcMetricsPrefix = Nothing , tcOptions = Map.fromList [ ([], [ConfSeverity defSeverity]) diff --git a/flake.lock b/flake.lock index 82e94186fda..03529c16a9d 100644 --- a/flake.lock +++ b/flake.lock @@ -3,11 +3,11 @@ "CHaP": { "flake": false, "locked": { - "lastModified": 1730295876, - "narHash": "sha256-ijnHTQ6eKIQ9FpEqDKt6c7vuFYN8aOBDhonp67utx2s=", + "lastModified": 1735857786, + "narHash": "sha256-X6Fp2uU++62rgaH4J1pIN5AalfV7f9rM5dmFaByMWqU=", "owner": "intersectmbo", "repo": "cardano-haskell-packages", - "rev": "25591f43ab943d5a070db5e8a2b9ff3a499d4d92", + "rev": "b9eaf0bbe60ccf64b7afc969b79f9820a4534bcf", "type": "github" }, "original": { diff --git a/nix/workbench/service/tracing.nix b/nix/workbench/service/tracing.nix index 9b8ef772d6e..9d24ecc31f6 100644 --- a/nix/workbench/service/tracing.nix +++ b/nix/workbench/service/tracing.nix @@ -76,6 +76,7 @@ let "Net.Subscription.DNS".severity = "Debug"; "Net.Subscription.IP".severity = "Debug"; "NodeState".severity = "Notice"; + "LedgerMetrics".severity = "Info"; "Resources".severity = "Debug"; "Shutdown".severity = "Notice"; "Startup".severity = "Notice"; diff --git a/trace-dispatcher/src/Cardano/Logging/ConfigurationParser.hs b/trace-dispatcher/src/Cardano/Logging/ConfigurationParser.hs index f911d4b5756..ce8d5c5f74a 100644 --- a/trace-dispatcher/src/Cardano/Logging/ConfigurationParser.hs +++ b/trace-dispatcher/src/Cardano/Logging/ConfigurationParser.hs @@ -35,6 +35,7 @@ data ConfigRepresentation = ConfigRepresentation { , traceOptionMetricsPrefix :: Maybe Text , traceOptionPeerFrequency :: Maybe Int , traceOptionResourceFrequency :: Maybe Int + , traceOptionLedgerMetricsFrequency :: Maybe Int } deriving (Eq, Ord, Show) @@ -46,6 +47,7 @@ instance AE.FromJSON ConfigRepresentation where <*> obj .:? "TraceOptionMetricsPrefix" <*> obj .:? "TraceOptionPeerFrequency" <*> obj .:? "TraceOptionResourceFrequency" + <*> obj .:? "TraceOptionLedgerMetricsFrequency" parseJSON _ = mempty instance AE.ToJSON ConfigRepresentation where @@ -56,6 +58,7 @@ instance AE.ToJSON ConfigRepresentation where , "TraceOptionMetricsPrefix" .= traceOptionMetricsPrefix , "TraceOptionPeerFrequency" .= traceOptionPeerFrequency , "TraceOptionResourceFrequency" .= traceOptionResourceFrequency + , "TraceOptionLedgerMetricsFrequency" .= traceOptionLedgerMetricsFrequency ] type OptionsRepresentation = Map.Map Text ConfigOptionRep @@ -76,6 +79,7 @@ instance AE.FromJSON ConfigOptionRep where <*> obj .:? "detail" <*> obj .:? "backends" <*> obj .:? "maxFrequency" + parseJSON _ = mempty instance AE.ToJSON ConfigOptionRep where @@ -113,6 +117,7 @@ readConfigurationWithDefault fp defaultConf = do (tcMetricsPrefix fileConf <|> tcMetricsPrefix defaultConf) (tcPeerFrequency fileConf <|> tcPeerFrequency defaultConf) (tcResourceFrequency fileConf <|> tcResourceFrequency defaultConf) + (tcLedgerMetricsFrequency fileConf <|> tcLedgerMetricsFrequency defaultConf) -- | Parse the byteString as external representation and converts to internal -- representation @@ -145,6 +150,8 @@ parseRepresentation bs = transform (decodeEither' bs) (traceOptionMetricsPrefix cr) (traceOptionPeerFrequency cr) (traceOptionResourceFrequency cr) + (traceOptionLedgerMetricsFrequency cr) + -- | Convert from external to internal representation toConfigOptions :: ConfigOptionRep -> [ConfigOption] @@ -166,6 +173,7 @@ configToRepresentation traceConfig = (tcMetricsPrefix traceConfig) (tcPeerFrequency traceConfig) (tcResourceFrequency traceConfig) + (tcLedgerMetricsFrequency traceConfig) where toOptionRepresentation :: Map.Map [Text] [ConfigOption] -> Map.Map Text ConfigOptionRep diff --git a/trace-dispatcher/src/Cardano/Logging/Types.hs b/trace-dispatcher/src/Cardano/Logging/Types.hs index e2c21afe5ea..5907a9c8010 100644 --- a/trace-dispatcher/src/Cardano/Logging/Types.hs +++ b/trace-dispatcher/src/Cardano/Logging/Types.hs @@ -480,6 +480,8 @@ data TraceConfig = TraceConfig { , tcPeerFrequency :: Maybe Int -- | Optional resource trace frequency in milliseconds. , tcResourceFrequency :: Maybe Int + -- | Optional ledger metrics frequency in milliseconds. + , tcLedgerMetricsFrequency :: Maybe Int } deriving (Eq, Ord, Show) @@ -492,6 +494,7 @@ emptyTraceConfig = TraceConfig { , tcMetricsPrefix = Nothing , tcPeerFrequency = Just 2000 -- Every 2 seconds , tcResourceFrequency = Just 5000 -- Every five seconds + , tcLedgerMetricsFrequency = Just 1000 } --------------------------------------------------------------------------- diff --git a/trace-dispatcher/test/Cardano/Logging/Test/Unit/Configuration.hs b/trace-dispatcher/test/Cardano/Logging/Test/Unit/Configuration.hs index d07e8d93090..650a73bcbd9 100644 --- a/trace-dispatcher/test/Cardano/Logging/Test/Unit/Configuration.hs +++ b/trace-dispatcher/test/Cardano/Logging/Test/Unit/Configuration.hs @@ -60,6 +60,7 @@ config1 = TraceConfig { , tcPeerFrequency = Nothing , tcResourceFrequency = Nothing , tcMetricsPrefix = Nothing + , tcLedgerMetricsFrequency = Nothing } config2 :: TraceConfig @@ -78,6 +79,7 @@ config2 = TraceConfig { , tcPeerFrequency = Nothing , tcResourceFrequency = Nothing , tcMetricsPrefix = Nothing + , tcLedgerMetricsFrequency = Nothing } testConfig' :: diff --git a/trace-dispatcher/test/Cardano/Logging/Test/Unit/Documentation.hs b/trace-dispatcher/test/Cardano/Logging/Test/Unit/Documentation.hs index f8196d5fd58..0614707ad0f 100644 --- a/trace-dispatcher/test/Cardano/Logging/Test/Unit/Documentation.hs +++ b/trace-dispatcher/test/Cardano/Logging/Test/Unit/Documentation.hs @@ -43,5 +43,6 @@ config1 = TraceConfig { , tcPeerFrequency = Nothing , tcResourceFrequency = Nothing , tcMetricsPrefix = Just "cardano" + , tcLedgerMetricsFrequency = Nothing }