Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
description: Support --prometheus-listen-address and --prometheus-listen-port
kind:
- feature
pr: 6723
project: cardano-testnet
28 changes: 23 additions & 5 deletions cardano-testnet/src/Parsers/Cardano.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import Data.IP (IP)
import qualified Data.List as L
import Data.List.NonEmpty (NonEmpty ((:|)))
import Data.Maybe
import Data.String (fromString)
import Data.Word (Word64)
import Network.Socket (PortNumber)
import Options.Applicative (CommandFields, Mod, Parser)
Expand Down Expand Up @@ -152,11 +153,28 @@ portReader = OA.eitherReader $ \token -> do
pure $ fromIntegral port

pEnableTracer :: Parser TraceSupport
pEnableTracer = OA.flag TraceDisabled TraceEnabled
( OA.long "enable-tracer"
<> OA.help "[EXPERIMENTAL] Enable cardano-tracer support on all of testnet nodes. Looks for cardano-tracer via the environment variable CARDANO_TRACER, falling back to looking into PATH. This will start a Prometheus server at 127.0.0.1, on a port that will be reported at runtime."
<> OA.showDefault
)
pEnableTracer = OA.asum
[ OA.flag' ()
( OA.long "enable-tracer"
<> OA.help "[EXPERIMENTAL] Enable cardano-tracer support on all of testnet nodes. Looks for cardano-tracer via the environment variable CARDANO_TRACER, falling back to looking into PATH. This will start a Prometheus server at 127.0.0.1 and a random port unless --prometheus-listen-address and --prometheus-listen-port are given."
)
*> (TraceEnabled
<$> OA.option ipReader
( OA.long "prometheus-listen-address"
<> OA.metavar "IP"
<> OA.value (fromString "127.0.0.1")
<> OA.showDefault
<> OA.help "IP address the Prometheus server will listen on. Requires --enable-tracer."
)
<*> OA.optional
(OA.option portReader
( OA.long "prometheus-listen-port"
<> OA.metavar "PORT"
<> OA.help "Base port for Prometheus. A random free port is used when omitted. Requires --enable-tracer."
)
))
, pure TraceDisabled
]

