@@ -5,7 +5,10 @@ Description : Metrics based on the Observation module. See Observation.hs.
55-}
66module PostgREST.Metrics
77 ( init
8+ , ConnTrack
9+ , ConnStats (.. )
810 , MetricsState (.. )
11+ , connectionCounts
912 , observationMetrics
1013 , metricsToText
1114 ) where
@@ -17,12 +20,18 @@ import Prometheus
1720
1821import PostgREST.Observation
1922
20- import Protolude
23+ import Control.Arrow ((&&&) )
24+ import Data.Bitraversable (bisequenceA )
25+ import Data.Tuple.Extra (both )
26+ import Data.UUID (UUID )
27+ import qualified Focus
28+ import Protolude
29+ import qualified StmHamt.SizedHamt as SH
2130
2231data MetricsState =
2332 MetricsState {
2433 poolTimeouts :: Counter ,
25- poolAvailable :: Gauge ,
34+ connTrack :: ConnTrack ,
2635 poolWaiting :: Gauge ,
2736 poolMaxSize :: Gauge ,
2837 schemaCacheLoads :: Vector Label1 Counter ,
@@ -36,7 +45,7 @@ init :: Int -> IO MetricsState
3645init configDbPoolSize = do
3746 metricState <- MetricsState <$>
3847 register (counter (Info " pgrst_db_pool_timeouts_total" " The total number of pool connection timeouts" )) <*>
39- register (gauge ( Info " pgrst_db_pool_available " " Available connections in the pool " )) <*>
48+ register (Metric ((identity &&& dbPoolAvailable) <$> connectionTracker )) <*>
4049 register (gauge (Info " pgrst_db_pool_waiting" " Requests waiting to acquire a pool connection" )) <*>
4150 register (gauge (Info " pgrst_db_pool_max" " Max pool connections" )) <*>
4251 register (vector " status" $ counter (Info " pgrst_schema_cache_loads_total" " The total number of times the schema cache was loaded" )) <*>
@@ -46,20 +55,19 @@ init configDbPoolSize = do
4655 register (counter (Info " pgrst_jwt_cache_evictions_total" " The total number of JWT cache evictions" ))
4756 setGauge (poolMaxSize metricState) (fromIntegral configDbPoolSize)
4857 pure metricState
58+ where
59+ dbPoolAvailable = (pure . noLabelsGroup (Info " pgrst_db_pool_available" " Available connections in the pool" ) GaugeType . calcAvailable <$> ) . connectionCounts
60+ where
61+ calcAvailable = (configDbPoolSize - ) . inUse
62+ toSample name labels = Sample name labels . encodeUtf8 . show
63+ noLabelsGroup info sampleType = SampleGroup info sampleType . pure . toSample (metricName info) mempty
4964
5065-- Only some observations are used as metrics
5166observationMetrics :: MetricsState -> ObservationHandler
5267observationMetrics MetricsState {.. } obs = case obs of
5368 PoolAcqTimeoutObs -> do
5469 incCounter poolTimeouts
55- (HasqlPoolObs (SQL. ConnectionObservation _ status)) -> case status of
56- SQL. ReadyForUseConnectionStatus -> do
57- incGauge poolAvailable
58- SQL. InUseConnectionStatus -> do
59- decGauge poolAvailable
60- SQL. TerminatedConnectionStatus _ -> do
61- decGauge poolAvailable
62- SQL. ConnectingConnectionStatus -> pure ()
70+ (HasqlPoolObs sqlObs) -> trackConnections connTrack sqlObs
6371 PoolRequest ->
6472 incGauge poolWaiting
6573 PoolRequestFullfilled ->
@@ -77,3 +85,28 @@ observationMetrics MetricsState{..} obs = case obs of
7785
7886metricsToText :: IO LBS. ByteString
7987metricsToText = exportMetricsAsText
88+
89+ data ConnStats = ConnStats {
90+ connected :: Int ,
91+ inUse :: Int
92+ } deriving (Eq , Show )
93+
94+ data ConnTrack = ConnTrack { connTrackConnected :: SH. SizedHamt UUID , connTrackInUse :: SH. SizedHamt UUID }
95+
96+ connectionTracker :: IO ConnTrack
97+ connectionTracker = ConnTrack <$> SH. newIO <*> SH. newIO
98+
99+ trackConnections :: ConnTrack -> SQL. Observation -> IO ()
100+ trackConnections ConnTrack {.. } (SQL. ConnectionObservation uuid status) = case status of
101+ SQL. ReadyForUseConnectionStatus -> atomically $
102+ SH. insert identity uuid connTrackConnected *>
103+ SH. focus Focus. delete identity uuid connTrackInUse
104+ SQL. TerminatedConnectionStatus _ -> atomically $
105+ SH. focus Focus. delete identity uuid connTrackConnected *>
106+ SH. focus Focus. delete identity uuid connTrackInUse
107+ SQL. InUseConnectionStatus -> atomically $
108+ SH. insert identity uuid connTrackInUse
109+ _ -> mempty
110+
111+ connectionCounts :: ConnTrack -> IO ConnStats
112+ connectionCounts = atomically . fmap (uncurry ConnStats ) . bisequenceA . both SH. size . (connTrackConnected &&& connTrackInUse)
0 commit comments