Skip to content

Commit b9120e3

Browse files
committed
cardano-tracer: retrofit EKG listing with JSON response
1 parent 1bb9e7e commit b9120e3

File tree

4 files changed

+28
-19
lines changed

4 files changed

+28
-19
lines changed

cardano-tracer/src/Cardano/Tracer/Environment.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ data TracerEnv = TracerEnv
3535
, teReforwardTraceObjects :: !([TraceObject] -> IO ())
3636
, teRegistry :: !HandleRegistry
3737
, teStateDir :: !(Maybe FilePath)
38-
, teMetricsHelp :: !([(Text, Builder)])
38+
, teMetricsHelp :: ![(Text, Builder)]
3939
}
4040

4141
#if RTVIEW

cardano-tracer/src/Cardano/Tracer/Handlers/Metrics/Monitoring.hs

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,23 @@ module Cardano.Tracer.Handlers.Metrics.Monitoring
66
( runMonitoringServer
77
) where
88

9-
import Prelude hiding (head)
109
import Cardano.Tracer.Configuration
1110
import Cardano.Tracer.Environment
11+
import Cardano.Tracer.Handlers.Metrics.Utils
1212
import Cardano.Tracer.MetaTrace
1313
import Cardano.Tracer.Types
1414

15-
import qualified Data.Text as T
16-
import System.Time.Extra (sleep)
15+
import Prelude hiding (head)
1716

18-
import qualified Cardano.Tracer.Handlers.Metrics.Utils as Utils
19-
import Cardano.Tracer.Handlers.Metrics.Utils (renderListOfConnectedNodes)
17+
import Data.ByteString as ByteString (ByteString, isInfixOf)
2018
import Data.ByteString.Builder (stringUtf8)
19+
import qualified Data.Text as T
2120
import Network.HTTP.Types
2221
import Network.Wai
23-
import Network.Wai.Handler.Warp (runSettings, defaultSettings)
22+
import Network.Wai.Handler.Warp (defaultSettings, runSettings)
2423
import qualified System.Metrics as EKG
2524
import System.Remote.Monitoring.Wai
25+
import System.Time.Extra (sleep)
2626

2727
-- | 'ekg' package allows to run only one EKG server, to display only one web page
2828
-- for particular EKG.Store. Since 'cardano-tracer' can be connected to any number
@@ -37,7 +37,7 @@ import System.Remote.Monitoring.Wai
3737
runMonitoringServer
3838
:: TracerEnv
3939
-> Endpoint -- ^ (web page with list of connected nodes, EKG web page).
40-
-> IO Utils.RouteDictionary
40+
-> IO RouteDictionary
4141
-> IO ()
4242
runMonitoringServer TracerEnv{teTracer} endpoint computeRoutes_autoUpdate = do
4343
-- Pause to prevent collision between "Listening"-notifications from servers.
@@ -50,27 +50,35 @@ runMonitoringServer TracerEnv{teTracer} endpoint computeRoutes_autoUpdate = do
5050
runSettings (setEndpoint endpoint defaultSettings) do
5151
renderEkg dummyStore computeRoutes_autoUpdate
5252

53-
renderEkg :: EKG.Store -> IO Utils.RouteDictionary -> Application
53+
renderEkg :: EKG.Store -> IO RouteDictionary -> Application
5454
renderEkg dummyStore computeRoutes_autoUpdate request send = do
55-
routeDictionary :: Utils.RouteDictionary <-
55+
routeDictionary :: RouteDictionary <-
5656
computeRoutes_autoUpdate
5757

58-
let nodeNames :: [NodeName]
59-
nodeNames = Utils.nodeNames routeDictionary
58+
let acceptHeader :: Maybe ByteString
59+
acceptHeader = lookup hAccept $ requestHeaders request
60+
61+
let wantsJson :: Bool
62+
wantsJson = all @Maybe ("application/json" `ByteString.isInfixOf`) acceptHeader
6063

6164
case pathInfo request of
65+
6266
[] ->
63-
send $ responseLBS status200 [] (renderListOfConnectedNodes "EKG metrics" nodeNames)
67+
send $ uncurry (responseLBS status200) $ if wantsJson
68+
then (contentHdrJSON , renderJson routeDictionary)
69+
else (contentHdrUtf8Html, renderListOfConnectedNodes "EKG metrics" routeDictionary)
70+
6471
route:rest
6572
| Just (store :: EKG.Store, _ :: NodeName)
66-
<- lookup route (Utils.getRouteDictionary routeDictionary)
73+
<- lookup route (getRouteDictionary routeDictionary)
6774
-> monitor store request { pathInfo = rest } send
6875
-- all endings in ekg-wai's asset/ folder
76+
6977
| any (`T.isSuffixOf` route) [".html", ".css", ".js", ".png"]
7078
-- we actually need an empty dummy store here, as we're sure monitor will internally invoke the staticApp to serve the assets
7179
-> monitor dummyStore request send
80+
7281
| otherwise
73-
-> send $ responseBuilder status404 [] do
82+
-> send $ responseBuilder status404 contentHdrUtf8Text do
7483
"Not found: "
7584
<> stringUtf8 (show route)
76-
<> "\n" <> stringUtf8 (show nodeNames)

cardano-tracer/src/Cardano/Tracer/Handlers/Metrics/Prometheus.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ renderPrometheus computeRoutes_autoUpdate metricsComp helpTextDict request send
9898
[] ->
9999
send $ uncurry (responseLBS status200) $ if wantsJson
100100
then (contentHdrJSON , renderJson routeDictionary)
101-
else (contentHdrUtf8Html, renderListOfConnectedNodes "Prometheus metrics" (nodeNames routeDictionary))
101+
else (contentHdrUtf8Html, renderListOfConnectedNodes "Prometheus metrics" routeDictionary)
102102

103103
route:_
104104
| Just (store :: EKG.Store, _) <- lookup route (getRouteDictionary routeDictionary)

cardano-tracer/src/Cardano/Tracer/Handlers/Metrics/Utils.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{-# LANGUAGE NamedFieldPuns #-}
22
{-# LANGUAGE OverloadedStrings #-}
3+
{-# LANGUAGE ViewPatterns #-}
34

45
module Cardano.Tracer.Handlers.Metrics.Utils
56
( module Cardano.Tracer.Handlers.Metrics.Utils
@@ -34,8 +35,8 @@ newtype RouteDictionary = RouteDictionary
3435
{ getRouteDictionary :: [(Text, (EKG.Store, NodeName))]
3536
}
3637

37-
renderListOfConnectedNodes :: Text -> [NodeName] -> Lazy.ByteString
38-
renderListOfConnectedNodes metricsTitle nodenames
38+
renderListOfConnectedNodes :: Text -> RouteDictionary -> Lazy.ByteString
39+
renderListOfConnectedNodes metricsTitle (nodeNames -> nodenames)
3940
| [] <- nodenames
4041
= "There are no connected nodes yet."
4142
| otherwise

0 commit comments

Comments
 (0)