pKesSource :: Parser PraosCredentialsSource
pKesSource = OA.flag UseKesKeyFile UseKesSocket
Expand Down
34 changes: 21 additions & 13 deletions cardano-testnet/src/Testnet/CardanoTracer.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DisambiguateRecordFields #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE NumericUnderscores #-}
{-# LANGUAGE OverloadedStrings #-}
Expand All @@ -26,6 +26,7 @@ import Control.Monad.Trans.Except (runExceptT)
import Control.Monad.Trans.Resource (MonadResource)
import Data.Aeson (encodeFile)
import Data.List.NonEmpty (NonEmpty(..))
import Data.IP (IP)
import GHC.Stack (HasCallStack)
import qualified GHC.Stack as GHC
import Network.Socket (PortNumber)
Expand All @@ -46,18 +47,20 @@ import RIO (runRIO, throwString, unless)
-- | Configuration record for invoking 'startCardanoTracer'.
data CardanoTracerConf = CardanoTracerConf
{ tempAbsPath :: FilePath -- ^ Path to the testnet's temp directory.
, prometheusIP :: IP -- ^ Attempt to bind prometheus on this IP.
, prometheusPort :: Maybe PortNumber -- ^ Attempt to bind prometheus to the port, if given. Choose a random port otherwise.
, testnetMagic :: Int -- ^ The magic number for the testnet.
, logFormat :: LogFormat -- ^ The format for logs produced by cardano-tracer.
} deriving (Eq, Show)

mkConfig :: CardanoTracerConf -> Int -> FilePath -> Sprocket -> TracerConfig
mkConfig CardanoTracerConf { testnetMagic, logFormat } port logFile sprocket = TracerConfig
mkConfig CardanoTracerConf { testnetMagic, logFormat, prometheusIP } port logFile sprocket = TracerConfig
{ networkMagic = fromIntegral testnetMagic
, network = AcceptAt $ LocalPipe $ sprocketArgumentName sprocket
, loRequestNum = Nothing
, ekgRequestFreq = Nothing
, hasEKG = Nothing
, hasPrometheus = Just $ Endpoint "127.0.0.1" port $ Just False
, hasPrometheus = Just $ Endpoint (show prometheusIP) port $ Just False
, hasTimeseries = Nothing
, tlsCertificate = Nothing
, hasForwarding = Nothing
Expand Down Expand Up @@ -91,7 +94,7 @@ startCardanoTracer
=> MonadCatch m
=> CardanoTracerConf
-> m CardanoTracerRuntime
startCardanoTracer conf@CardanoTracerConf{tempAbsPath} = GHC.withFrozenCallStack $ do
startCardanoTracer conf@CardanoTracerConf{tempAbsPath, prometheusPort = mPort} = GHC.withFrozenCallStack $ do
let tmpPath = TmpAbsolutePath tempAbsPath
logDir = makeLogDir tmpPath
tempBaseAbsPath = makeTmpBaseAbsPath tmpPath
Expand All @@ -108,16 +111,21 @@ startCardanoTracer conf@CardanoTracerConf{tempAbsPath} = GHC.withFrozenCallStack
hNodeStdout <- liftIO $ IO.openFile nodeStdoutFile IO.WriteMode
hNodeStderr <- liftIO $ IO.openFile nodeStderrFile IO.WriteMode

[prometheusPortNo] <- liftIO $ IO.allocateRandomPorts 1
let prometheusPort = fromIntegral prometheusPortNo
-- The port number if it is obtained using 'H.randomPort', it is firstly bound to and then closed. The closing
-- and release in the operating system is done asynchronously and can be slow. Here we wait until the port

let portWaitTimeout = 45
isClosed <- liftIOAnnotated $ Ping.waitForPortClosed portWaitTimeout 0.1 prometheusPort
unless isClosed $
throwString $ "Port is still in use after " ++ show portWaitTimeout ++ " seconds before starting tracer: " <> show prometheusPortNo
liftIO $ encodeFile configFile $ mkConfig conf prometheusPortNo logDir sprocket
prometheusPort <-
case mPort of
Just port -> pure port
Nothing -> do
[prometheusPortNo] <- liftIO $ IO.allocateRandomPorts 1
let prometheusPort = fromIntegral prometheusPortNo
-- The port number if it is obtained using 'H.randomPort', it is firstly bound to and then closed. The closing
-- and release in the operating system is done asynchronously and can be slow. Here we wait until the port
isClosed <- liftIOAnnotated $ Ping.waitForPortClosed portWaitTimeout 0.1 prometheusPort
unless isClosed $
throwString $ "Port is still in use after " ++ show portWaitTimeout ++ " seconds before starting tracer: " <> show prometheusPort
pure prometheusPort

liftIO $ encodeFile configFile $ mkConfig conf (fromIntegral prometheusPort) logDir sprocket

cp <- runRIO () $ procFlex "cardano-tracer" "CARDANO_TRACER"
[ "--config", configFile
Expand Down
4 changes: 3 additions & 1 deletion cardano-testnet/src/Testnet/Start/Cardano.hs
Original file line number Diff line number Diff line change
Expand Up @@ -289,10 +289,12 @@ cardanoTestnet
-- alongside the nodes (see 'interruptNodesOnSigINT' below).
(nodeConfigFile', mTracer) <- case cardanoEnableTracer of
TraceDisabled -> pure (nodeConfigFile, Nothing)
TraceEnabled -> do
TraceEnabled ip mport -> do
cfgFile' <- liftIOAnnotated $ enableTraceForwarding nodeConfigFile
tracerRuntime <- startCardanoTracer $ CardanoTracerConf
{ tempAbsPath = tmpAbsPath
, prometheusIP = ip
, prometheusPort = mport
, testnetMagic = testnetMagic
, logFormat = ForMachine
}
Expand Down
7 changes: 6 additions & 1 deletion cardano-testnet/src/Testnet/Start/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,12 @@ instance Default RpcHttpOptions where

data TraceSupport
= TraceDisabled -- ^ Do not enable tracing
| TraceEnabled -- ^ Enable tracing over cardano-tracer
| TraceEnabled
-- ^ Enable tracing over cardano-tracer.
IP
-- ^ Bind prometheus on this IP.
(Maybe PortNumber)
-- ^ Using this port for prometheus, when given. Choose randomly otherwise.
deriving (Eq, Show)

-- | Options for creating a testnet environment (genesis files, topology, ports).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ Usage: cardano-testnet cardano
[ --enable-grpc
| --enable-grpc-http [--grpc-listen-address IP] [--grpc-listen-port-base PORT]
]
[--enable-tracer]
[--enable-tracer
[--prometheus-listen-address IP]
[--prometheus-listen-port PORT]]
[--use-kes-agent]
[--disable-chain-stall-watchdog]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ Usage: cardano-testnet cardano
[ --enable-grpc
| --enable-grpc-http [--grpc-listen-address IP] [--grpc-listen-port-base PORT]
]
[--enable-tracer]
[--enable-tracer
[--prometheus-listen-address IP]
[--prometheus-listen-port PORT]]
[--use-kes-agent]
[--disable-chain-stall-watchdog]

Expand Down Expand Up @@ -81,8 +83,15 @@ Available options:
of testnet nodes. Looks for cardano-tracer via the
environment variable CARDANO_TRACER, falling back to
looking into PATH. This will start a Prometheus
server at 127.0.0.1, on a port that will be reported
at runtime.
server at 127.0.0.1 and a random port unless
--prometheus-listen-address and
--prometheus-listen-port are given.
--prometheus-listen-address IP
IP address the Prometheus server will listen on.
Requires --enable-tracer. (default: 127.0.0.1)
--prometheus-listen-port PORT
Base port for Prometheus. A random free port is used
when omitted. Requires --enable-tracer.
--use-kes-agent Get Praos block forging credentials from kes-agent
via the default socket path
--disable-chain-stall-watchdog
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ hprop_enable_tracer :: H.Property
hprop_enable_tracer = integrationRetryWorkspace 2 "enable-tracer" $ \tmpDir -> H.runWithDefaultWatchdog_ $ do

let creationOptions = def
runtimeOptions = def { runtimeEnableTracer = TraceEnabled }
runtimeOptions = def { runtimeEnableTracer = TraceEnabled "127.0.0.1" Nothing }

conf <- mkConf tmpDir
runtime <- createAndRunTestnet creationOptions runtimeOptions conf
Expand Down
Loading