diff --git a/cabal.project b/cabal.project index 25874410b4e..d7ffd548b58 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 2025-06-24T21:06:59Z - , cardano-haskell-packages 2025-09-18T12:21:32Z + , cardano-haskell-packages 2025-10-07T11:20:00Z packages: cardano-node diff --git a/flake.lock b/flake.lock index 088771904d5..5f8a68675b8 100644 --- a/flake.lock +++ b/flake.lock @@ -3,11 +3,11 @@ "CHaP": { "flake": false, "locked": { - "lastModified": 1758727647, - "narHash": "sha256-J0PlznW05SByIJZvP90JvFMvnHsP+Rs/qwLogpConI4=", + "lastModified": 1759837865, + "narHash": "sha256-g8SMcVN1v51Muz6a+xJkB92mPx1jsg+sjHKvQ3Wj/jY=", "owner": "intersectmbo", "repo": "cardano-haskell-packages", - "rev": "bbf172e0d11e3842e543df101dee223f05a2332e", + "rev": "9a46cacd941c108492cd4cee5d29735e8cd8ee65", "type": "github" }, "original": { @@ -104,6 +104,9 @@ "cardano-automation": { "inputs": { "flake-utils": "flake-utils", + "hackageNix": [ + "hackageNix" + ], "haskellNix": [ "haskellNix" ], @@ -112,11 +115,11 @@ ] }, "locked": { - "lastModified": 1750923974, - "narHash": "sha256-PXB1aro2KalRw6OZkcbICl6Ge7HB4yEl5O3epm9VZl8=", + "lastModified": 1759830003, + "narHash": "sha256-j5C9yqLzvOEfNcxBUP9QA2baIhWsk0vcLGrbpxCvND8=", "owner": "input-output-hk", "repo": "cardano-automation", - "rev": "64bf80a78102787790bac96075ef4109ff7de36e", + "rev": "d2017cf99d9c98b0acb4383d03ecfa8f9fdc2aac", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 922bde27b5d..8a74b4b182e 100644 --- a/flake.nix +++ b/flake.nix @@ -10,6 +10,7 @@ cardano-automation = { url = "github:input-output-hk/cardano-automation"; inputs = { + hackageNix.follows = "hackageNix"; haskellNix.follows = "haskellNix"; nixpkgs.follows = "nixpkgs"; }; diff --git a/trace-dispatcher/test/trace-dispatcher-prometheus-simple-test.hs b/trace-dispatcher/test/trace-dispatcher-prometheus-simple-test.hs new file mode 100644 index 00000000000..e226402c421 --- /dev/null +++ b/trace-dispatcher/test/trace-dispatcher-prometheus-simple-test.hs @@ -0,0 +1,70 @@ +import Cardano.Logging (metricsFormatter) +import Cardano.Logging.Configuration (configureTracers) +import Cardano.Logging.Prometheus.TCPServer (runPrometheusSimple) +import Cardano.Logging.Trace (traceWith) +import Cardano.Logging.Tracer.EKG (ekgTracer) +import Cardano.Logging.Types + +import Control.Concurrent (threadDelay) +import Control.Monad (unless) +import Data.Aeson +import qualified Data.Map.Internal as Map +import Data.Text (pack) +import Network.HTTP.Client (defaultManagerSettings, newManager) +import Network.HTTP.PrometheusTracker (scrapeOnce) +import Network.HTTP.PrometheusTracker.Types (MetricsMap (MM), MetricsValue (MVDouble)) +import System.Exit (die, exitSuccess) +import System.Metrics (newStore) + +newtype Measure = Measure Int + +instance LogFormatting Measure where + forMachine _dtal (Measure count) = + mconcat + [ "count" .= String (pack $ show count) + ] + asMetrics (Measure count) = + [ DoubleM "measure" (fromIntegral count)] + +instance MetaTrace Measure where + namespaceFor (Measure _count) = Namespace [] ["Count"] + severityFor (Namespace [] ["Count"]) _ = Just Info + privacyFor (Namespace [] ["Count"]) _ = Just Public + documentFor (Namespace [] ["Count"]) = Just "A counter" + metricsDocFor (Namespace [] ["Count"]) = + [("count", "an integer")] + allNamespaces = [Namespace [] ["Count"]] + +{- Thread #1: + - Run the prometheus simple server + - Trace a metric + - Spawn Thread #2 + - Wait + + Thread #2: + - Scrape the metrics + - Ensure that we see the expected metric and its value in the list +-} +main :: IO () +main = do + store <- newStore + let host = "localhost" + let port = 9090 + runPrometheusSimple store (True, Just host, port) >>= handleSpawn + pretracer <- ekgTracer emptyTraceConfig store + let tracer = metricsFormatter pretracer :: Trace IO Measure + confState <- emptyConfigReflection + configureTracers confState emptyTraceConfig [tracer] + traceWith tracer (Measure 42) + manager <- newManager defaultManagerSettings + _ <- threadDelay (3 * 1000000) + MM metricsMap <- scrapeOnce manager ("http://" <> host <> ":" <> show port <> "/metrics") + MVDouble value <- maybe (die "'measure' metric not found in the scape list") pure (Map.lookup "measure" metricsMap) + unless (value == 42) $ die ("Unexpected value: " <> show value) + putStrLn "Got correct metric value ✔" where + + handleSpawn :: Maybe String -> IO () + handleSpawn Nothing = pure () + handleSpawn (Just err) = do + putStrLn $ "Couldn't spawn prometheus-simple server!\n" <> err + exitSuccess diff --git a/trace-dispatcher/trace-dispatcher.cabal b/trace-dispatcher/trace-dispatcher.cabal index 6b6da149118..e2d4637b16e 100644 --- a/trace-dispatcher/trace-dispatcher.cabal +++ b/trace-dispatcher/trace-dispatcher.cabal @@ -98,6 +98,26 @@ library else build-depends: unix +test-suite trace-dispatcher-prometheus-simple-test + import: project-config + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: trace-dispatcher-prometheus-simple-test.hs + build-depends: base >=4.12 && <5 + , aeson + , cardano-prometheus-tracker + , containers + , ekg-core + , http-client + , text + , trace-dispatcher + + ghc-options: + -threaded + -Wunused-packages + + if !(os(linux) || os(darwin) || os(freebsd)) + buildable: False test-suite trace-dispatcher-test import: project-config @@ -109,35 +129,38 @@ test-suite trace-dispatcher-test Cardano.Logging.Test.Config Cardano.Logging.Test.Tracer Cardano.Logging.Test.Script - Cardano.Logging.Test.Unit.TestObjects Cardano.Logging.Test.Unit.Aggregation - Cardano.Logging.Test.Unit.Trivial - Cardano.Logging.Test.Unit.Routing - Cardano.Logging.Test.Unit.EKG Cardano.Logging.Test.Unit.Configuration Cardano.Logging.Test.Unit.DataPoint - Cardano.Logging.Test.Unit.FrequencyLimiting Cardano.Logging.Test.Unit.Documentation + Cardano.Logging.Test.Unit.EKG + Cardano.Logging.Test.Unit.FrequencyLimiting + Cardano.Logging.Test.Unit.Routing + Cardano.Logging.Test.Unit.TestObjects + Cardano.Logging.Test.Unit.Trivial build-depends: base >=4.12 && <5 , aeson + , async , bytestring , containers , deepseq , ekg-core , generic-data , hostname - , text , stm , tasty , tasty-hunit , tasty-quickcheck + , text , time , trace-dispatcher , unordered-containers , utf8-string + , unix-compat , yaml , QuickCheck + , cardano-prometheus-tracker benchmark trace-dispatcher-bench