From fe54a28b8c547f83a4cb30d2b65df39ef65ca63c Mon Sep 17 00:00:00 2001 From: Andrei Dziahel Date: Tue, 2 Jan 2024 17:38:28 +0100 Subject: [PATCH] otel: add opentelemetry traces * Introduces producing OpenTelemetry traces with hs-opentelemetry. * Adds OTel spans over the whole application loop and over each request processing phase * Preliminary OTel tracing support in spec tests --- .github/workflows/test.yaml | 2 + cabal.project.freeze | 2 +- nix/overlays/haskell-packages.nix | 65 ++++++++++++++++++++++++ postgrest.cabal | 5 ++ src/PostgREST/App.hs | 76 +++++++++++++++------------- src/PostgREST/AppState.hs | 18 +++++-- src/PostgREST/CLI.hs | 16 +++--- src/PostgREST/OpenTelemetry.hs | 22 ++++++++ stack-21.7.yaml | 13 +++++ stack-21.7.yaml.lock | 84 +++++++++++++++++++++++++++++++ stack.yaml | 12 +++++ stack.yaml.lock | 81 ++++++++++++++++++++++++++++- test/memory/memory-tests.sh | 17 ++++--- test/spec/Main.hs | 5 +- 14 files changed, 358 insertions(+), 60 deletions(-) create mode 100644 src/PostgREST/OpenTelemetry.hs diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index c7c892e429..9393b62f3e 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -127,6 +127,8 @@ jobs: with: prefix: v - name: Run loadtest + env: + OTEL_TRACES_SAMPLER: "always_off" run: | postgrest-loadtest-against main ${{ steps.get-latest-tag.outputs.tag }} postgrest-loadtest-report > loadtest/loadtest.md diff --git a/cabal.project.freeze b/cabal.project.freeze index 9a875ecec9..fc52d1eed8 100644 --- a/cabal.project.freeze +++ b/cabal.project.freeze @@ -1 +1 @@ -index-state: hackage.haskell.org 2024-11-10T13:08:54Z +index-state: hackage.haskell.org 2024-11-25T13:43:26Z diff --git a/nix/overlays/haskell-packages.nix b/nix/overlays/haskell-packages.nix index 917ab2478a..42d1972b48 100644 --- a/nix/overlays/haskell-packages.nix +++ b/nix/overlays/haskell-packages.nix @@ -69,6 +69,71 @@ let { postgresql = super.libpq; }); + + hs-opentelemetry-sdk = lib.dontCheck (prev.callHackageDirect + { + pkg = "hs-opentelemetry-sdk"; + ver = "0.1.0.0"; + sha256 = "sha256-kg6iYyEW2a/qb7FFXbph/xKPFW/6Wqhl5P9NZotgbVs="; + } + { }); + hs-opentelemetry-propagator-datadog = lib.dontCheck (prev.callHackageDirect + { + pkg = "hs-opentelemetry-propagator-datadog"; + ver = "0.0.1.0"; + sha256 = "sha256-V2FOsdyrR3X44FILTRpDIDNghc5vPIDx7z0CUGyJXQk="; + } + { }); + hs-opentelemetry-exporter-otlp = lib.dontCheck (prev.callHackageDirect + { + pkg = "hs-opentelemetry-exporter-otlp"; + ver = "0.1.0.0"; + sha256 = "sha256-Y0ihGMDIu3GcN7wkjnth4z72WfyBUmqSNrJEvoGxi6M="; + } + { }); + hs-opentelemetry-instrumentation-wai = lib.dontCheck (prev.callHackageDirect + { + pkg = "hs-opentelemetry-instrumentation-wai"; + ver = "0.1.1.0"; + sha256 = "sha256-9jz06jEOAfuDtk7RS7cntCDPmORukeS7hHYP04vxGXA="; + } + { }); + hs-opentelemetry-api = lib.dontCheck (prev.callHackageDirect + { + pkg = "hs-opentelemetry-api"; + ver = "0.2.0.0"; + sha256 = "sha256-IgyI6J9ZiN9x0A/Jdp9fsdhJTqX3AJyTLlKmk8hFsTk="; + } + { }); + hs-opentelemetry-propagator-b3 = lib.dontCheck (prev.callHackageDirect + { + pkg = "hs-opentelemetry-propagator-b3"; + ver = "0.0.1.2"; + sha256 = "sha256-hUk4f/xngG5NujSJGGb7lWawNE6EAbvw/8krKsGGsPY="; + } + { }); + hs-opentelemetry-propagator-w3c = lib.dontCheck (prev.callHackageDirect + { + pkg = "hs-opentelemetry-propagator-w3c"; + ver = "0.0.1.4"; + sha256 = "sha256-Rq+bcerTD4Pqzr1sznvoOtkKanlV+0Blq3EXXN2HQuU="; + } + { }); + hs-opentelemetry-otlp = lib.dontCheck (prev.callHackageDirect + { + pkg = "hs-opentelemetry-otlp"; + ver = "0.1.0.0"; + sha256 = "sha256-xZFIlyx2BKnwo6XCblCZTukNsjv/uG5T3u8uKlKJ1yc="; + } + { }); + hs-opentelemetry-utils-exceptions = lib.dontCheck (prev.callHackageDirect + { + pkg = "hs-opentelemetry-utils-exceptions"; + ver = "0.2.0.1"; + sha256 = "sha256-gukjbleRa4PKWcyBXC1J0kSQzohF5Or+ayvp5wxrzT0="; + } + { }); + }; in { diff --git a/postgrest.cabal b/postgrest.cabal index 092a98de82..7f28a9c336 100644 --- a/postgrest.cabal +++ b/postgrest.cabal @@ -73,6 +73,7 @@ library PostgREST.Query.QueryBuilder PostgREST.Query.SqlFragment PostgREST.Query.Statements + PostgREST.OpenTelemetry PostgREST.Plan PostgREST.Plan.CallPlan PostgREST.Plan.MutatePlan @@ -116,6 +117,9 @@ library , hasql-transaction >= 1.0.1 && < 1.1 , heredoc >= 0.2 && < 0.3 , http-types >= 0.12.2 && < 0.13 + , hs-opentelemetry-sdk >= 0.1.0.0 && < 0.2.0.0 + , hs-opentelemetry-instrumentation-wai + , hs-opentelemetry-utils-exceptions , insert-ordered-containers >= 0.2.2 && < 0.3 , iproute >= 1.7.0 && < 1.8 , jose-jwt >= 0.9.6 && < 0.11 @@ -263,6 +267,7 @@ test-suite spec , hasql-pool >= 1.0.1 && < 1.1 , hasql-transaction >= 1.0.1 && < 1.1 , heredoc >= 0.2 && < 0.3 + , hs-opentelemetry-sdk >= 0.1.0.0 && < 0.2.0.0 , hspec >= 2.3 && < 2.12 , hspec-wai >= 0.10 && < 0.12 , hspec-wai-json >= 0.10 && < 0.12 diff --git a/src/PostgREST/App.hs b/src/PostgREST/App.hs index 99febebaca..49188cc3b2 100644 --- a/src/PostgREST/App.hs +++ b/src/PostgREST/App.hs @@ -41,11 +41,11 @@ import qualified PostgREST.Response as Response import qualified PostgREST.Unix as Unix (installSignalHandlers) import PostgREST.ApiRequest (ApiRequest (..)) -import PostgREST.AppState (AppState) +import PostgREST.AppState (AppState, getOTelTracer) import PostgREST.Auth (AuthResult (..)) import PostgREST.Config (AppConfig (..), LogLevel (..)) import PostgREST.Config.PgVersion (PgVersion (..)) -import PostgREST.Error (Error) +import PostgREST.Error (Error (..)) import PostgREST.Network (resolveHost) import PostgREST.Observation (Observation (..)) import PostgREST.Response.Performance (ServerTiming (..), @@ -53,12 +53,15 @@ import PostgREST.Response.Performance (ServerTiming (..), import PostgREST.SchemaCache (SchemaCache (..)) import PostgREST.Version (docsVersion, prettyVersion) -import qualified Data.ByteString.Char8 as BS -import qualified Data.List as L -import qualified Network.HTTP.Types as HTTP -import qualified Network.Socket as NS -import Protolude hiding (Handler) -import System.TimeIt (timeItT) +import qualified Data.ByteString.Char8 as BS +import qualified Data.List as L +import qualified Network.HTTP.Types as HTTP +import qualified Network.Socket as NS +import OpenTelemetry.Instrumentation.Wai (newOpenTelemetryWaiMiddleware) +import OpenTelemetry.Trace (defaultSpanArguments) +import OpenTelemetry.Utils.Exceptions (inSpanM) +import Protolude hiding (Handler) +import System.TimeIt (timeItT) type Handler = ExceptT Error @@ -84,7 +87,9 @@ run appState = do host <- resolveHost $ AppState.getSocketREST appState observer $ AppServerPortObs (fromJust host) port - Warp.runSettingsSocket (serverSettings conf) (AppState.getSocketREST appState) app + oTelMWare <- newOpenTelemetryWaiMiddleware + + Warp.runSettingsSocket (serverSettings conf) (AppState.getSocketREST appState) (oTelMWare app) serverSettings :: AppConfig -> Warp.Settings serverSettings AppConfig{..} = @@ -102,27 +107,28 @@ postgrest logLevel appState connWorker = Logger.middleware logLevel Auth.getRole $ -- fromJust can be used, because the auth middleware will **always** add -- some AuthResult to the vault. - \req respond -> case fromJust $ Auth.getResult req of - Left err -> respond $ Error.errorResponseFor err - Right authResult -> do - appConf <- AppState.getConfig appState -- the config must be read again because it can reload - maybeSchemaCache <- AppState.getSchemaCache appState - pgVer <- AppState.getPgVersion appState - - let - eitherResponse :: IO (Either Error Wai.Response) - eitherResponse = - runExceptT $ postgrestResponse appState appConf maybeSchemaCache pgVer authResult req - - response <- either Error.errorResponseFor identity <$> eitherResponse - -- Launch the connWorker when the connection is down. The postgrest - -- function can respond successfully (with a stale schema cache) before - -- the connWorker is done. - when (isServiceUnavailable response) connWorker - resp <- do - delay <- AppState.getNextDelay appState - return $ addRetryHint delay response - respond resp + \req respond -> inSpanM (getOTelTracer appState) "respond" defaultSpanArguments $ + case fromJust $ Auth.getResult req of + Left err -> respond $ Error.errorResponseFor err + Right authResult -> do + appConf <- AppState.getConfig appState -- the config must be read again because it can reload + maybeSchemaCache <- AppState.getSchemaCache appState + pgVer <- AppState.getPgVersion appState + + let + eitherResponse :: IO (Either Error Wai.Response) + eitherResponse = inSpanM (getOTelTracer appState) "eitherResponse" defaultSpanArguments $ + runExceptT $ postgrestResponse appState appConf maybeSchemaCache pgVer authResult req + + response <- either Error.errorResponseFor identity <$> eitherResponse + -- Launch the connWorker when the connection is down. The postgrest + -- function can respond successfully (with a stale schema cache) before + -- the connWorker is done. + when (isServiceUnavailable response) connWorker + resp <- do + delay <- AppState.getNextDelay appState + return $ addRetryHint delay response + respond resp postgrestResponse :: AppState.AppState @@ -144,10 +150,10 @@ postgrestResponse appState conf@AppConfig{..} maybeSchemaCache pgVer authResult@ let jwtTime = if configServerTimingEnabled then Auth.getJwtDur req else Nothing - (parseTime, apiReq@ApiRequest{..}) <- withTiming $ liftEither . mapLeft Error.ApiRequestError $ ApiRequest.userApiRequest conf req body sCache - (planTime, plan) <- withTiming $ liftEither $ Plan.actionPlan iAction conf apiReq sCache - (queryTime, queryResult) <- withTiming $ Query.runQuery appState conf authResult apiReq plan sCache pgVer (Just authRole /= configDbAnonRole) - (respTime, resp) <- withTiming $ liftEither $ Response.actionResponse queryResult apiReq (T.decodeUtf8 prettyVersion, docsVersion) conf sCache iSchema iNegotiatedByProfile + (parseTime, apiReq@ApiRequest{..}) <- withOTel "parse" $ withTiming $ liftEither . mapLeft Error.ApiRequestError $ ApiRequest.userApiRequest conf req body sCache + (planTime, plan) <- withOTel "plan" $ withTiming $ liftEither $ Plan.actionPlan iAction conf apiReq sCache + (queryTime, queryResult) <- withOTel "query" $ withTiming $ Query.runQuery appState conf authResult apiReq plan sCache pgVer (Just authRole /= configDbAnonRole) + (respTime, resp) <- withOTel "response" $ withTiming $ liftEither $ Response.actionResponse queryResult apiReq (T.decodeUtf8 prettyVersion, docsVersion) conf sCache iSchema iNegotiatedByProfile return $ toWaiResponse (ServerTiming jwtTime parseTime planTime queryTime respTime) resp @@ -164,6 +170,8 @@ postgrestResponse appState conf@AppConfig{..} maybeSchemaCache pgVer authResult@ r <- f pure (Nothing, r) + withOTel label = inSpanM (getOTelTracer appState) label defaultSpanArguments + traceHeaderMiddleware :: AppState -> Wai.Middleware traceHeaderMiddleware appState app req respond = do conf <- AppState.getConfig appState diff --git a/src/PostgREST/AppState.hs b/src/PostgREST/AppState.hs index c52c63d2a9..fc50c33f4a 100644 --- a/src/PostgREST/AppState.hs +++ b/src/PostgREST/AppState.hs @@ -16,6 +16,7 @@ module PostgREST.AppState , getJwtCache , getSocketREST , getSocketAdmin + , getOTelTracer , init , initSockets , initWithPool @@ -76,6 +77,7 @@ import PostgREST.Unix (createAndBindDomainSocket) import Data.Streaming.Network (bindPortTCP, bindRandomPortTCP) import Data.String (IsString (..)) +import OpenTelemetry.Trace (Tracer) import Protolude data AuthResult = AuthResult @@ -116,6 +118,8 @@ data AppState = AppState , stateObserver :: ObservationHandler , stateLogger :: Logger.LoggerState , stateMetrics :: Metrics.MetricsState + -- | OpenTelemetry tracer + , oTelTracer :: Tracer } -- | Schema cache status @@ -126,8 +130,8 @@ data SchemaCacheStatus type AppSockets = (NS.Socket, Maybe NS.Socket) -init :: AppConfig -> IO AppState -init conf@AppConfig{configLogLevel, configDbPoolSize} = do +init :: AppConfig -> Tracer -> IO AppState +init conf@AppConfig{configLogLevel, configDbPoolSize} tracer = do loggerState <- Logger.init metricsState <- Metrics.init configDbPoolSize let observer = liftA2 (>>) (Logger.observationLogger loggerState configLogLevel) (Metrics.observationMetrics metricsState) @@ -136,11 +140,11 @@ init conf@AppConfig{configLogLevel, configDbPoolSize} = do pool <- initPool conf observer (sock, adminSock) <- initSockets conf - state' <- initWithPool (sock, adminSock) pool conf loggerState metricsState observer + state' <- initWithPool (sock, adminSock) pool conf loggerState metricsState tracer observer pure state' { stateSocketREST = sock, stateSocketAdmin = adminSock} -initWithPool :: AppSockets -> SQL.Pool -> AppConfig -> Logger.LoggerState -> Metrics.MetricsState -> ObservationHandler -> IO AppState -initWithPool (sock, adminSock) pool conf loggerState metricsState observer = do +initWithPool :: AppSockets -> SQL.Pool -> AppConfig -> Logger.LoggerState -> Metrics.MetricsState -> Tracer -> ObservationHandler -> IO AppState +initWithPool (sock, adminSock) pool conf loggerState metricsState tracer observer = do appState <- AppState pool <$> newIORef minimumPgVersion -- assume we're in a supported version when starting, this will be corrected on a later step @@ -159,6 +163,7 @@ initWithPool (sock, adminSock) pool conf loggerState metricsState observer = do <*> pure observer <*> pure loggerState <*> pure metricsState + <*> pure tracer deb <- let decisecond = 100000 in @@ -325,6 +330,9 @@ getSocketREST = stateSocketREST getSocketAdmin :: AppState -> Maybe NS.Socket getSocketAdmin = stateSocketAdmin +getOTelTracer :: AppState -> Tracer +getOTelTracer = oTelTracer + getMainThreadId :: AppState -> ThreadId getMainThreadId = stateMainThreadId diff --git a/src/PostgREST/CLI.hs b/src/PostgREST/CLI.hs index 0ba71144b8..e07248909e 100644 --- a/src/PostgREST/CLI.hs +++ b/src/PostgREST/CLI.hs @@ -16,11 +16,12 @@ import qualified Options.Applicative as O import Text.Heredoc (str) -import PostgREST.AppState (AppState) -import PostgREST.Config (AppConfig (..)) -import PostgREST.Observation (Observation (..)) -import PostgREST.SchemaCache (querySchemaCache) -import PostgREST.Version (prettyVersion) +import PostgREST.AppState (AppState) +import PostgREST.Config (AppConfig (..)) +import PostgREST.Observation (Observation (..)) +import PostgREST.OpenTelemetry (withTracer) +import PostgREST.SchemaCache (querySchemaCache) +import PostgREST.Version (prettyVersion) import qualified PostgREST.App as App import qualified PostgREST.AppState as AppState @@ -28,9 +29,8 @@ import qualified PostgREST.Config as Config import Protolude - main :: CLI -> IO () -main CLI{cliCommand, cliPath} = do +main CLI{cliCommand, cliPath} = withTracer "PostgREST" $ \tracer -> do conf@AppConfig{..} <- either panic identity <$> Config.readAppConfig mempty cliPath Nothing mempty mempty @@ -38,7 +38,7 @@ main CLI{cliCommand, cliPath} = do -- explicitly close the connections to PostgreSQL on shutdown. -- 'AppState.destroy' takes care of that. bracket - (AppState.init conf) + (AppState.init conf tracer) AppState.destroy (\appState -> case cliCommand of CmdDumpConfig -> do diff --git a/src/PostgREST/OpenTelemetry.hs b/src/PostgREST/OpenTelemetry.hs new file mode 100644 index 0000000000..4c31f5af47 --- /dev/null +++ b/src/PostgREST/OpenTelemetry.hs @@ -0,0 +1,22 @@ +module PostgREST.OpenTelemetry (withTracer) where + +import OpenTelemetry.Attributes (emptyAttributes) +import OpenTelemetry.Trace (InstrumentationLibrary (..), Tracer, + initializeGlobalTracerProvider, + makeTracer, shutdownTracerProvider, + tracerOptions) +import PostgREST.Version (prettyVersion) +import Protolude + +withTracer :: Text -> (Tracer -> IO c) -> IO c +withTracer label f = bracket + initializeGlobalTracerProvider + shutdownTracerProvider + (\tracerProvider -> f $ makeTracer tracerProvider instrumentationLibrary tracerOptions) + where + instrumentationLibrary = + InstrumentationLibrary + { libraryName = label + , libraryVersion = decodeUtf8 prettyVersion + , librarySchemaUrl = "" + , libraryAttributes = emptyAttributes} diff --git a/stack-21.7.yaml b/stack-21.7.yaml index e75e6a77cb..02e0840c6c 100644 --- a/stack-21.7.yaml +++ b/stack-21.7.yaml @@ -22,3 +22,16 @@ extra-deps: - hasql-notifications-0.2.2.0 - hasql-pool-1.0.1 - postgresql-libpq-0.10.1.0 + + - hs-opentelemetry-sdk-0.1.0.0@sha256:2642851866f11a494c99f15202d4bd9e75d4a5e1a7f3f172742a0676a33c664f,4059 + - hs-opentelemetry-api-0.2.0.0@sha256:bbdbe7e212e99f17a7e68d09b94c1a6613e50ce88b3cb1b68979bbb0221291ae,4051 + - hs-opentelemetry-exporter-otlp-0.1.0.0@sha256:4c908a7e2e5053879687b7a7ee6e40a8eb22868e1a0808cd0cfd6ac9905057b8,1526 + - hs-opentelemetry-instrumentation-wai-0.1.1.0@sha256:d97b4cb3870217e64e95da3f51db814eca62eb57484ee0a6f747366da5940bc2,1371 + - hs-opentelemetry-propagator-b3-0.0.1.2@sha256:8815dd74f27a908b5be0729cc09a3bf9f3049481c982252bbd6c3f6b908ecfcd,1340 + - hs-opentelemetry-propagator-datadog-0.0.1.0@sha256:c85de95e3c33b3ffcf980f560166e960cab0888e0741315f487288b3653c007c,2950 + - hs-opentelemetry-propagator-w3c-0.0.1.4@sha256:251428754454fbaf71d9b6acbbea473014b1ab50bdcda8bc8fe1532e63193374,1382 + - hs-opentelemetry-utils-exceptions-0.2.0.1@sha256:b32c3109b896dbab67c74c28e8ffcfe6e7f86aa29454fc6a31c06a671246e78b,1477 + - hs-opentelemetry-otlp-0.1.0.0@sha256:5cd096b15f26f51ffae4c18f6a26794daef801acc9e13033db8b21a7606336d4,2533 + - thread-utils-context-0.3.0.4@sha256:e763da1c6cab3b6d378fb670ca74aa9bf03c9b61b6fcf7628c56363fb0e3e71e,1671 + - thread-utils-finalizers-0.1.1.0@sha256:24944b71d9f1d01695a5908b4a3b44838fab870883114a323336d537995e0a5b,1381 + - unix-compat-0.7.3@sha256:b23220ab66f6ab2bedeec964152fef48c1f00f33dc911a59dde842d1d8fd2e05,3244 diff --git a/stack-21.7.yaml.lock b/stack-21.7.yaml.lock index a9cc5866af..47070e1b42 100644 --- a/stack-21.7.yaml.lock +++ b/stack-21.7.yaml.lock @@ -39,6 +39,90 @@ packages: size: 1096 original: hackage: postgresql-libpq-0.10.1.0 +- completed: + hackage: hs-opentelemetry-sdk-0.1.0.0@sha256:2642851866f11a494c99f15202d4bd9e75d4a5e1a7f3f172742a0676a33c664f,4059 + pantry-tree: + sha256: c0868a6eb3d6add84df1ad32cdb0ebdbebe41205897e16ae8b30e96f205a8fe0 + size: 1934 + original: + hackage: hs-opentelemetry-sdk-0.1.0.0@sha256:2642851866f11a494c99f15202d4bd9e75d4a5e1a7f3f172742a0676a33c664f,4059 +- completed: + hackage: hs-opentelemetry-api-0.2.0.0@sha256:bbdbe7e212e99f17a7e68d09b94c1a6613e50ce88b3cb1b68979bbb0221291ae,4051 + pantry-tree: + sha256: fcb11b19fa633afb8c34e002e6b8e8927d20fc2332d4234cc10a0b6e3dbe6022 + size: 4396 + original: + hackage: hs-opentelemetry-api-0.2.0.0@sha256:bbdbe7e212e99f17a7e68d09b94c1a6613e50ce88b3cb1b68979bbb0221291ae,4051 +- completed: + hackage: hs-opentelemetry-exporter-otlp-0.1.0.0@sha256:4c908a7e2e5053879687b7a7ee6e40a8eb22868e1a0808cd0cfd6ac9905057b8,1526 + pantry-tree: + sha256: dd22c915f65b1ca76c6130cfb39ce666376d4813c267e12dd59be61a914bb264 + size: 511 + original: + hackage: hs-opentelemetry-exporter-otlp-0.1.0.0@sha256:4c908a7e2e5053879687b7a7ee6e40a8eb22868e1a0808cd0cfd6ac9905057b8,1526 +- completed: + hackage: hs-opentelemetry-instrumentation-wai-0.1.1.0@sha256:d97b4cb3870217e64e95da3f51db814eca62eb57484ee0a6f747366da5940bc2,1371 + pantry-tree: + sha256: 23bbd4e58ba48b0ec3541a494d02e08e6b934d7173523be8aab04c6b2c7bb98b + size: 360 + original: + hackage: hs-opentelemetry-instrumentation-wai-0.1.1.0@sha256:d97b4cb3870217e64e95da3f51db814eca62eb57484ee0a6f747366da5940bc2,1371 +- completed: + hackage: hs-opentelemetry-propagator-b3-0.0.1.2@sha256:8815dd74f27a908b5be0729cc09a3bf9f3049481c982252bbd6c3f6b908ecfcd,1340 + pantry-tree: + sha256: fc71f8b7dc25625af6b81c1b3c1c5d808b682e2a7c1daf8e23f2af45ab9dc123 + size: 431 + original: + hackage: hs-opentelemetry-propagator-b3-0.0.1.2@sha256:8815dd74f27a908b5be0729cc09a3bf9f3049481c982252bbd6c3f6b908ecfcd,1340 +- completed: + hackage: hs-opentelemetry-propagator-datadog-0.0.1.0@sha256:c85de95e3c33b3ffcf980f560166e960cab0888e0741315f487288b3653c007c,2950 + pantry-tree: + sha256: 04c10d8901e506c8c7662c8ce549a152118303fd2d0354a887bede4e73f0a8ee + size: 730 + original: + hackage: hs-opentelemetry-propagator-datadog-0.0.1.0@sha256:c85de95e3c33b3ffcf980f560166e960cab0888e0741315f487288b3653c007c,2950 +- completed: + hackage: hs-opentelemetry-propagator-w3c-0.0.1.4@sha256:251428754454fbaf71d9b6acbbea473014b1ab50bdcda8bc8fe1532e63193374,1382 + pantry-tree: + sha256: 5f7ff3fd37b7f720064193f02c84e8af6b554f8a7a2b7702a4bcd34fe576f721 + size: 445 + original: + hackage: hs-opentelemetry-propagator-w3c-0.0.1.4@sha256:251428754454fbaf71d9b6acbbea473014b1ab50bdcda8bc8fe1532e63193374,1382 +- completed: + hackage: hs-opentelemetry-utils-exceptions-0.2.0.1@sha256:b32c3109b896dbab67c74c28e8ffcfe6e7f86aa29454fc6a31c06a671246e78b,1477 + pantry-tree: + sha256: 7829e2f06282a2ca913ab46ac98a3dd5b0b89b1189d5eb071f250b641115e548 + size: 406 + original: + hackage: hs-opentelemetry-utils-exceptions-0.2.0.1@sha256:b32c3109b896dbab67c74c28e8ffcfe6e7f86aa29454fc6a31c06a671246e78b,1477 +- completed: + hackage: hs-opentelemetry-otlp-0.1.0.0@sha256:5cd096b15f26f51ffae4c18f6a26794daef801acc9e13033db8b21a7606336d4,2533 + pantry-tree: + sha256: 618a513764a7ae9995fc4f8b8ee5cec731a8759ac8c5df8e9553171abd3ff97d + size: 2585 + original: + hackage: hs-opentelemetry-otlp-0.1.0.0@sha256:5cd096b15f26f51ffae4c18f6a26794daef801acc9e13033db8b21a7606336d4,2533 +- completed: + hackage: thread-utils-context-0.3.0.4@sha256:e763da1c6cab3b6d378fb670ca74aa9bf03c9b61b6fcf7628c56363fb0e3e71e,1671 + pantry-tree: + sha256: 57d909a991b5e0b4c7a28121cb52ee9c2db6c09e0419b89af6c82fae52be88d4 + size: 397 + original: + hackage: thread-utils-context-0.3.0.4@sha256:e763da1c6cab3b6d378fb670ca74aa9bf03c9b61b6fcf7628c56363fb0e3e71e,1671 +- completed: + hackage: thread-utils-finalizers-0.1.1.0@sha256:24944b71d9f1d01695a5908b4a3b44838fab870883114a323336d537995e0a5b,1381 + pantry-tree: + sha256: 8c2c2e2e22c20bf3696ee6f30b50b3a9eeae187a22beb536441eefb0a3f9c549 + size: 400 + original: + hackage: thread-utils-finalizers-0.1.1.0@sha256:24944b71d9f1d01695a5908b4a3b44838fab870883114a323336d537995e0a5b,1381 +- completed: + hackage: unix-compat-0.7.3@sha256:b23220ab66f6ab2bedeec964152fef48c1f00f33dc911a59dde842d1d8fd2e05,3244 + pantry-tree: + sha256: 9f31237b73544c43a9349446e7b55ca6e8195ca45ead413778d35bba185e0aea + size: 1329 + original: + hackage: unix-compat-0.7.3@sha256:b23220ab66f6ab2bedeec964152fef48c1f00f33dc911a59dde842d1d8fd2e05,3244 snapshots: - completed: sha256: 23bb9bb355bfdb1635252e120a29b712f0d5e8a6c6a65c5ab5bd6692f46c438e diff --git a/stack.yaml b/stack.yaml index 477fe59f31..718839f474 100644 --- a/stack.yaml +++ b/stack.yaml @@ -14,3 +14,15 @@ extra-deps: - hasql-pool-1.0.1 - jose-jwt-0.10.0 - postgresql-libpq-0.10.1.0 + + - hs-opentelemetry-sdk-0.1.0.0@sha256:2642851866f11a494c99f15202d4bd9e75d4a5e1a7f3f172742a0676a33c664f,4059 + - hs-opentelemetry-api-0.2.0.0@sha256:bbdbe7e212e99f17a7e68d09b94c1a6613e50ce88b3cb1b68979bbb0221291ae,4051 + - hs-opentelemetry-exporter-otlp-0.1.0.0@sha256:4c908a7e2e5053879687b7a7ee6e40a8eb22868e1a0808cd0cfd6ac9905057b8,1526 + - hs-opentelemetry-instrumentation-wai-0.1.1.0@sha256:d97b4cb3870217e64e95da3f51db814eca62eb57484ee0a6f747366da5940bc2,1371 + - hs-opentelemetry-propagator-b3-0.0.1.2@sha256:8815dd74f27a908b5be0729cc09a3bf9f3049481c982252bbd6c3f6b908ecfcd,1340 + - hs-opentelemetry-propagator-datadog-0.0.1.0@sha256:c85de95e3c33b3ffcf980f560166e960cab0888e0741315f487288b3653c007c,2950 + - hs-opentelemetry-propagator-w3c-0.0.1.4@sha256:251428754454fbaf71d9b6acbbea473014b1ab50bdcda8bc8fe1532e63193374,1382 + - hs-opentelemetry-utils-exceptions-0.2.0.1@sha256:b32c3109b896dbab67c74c28e8ffcfe6e7f86aa29454fc6a31c06a671246e78b,1477 + - hs-opentelemetry-otlp-0.1.0.0@sha256:5cd096b15f26f51ffae4c18f6a26794daef801acc9e13033db8b21a7606336d4,2533 + - thread-utils-context-0.3.0.4@sha256:e763da1c6cab3b6d378fb670ca74aa9bf03c9b61b6fcf7628c56363fb0e3e71e,1671 + - thread-utils-finalizers-0.1.1.0@sha256:24944b71d9f1d01695a5908b4a3b44838fab870883114a323336d537995e0a5b,1381 diff --git a/stack.yaml.lock b/stack.yaml.lock index 4b5fce07dd..d9e370e23d 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -26,12 +26,89 @@ packages: original: hackage: jose-jwt-0.10.0 - completed: - hackage: postgresql-libpq-0.10.1.0@sha256:6b580c9d5068e78eecc13e655b2885c8e79cdacfca513c5d1e5a6b9dc61d9758,3166 + hackage: postgresql-libpq-0.10.1.0@sha256:6a45edff0a9e30b32cda6e443107950492322622c4fbefc8fb4dcf6452dcf0b4,3203 pantry-tree: - sha256: ae81e7628a8f3d1ef33ace71fa0845c073c003ca7f1150cc9d9ba1e55fc84236 + sha256: 1c0120f2cd6d15bfdf64060ebde4b037f01381a8d04d188d753b43e1c978d164 size: 1096 original: hackage: postgresql-libpq-0.10.1.0 +- completed: + hackage: hs-opentelemetry-sdk-0.1.0.0@sha256:2642851866f11a494c99f15202d4bd9e75d4a5e1a7f3f172742a0676a33c664f,4059 + pantry-tree: + sha256: c0868a6eb3d6add84df1ad32cdb0ebdbebe41205897e16ae8b30e96f205a8fe0 + size: 1934 + original: + hackage: hs-opentelemetry-sdk-0.1.0.0@sha256:2642851866f11a494c99f15202d4bd9e75d4a5e1a7f3f172742a0676a33c664f,4059 +- completed: + hackage: hs-opentelemetry-api-0.2.0.0@sha256:bbdbe7e212e99f17a7e68d09b94c1a6613e50ce88b3cb1b68979bbb0221291ae,4051 + pantry-tree: + sha256: fcb11b19fa633afb8c34e002e6b8e8927d20fc2332d4234cc10a0b6e3dbe6022 + size: 4396 + original: + hackage: hs-opentelemetry-api-0.2.0.0@sha256:bbdbe7e212e99f17a7e68d09b94c1a6613e50ce88b3cb1b68979bbb0221291ae,4051 +- completed: + hackage: hs-opentelemetry-exporter-otlp-0.1.0.0@sha256:4c908a7e2e5053879687b7a7ee6e40a8eb22868e1a0808cd0cfd6ac9905057b8,1526 + pantry-tree: + sha256: dd22c915f65b1ca76c6130cfb39ce666376d4813c267e12dd59be61a914bb264 + size: 511 + original: + hackage: hs-opentelemetry-exporter-otlp-0.1.0.0@sha256:4c908a7e2e5053879687b7a7ee6e40a8eb22868e1a0808cd0cfd6ac9905057b8,1526 +- completed: + hackage: hs-opentelemetry-instrumentation-wai-0.1.1.0@sha256:d97b4cb3870217e64e95da3f51db814eca62eb57484ee0a6f747366da5940bc2,1371 + pantry-tree: + sha256: 23bbd4e58ba48b0ec3541a494d02e08e6b934d7173523be8aab04c6b2c7bb98b + size: 360 + original: + hackage: hs-opentelemetry-instrumentation-wai-0.1.1.0@sha256:d97b4cb3870217e64e95da3f51db814eca62eb57484ee0a6f747366da5940bc2,1371 +- completed: + hackage: hs-opentelemetry-propagator-b3-0.0.1.2@sha256:8815dd74f27a908b5be0729cc09a3bf9f3049481c982252bbd6c3f6b908ecfcd,1340 + pantry-tree: + sha256: fc71f8b7dc25625af6b81c1b3c1c5d808b682e2a7c1daf8e23f2af45ab9dc123 + size: 431 + original: + hackage: hs-opentelemetry-propagator-b3-0.0.1.2@sha256:8815dd74f27a908b5be0729cc09a3bf9f3049481c982252bbd6c3f6b908ecfcd,1340 +- completed: + hackage: hs-opentelemetry-propagator-datadog-0.0.1.0@sha256:c85de95e3c33b3ffcf980f560166e960cab0888e0741315f487288b3653c007c,2950 + pantry-tree: + sha256: 04c10d8901e506c8c7662c8ce549a152118303fd2d0354a887bede4e73f0a8ee + size: 730 + original: + hackage: hs-opentelemetry-propagator-datadog-0.0.1.0@sha256:c85de95e3c33b3ffcf980f560166e960cab0888e0741315f487288b3653c007c,2950 +- completed: + hackage: hs-opentelemetry-propagator-w3c-0.0.1.4@sha256:251428754454fbaf71d9b6acbbea473014b1ab50bdcda8bc8fe1532e63193374,1382 + pantry-tree: + sha256: 5f7ff3fd37b7f720064193f02c84e8af6b554f8a7a2b7702a4bcd34fe576f721 + size: 445 + original: + hackage: hs-opentelemetry-propagator-w3c-0.0.1.4@sha256:251428754454fbaf71d9b6acbbea473014b1ab50bdcda8bc8fe1532e63193374,1382 +- completed: + hackage: hs-opentelemetry-utils-exceptions-0.2.0.1@sha256:b32c3109b896dbab67c74c28e8ffcfe6e7f86aa29454fc6a31c06a671246e78b,1477 + pantry-tree: + sha256: 7829e2f06282a2ca913ab46ac98a3dd5b0b89b1189d5eb071f250b641115e548 + size: 406 + original: + hackage: hs-opentelemetry-utils-exceptions-0.2.0.1@sha256:b32c3109b896dbab67c74c28e8ffcfe6e7f86aa29454fc6a31c06a671246e78b,1477 +- completed: + hackage: hs-opentelemetry-otlp-0.1.0.0@sha256:5cd096b15f26f51ffae4c18f6a26794daef801acc9e13033db8b21a7606336d4,2533 + pantry-tree: + sha256: 618a513764a7ae9995fc4f8b8ee5cec731a8759ac8c5df8e9553171abd3ff97d + size: 2585 + original: + hackage: hs-opentelemetry-otlp-0.1.0.0@sha256:5cd096b15f26f51ffae4c18f6a26794daef801acc9e13033db8b21a7606336d4,2533 +- completed: + hackage: thread-utils-context-0.3.0.4@sha256:e763da1c6cab3b6d378fb670ca74aa9bf03c9b61b6fcf7628c56363fb0e3e71e,1671 + pantry-tree: + sha256: 57d909a991b5e0b4c7a28121cb52ee9c2db6c09e0419b89af6c82fae52be88d4 + size: 397 + original: + hackage: thread-utils-context-0.3.0.4@sha256:e763da1c6cab3b6d378fb670ca74aa9bf03c9b61b6fcf7628c56363fb0e3e71e,1671 +- completed: + hackage: thread-utils-finalizers-0.1.1.0@sha256:24944b71d9f1d01695a5908b4a3b44838fab870883114a323336d537995e0a5b,1381 + pantry-tree: + sha256: 8c2c2e2e22c20bf3696ee6f30b50b3a9eeae187a22beb536441eefb0a3f9c549 + size: 400 + original: + hackage: thread-utils-finalizers-0.1.1.0@sha256:24944b71d9f1d01695a5908b4a3b44838fab870883114a323336d537995e0a5b,1381 snapshots: - completed: sha256: 1e32b51d9082fdf6f3bd92accc9dfffd4ddaf406404427fb10bf76d2bc03cbbb diff --git a/test/memory/memory-tests.sh b/test/memory/memory-tests.sh index dfd0ea0cf1..882eed508e 100755 --- a/test/memory/memory-tests.sh +++ b/test/memory/memory-tests.sh @@ -13,6 +13,7 @@ export PGRST_SERVER_HOST="127.0.0.1" export PGRST_SERVER_PORT="$pgrPort" export PGRST_JWT_SECRET="reallyreallyreallyreallyverysafe" export PGRST_DB_CONFIG="false" +export OTEL_TRACES_SAMPLER="always_off" # minimize the impact of tracing on memory usage trap "kill 0" int term exit @@ -103,20 +104,20 @@ postJsonArrayTest(){ echo "Running memory usage tests.." jsonKeyTest "1M" "POST" "/rpc/leak?columns=blob" "27M" -jsonKeyTest "1M" "POST" "/leak?columns=blob" "21M" -jsonKeyTest "1M" "PATCH" "/leak?id=eq.1&columns=blob" "21M" +jsonKeyTest "1M" "POST" "/leak?columns=blob" "22M" +jsonKeyTest "1M" "PATCH" "/leak?id=eq.1&columns=blob" "22M" jsonKeyTest "10M" "POST" "/rpc/leak?columns=blob" "32M" jsonKeyTest "10M" "POST" "/leak?columns=blob" "32M" jsonKeyTest "10M" "PATCH" "/leak?id=eq.1&columns=blob" "32M" -jsonKeyTest "50M" "POST" "/rpc/leak?columns=blob" "72M" -jsonKeyTest "50M" "POST" "/leak?columns=blob" "72M" -jsonKeyTest "50M" "PATCH" "/leak?id=eq.1&columns=blob" "72M" +jsonKeyTest "50M" "POST" "/rpc/leak?columns=blob" "73M" +jsonKeyTest "50M" "POST" "/leak?columns=blob" "73M" +jsonKeyTest "50M" "PATCH" "/leak?id=eq.1&columns=blob" "73M" -postJsonArrayTest "1000" "/perf_articles?columns=id,body" "20M" -postJsonArrayTest "10000" "/perf_articles?columns=id,body" "20M" -postJsonArrayTest "100000" "/perf_articles?columns=id,body" "24M" +postJsonArrayTest "1000" "/perf_articles?columns=id,body" "21M" +postJsonArrayTest "10000" "/perf_articles?columns=id,body" "22M" +postJsonArrayTest "100000" "/perf_articles?columns=id,body" "25M" trap - int term exit diff --git a/test/spec/Main.hs b/test/spec/Main.hs index 526bd45dcc..9d1f6373fb 100644 --- a/test/spec/Main.hs +++ b/test/spec/Main.hs @@ -11,6 +11,7 @@ import Test.Hspec import PostgREST.App (postgrest) import PostgREST.Config (AppConfig (..)) import PostgREST.Config.Database (queryPgVersion) +import PostgREST.OpenTelemetry (withTracer) import PostgREST.SchemaCache (querySchemaCache) import Protolude hiding (toList, toS) import SpecHelper @@ -89,8 +90,8 @@ main = do metricsState <- Metrics.init (configDbPoolSize testCfg) let - initApp sCache config = do - appState <- AppState.initWithPool sockets pool config loggerState metricsState (const $ pure ()) + initApp sCache config = withTracer "PostgREST.Spec" $ \tracer -> do + appState <- AppState.initWithPool sockets pool config loggerState metricsState tracer (const $ pure ()) AppState.putPgVersion appState actualPgVersion AppState.putSchemaCache appState (Just sCache) return ((), postgrest (configLogLevel config) appState (pure ()))