@@ -35,21 +35,22 @@ import qualified Network.Wai as Wai
3535import qualified Network.Wai.Handler.Warp as Warp
3636import qualified Network.Wai.Header as WaiHeader
3737
38- import qualified PostgREST.Admin as Admin
39- import qualified PostgREST.ApiRequest as ApiRequest
40- import qualified PostgREST.AppState as AppState
41- import qualified PostgREST.Auth as Auth
42- import qualified PostgREST.Cors as Cors
43- import qualified PostgREST.Error as Error
44- import qualified PostgREST.Listener as Listener
45- import qualified PostgREST.MainTx as MainTx
46- import qualified PostgREST.Plan as Plan
47- import qualified PostgREST.Query as Query
48- import qualified PostgREST.Response as Response
49- import qualified PostgREST.Unix as Unix (installSignalHandlers )
38+ import qualified PostgREST.Admin as Admin
39+ import qualified PostgREST.ApiRequest as ApiRequest
40+ import qualified PostgREST.AppState as AppState
41+ import qualified PostgREST.Auth as Auth
42+ import qualified PostgREST.Cors as Cors
43+ import qualified PostgREST.Error as Error
44+ import qualified PostgREST.Listener as Listener
45+ import qualified PostgREST.MainTx as MainTx
46+ import qualified PostgREST.OpenTelemetry as OTel
47+ import qualified PostgREST.Plan as Plan
48+ import qualified PostgREST.Query as Query
49+ import qualified PostgREST.Response as Response
50+ import qualified PostgREST.Unix as Unix (installSignalHandlers )
5051
5152import PostgREST.ApiRequest (ApiRequest (.. ))
52- import PostgREST.AppState (AppState )
53+ import PostgREST.AppState (AppState , getOTelMaybeTracer )
5354import PostgREST.Auth.Types (AuthResult (.. ))
5455import PostgREST.Config (AppConfig (.. ))
5556import PostgREST.Error (Error )
@@ -71,7 +72,7 @@ import qualified Network.Socket as NS
7172import PostgREST.Unix (createAndBindDomainSocket )
7273import Protolude hiding (Handler )
7374
74- run :: AppState -> IO ()
75+ run :: HasCallStack => AppState -> IO ()
7576run appState = do
7677 conf <- AppState. getConfig appState
7778
@@ -119,11 +120,12 @@ serverSettings AppConfig{..} =
119120 & setServerName (" postgrest/" <> prettyVersion)
120121
121122-- | PostgREST application
122- postgrest :: AppState. AppState -> IO () -> Wai. Application
123+ postgrest :: HasCallStack => AppState. AppState -> IO () -> Wai. Application
123124postgrest appState connWorker =
125+ (OTel. oTelMiddleware . getOTelMaybeTracer) appState .
124126 traceHeaderMiddleware appState .
125127 Cors. middleware appState $
126- \ req respond -> do
128+ \ req respond -> OTel. inSpanMDefault (getOTelMaybeTracer appState) " request " $ do
127129 appConf@ AppConfig {.. } <- AppState. getConfig appState -- the config must be read again because it can reload
128130 maybeSchemaCache <- AppState. getSchemaCache appState
129131
@@ -164,7 +166,8 @@ postgrest appState connWorker =
164166 ResponseObs user req (Wai. responseStatus resp) (WaiHeader. contentLength $ Wai. responseHeaders resp)
165167
166168postgrestResponse
167- :: AppState. AppState
169+ :: HasCallStack
170+ => AppState. AppState
168171 -> AppConfig
169172 -> Maybe SchemaCache
170173 -> Maybe Double
@@ -186,14 +189,14 @@ postgrestResponse appState conf@AppConfig{..} maybeSchemaCache jwtTime authResul
186189
187190 body <- lift $ Wai. strictRequestBody req
188191
189- (parseTime, apiReq@ ApiRequest {.. }) <- withTiming conf $ liftEither . mapLeft Error. ApiRequestErr $ ApiRequest. userApiRequest conf prefs req body
190- (planTime, plan) <- withTiming conf $ liftEither $ Plan. actionPlan iAction conf apiReq sCache
192+ (parseTime, apiReq@ ApiRequest {.. }) <- withRequestPhase " parse " $ liftEither . mapLeft Error. ApiRequestErr $ ApiRequest. userApiRequest conf prefs req body
193+ (planTime, plan) <- withRequestPhase " plan " $ liftEither $ Plan. actionPlan iAction conf apiReq sCache
191194
192195 let mainQ = Query. mainQuery plan conf apiReq authResult configDbPreRequest
193196 tx = MainTx. mainTx mainQ conf authResult apiReq plan sCache
194197 obsQuery s = when configLogQuery $ observer $ QueryObs mainQ s
195198
196- (txTime, txResult) <- withTiming conf $ do
199+ (txTime, txResult) <- withRequestPhase " query " $ do
197200 case tx of
198201 MainTx. NoDbTx r -> pure r
199202 MainTx. DbTx {.. } -> do
@@ -206,7 +209,7 @@ postgrestResponse appState conf@AppConfig{..} maybeSchemaCache jwtTime authResul
206209 lift $ whenLeft eitherResp $ obsQuery . Error. status
207210 liftEither eitherResp
208211
209- (respTime, resp) <- withTiming conf $ do
212+ (respTime, resp) <- withRequestPhase " response " $ do
210213 let response = Response. actionResponse txResult apiReq (T. decodeUtf8 prettyVersion, docsVersion) conf sCache
211214 status' = either Error. status Response. pgrstStatus response
212215
@@ -230,6 +233,13 @@ postgrestResponse appState conf@AppConfig{..} maybeSchemaCache jwtTime authResul
230233 varyHeaderPresent :: [HTTP. Header ] -> Bool
231234 varyHeaderPresent = any (\ (h, _v) -> h == HTTP. hVary)
232235
236+ withOTel :: HasCallStack => Text -> ExceptT e IO a -> ExceptT e IO a
237+ withOTel label = do
238+ OTel. inSpanMDefault (getOTelMaybeTracer appState) label
239+
240+ withRequestPhase :: HasCallStack => Text -> ExceptT e IO a -> ExceptT e IO (Maybe Double , a )
241+ withRequestPhase label = withOTel label . withTiming conf
242+
233243withTiming :: AppConfig -> ExceptT e IO a -> ExceptT e IO (Maybe Double , a )
234244withTiming AppConfig {configServerTimingEnabled} f = if configServerTimingEnabled
235245 then do
0 commit comments