add postgres query to traces

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/10853
GitOrigin-RevId: b47c7077fc8fc7115ab05dffe93195abfeb4131d
This commit is contained in:
paritosh-08 2024-06-06 23:54:33 +05:30 committed by hasura-bot
parent 8bc5c01961
commit cf41d2abd9
25 changed files with 165 additions and 83 deletions

View File

@ -1229,6 +1229,19 @@ This sets transaction isolation.
| **Default** | `read-committed` |
| **Supported in** | Deprecated in versions > `v2.0.0` |
### Trace SQL Queries
Add SQL queries to the OTLP traces.
| | |
| ------------------- | ---------------------------------------- |
| **Flag** | `--trace-sql-query` |
| **Env var** | `HASURA_GRAPHQL_ENABLE_QUERY_TRACING` |
| **Accepted values** | Boolean |
| **Options** | `true` or `false` |
| **Default** | `false` |
| **Supported in** | CE, Enterprise Edition |
### Unauthorized Role
This identifies an [unauthorized role](/auth/authentication/unauthenticated-access.mdx), used when the

View File

@ -332,7 +332,8 @@ serveOptions =
soPersistedQueries = Init._default Init.persistedQueriesOption,
soPersistedQueriesTtl = Init._default Init.persistedQueriesTtlOption,
soRemoteSchemaResponsePriority = Init._default Init.remoteSchemaResponsePriorityOption,
soHeaderPrecedence = Init._default Init.configuredHeaderPrecedenceOption
soHeaderPrecedence = Init._default Init.configuredHeaderPrecedenceOption,
soTraceQueryStatus = Init._default Init.traceQueryStatusOption
}
-- | What log level should be used by the engine; this is not exported, and

View File

@ -174,7 +174,8 @@ data AppContext = AppContext
acCloseWebsocketsOnMetadataChangeStatus :: CloseWebsocketsOnMetadataChangeStatus,
acSchemaSampledFeatureFlags :: SchemaSampledFeatureFlags,
acRemoteSchemaResponsePriority :: RemoteSchemaResponsePriority,
acHeaderPrecedence :: HeaderPrecedence
acHeaderPrecedence :: HeaderPrecedence,
acTraceQueryStatus :: TraceQueryStatus
}
-- | Collection of the LoggerCtx, the regular Logger and the PGLogger
@ -297,7 +298,8 @@ buildAppContextRule = proc (ServeOptions {..}, env, _keys, checkFeatureFlag) ->
acCloseWebsocketsOnMetadataChangeStatus = soCloseWebsocketsOnMetadataChangeStatus,
acSchemaSampledFeatureFlags = schemaSampledFeatureFlags,
acRemoteSchemaResponsePriority = soRemoteSchemaResponsePriority,
acHeaderPrecedence = soHeaderPrecedence
acHeaderPrecedence = soHeaderPrecedence,
acTraceQueryStatus = soTraceQueryStatus
}
where
buildEventEngineCtx = Inc.cache proc (httpPoolSize, fetchInterval, fetchBatchSize) -> do

View File

@ -38,7 +38,7 @@ import Hasura.RQL.Types.Column
import Hasura.RQL.Types.Common
import Hasura.RQL.Types.Schema.Options qualified as Options
import Hasura.SQL.AnyBackend qualified as AB
import Hasura.Server.Types (HeaderPrecedence)
import Hasura.Server.Types (HeaderPrecedence, TraceQueryStatus)
import Hasura.Session
import Language.GraphQL.Draft.Syntax qualified as G
import Network.HTTP.Client as HTTP
@ -78,8 +78,9 @@ bqDBQueryPlan ::
QueryDB 'BigQuery Void (UnpreparedValue 'BigQuery) ->
[HTTP.Header] ->
Maybe G.Name ->
TraceQueryStatus ->
m (DBStepInfo 'BigQuery, [ModelInfoPart])
bqDBQueryPlan userInfo sourceName sourceConfig qrf _ _ = do
bqDBQueryPlan userInfo sourceName sourceConfig qrf _ _ _ = do
-- TODO (naveen): Append query tags to the query
select <- planNoPlan (BigQuery.bigQuerySourceConfigToFromIrConfig sourceConfig) userInfo qrf
let action = OnBaseMonad do
@ -147,8 +148,9 @@ bqDBMutationPlan ::
Maybe G.Name ->
Maybe (HashMap G.Name (G.Value G.Variable)) ->
HeaderPrecedence ->
TraceQueryStatus ->
m (DBStepInfo 'BigQuery, [ModelInfoPart])
bqDBMutationPlan _env _manager _logger _userInfo _stringifyNum _sourceName _sourceConfig _mrf _headers _gName _maybeSelSetArgs _ =
bqDBMutationPlan _env _manager _logger _userInfo _stringifyNum _sourceName _sourceConfig _mrf _headers _gName _maybeSelSetArgs _ _traceQueryStatus =
throw500 "mutations are not supported in BigQuery; this should be unreachable"
-- explain
@ -230,9 +232,10 @@ bqDBRemoteRelationshipPlan ::
[HTTP.Header] ->
Maybe G.Name ->
Options.StringifyNumbers ->
TraceQueryStatus ->
m (DBStepInfo 'BigQuery, [ModelInfoPart])
bqDBRemoteRelationshipPlan userInfo sourceName sourceConfig lhs lhsSchema argumentId relationship reqHeaders operationName stringifyNumbers = do
(dbStepInfo, modelInfo) <- flip runReaderT emptyQueryTagsComment $ bqDBQueryPlan userInfo sourceName sourceConfig rootSelection reqHeaders operationName
bqDBRemoteRelationshipPlan userInfo sourceName sourceConfig lhs lhsSchema argumentId relationship reqHeaders operationName stringifyNumbers traceQueryStatus = do
(dbStepInfo, modelInfo) <- flip runReaderT emptyQueryTagsComment $ bqDBQueryPlan userInfo sourceName sourceConfig rootSelection reqHeaders operationName traceQueryStatus
pure (dbStepInfo, modelInfo)
where
coerceToColumn = BigQuery.ColumnName . getFieldNameTxt

View File

@ -54,7 +54,7 @@ instance BackendExecute 'DataConnector where
type MultiplexedQuery 'DataConnector = Void
type ExecutionMonad 'DataConnector = AgentClientT
mkDBQueryPlan UserInfo {..} sourceName sourceConfig ir _headers _gName = do
mkDBQueryPlan UserInfo {..} sourceName sourceConfig ir _headers _gName _traceQueryStatus = do
queryPlan@Plan {..} <- flip runReaderT (API._cScalarTypes $ _scCapabilities sourceConfig, _uiSession) $ Plan.mkQueryPlan ir
transformedSourceConfig <- transformSourceConfig sourceConfig (Just _uiSession)
modelNames <- irToModelInfoGen sourceName ModelSourceTypeDataConnector ir
@ -84,7 +84,7 @@ instance BackendExecute 'DataConnector where
dbsiResolvedConnectionTemplate = ()
}
mkDBMutationPlan _env _manager _logger UserInfo {..} _stringifyNum sourceName sourceConfig mutationDB _headers _gName _maybeSelSetArgs _ = do
mkDBMutationPlan _env _manager _logger UserInfo {..} _stringifyNum sourceName sourceConfig mutationDB _headers _gName _maybeSelSetArgs _ _traceQueryStatus = do
(mutationPlan@Plan {..}, modelNames) <- flip runReaderT (API._cScalarTypes $ _scCapabilities sourceConfig, _uiSession) $ Plan.mkMutationPlan sourceName ModelSourceTypeDataConnector mutationDB
transformedSourceConfig <- transformSourceConfig sourceConfig (Just _uiSession)
let modelInfo = getModelInfoPartfromModelNames modelNames (ModelOperationType G.OperationTypeMutation)
@ -105,7 +105,7 @@ instance BackendExecute 'DataConnector where
mkDBStreamingSubscriptionPlan _ _ _ _ _ _ =
throw400 NotSupported "mkLiveQuerySubscriptionPlan: not implemented for the Data Connector backend."
mkDBRemoteRelationshipPlan UserInfo {..} sourceName sourceConfig joinIds joinIdsSchema argumentIdFieldName (resultFieldName, ir) _ _ _ = do
mkDBRemoteRelationshipPlan UserInfo {..} sourceName sourceConfig joinIds joinIdsSchema argumentIdFieldName (resultFieldName, ir) _ _ _ _ = do
(remoteRelationshipPlan@Plan {..}, modelInfo) <- flip runReaderT (API._cScalarTypes $ _scCapabilities sourceConfig, _uiSession) $ Plan.mkRemoteRelationshipPlan sourceName sourceConfig joinIds joinIdsSchema argumentIdFieldName resultFieldName ir
transformedSourceConfig <- transformSourceConfig sourceConfig (Just _uiSession)
pure

View File

@ -55,7 +55,7 @@ import Hasura.RQL.Types.Column qualified as RQLColumn
import Hasura.RQL.Types.Common as RQLTypes
import Hasura.RQL.Types.Schema.Options qualified as Options
import Hasura.SQL.AnyBackend qualified as AB
import Hasura.Server.Types (HeaderPrecedence)
import Hasura.Server.Types (HeaderPrecedence, TraceQueryStatus)
import Hasura.Session
import Language.GraphQL.Draft.Syntax qualified as G
import Network.HTTP.Client as HTTP
@ -100,8 +100,9 @@ msDBQueryPlan ::
QueryDB 'MSSQL Void (UnpreparedValue 'MSSQL) ->
[HTTP.Header] ->
Maybe G.Name ->
TraceQueryStatus ->
m (DBStepInfo 'MSSQL, [ModelInfoPart])
msDBQueryPlan userInfo sourceName sourceConfig qrf _ _ = do
msDBQueryPlan userInfo sourceName sourceConfig qrf _ _ _ = do
let sessionVariables = _uiSession userInfo
QueryWithDDL {qwdBeforeSteps, qwdAfterSteps, qwdQuery = statement} <- planQuery sessionVariables qrf
queryTags <- ask
@ -319,8 +320,9 @@ msDBMutationPlan ::
Maybe G.Name ->
Maybe (HashMap G.Name (G.Value G.Variable)) ->
HeaderPrecedence ->
TraceQueryStatus ->
m (DBStepInfo 'MSSQL, [ModelInfoPart])
msDBMutationPlan _env _manager _logger userInfo stringifyNum sourceName sourceConfig mrf _headers _gName _maybeSelSetArgs _ = do
msDBMutationPlan _env _manager _logger userInfo stringifyNum sourceName sourceConfig mrf _headers _gName _maybeSelSetArgs _ _ = do
go <$> case mrf of
MDBInsert annInsert -> executeInsert userInfo stringifyNum sourceName ModelSourceTypeMSSQL sourceConfig annInsert
MDBDelete annDelete -> executeDelete userInfo stringifyNum sourceName ModelSourceTypeMSSQL sourceConfig annDelete
@ -525,8 +527,9 @@ msDBRemoteRelationshipPlan ::
[HTTP.Header] ->
Maybe G.Name ->
Options.StringifyNumbers ->
TraceQueryStatus ->
m (DBStepInfo 'MSSQL, [ModelInfoPart])
msDBRemoteRelationshipPlan userInfo sourceName sourceConfig lhs lhsSchema argumentId relationship _headers _gName _stringifyNumbers = do
msDBRemoteRelationshipPlan userInfo sourceName sourceConfig lhs lhsSchema argumentId relationship _headers _gName _stringifyNumbers _traceQueryStatus = do
-- `stringifyNumbers` is not currently handled in any SQL Server operation
statement <- planSourceRelationship (_uiSession userInfo) lhs lhsSchema argumentId relationship

View File

@ -10,7 +10,6 @@
-- This module includes the Postgres implementation of queries, mutations, and more.
module Hasura.Backends.Postgres.Instances.Execute
( PreparedSql (..),
pgDBQueryPlanSimple,
)
where
@ -93,7 +92,7 @@ import Hasura.RQL.Types.Common (FieldName (..), JsonAggSelect (..), SourceName (
import Hasura.RQL.Types.Permission (ValidateInput (..), ValidateInputHttpDefinition (..))
import Hasura.RQL.Types.Schema.Options qualified as Options
import Hasura.SQL.AnyBackend qualified as AB
import Hasura.Server.Types (HeaderPrecedence)
import Hasura.Server.Types (HeaderPrecedence, TraceQueryStatus (TraceQueryEnabled))
import Hasura.Session (UserInfo (..))
import Hasura.Tracing qualified as Tracing
import Language.GraphQL.Draft.Syntax qualified as G
@ -140,8 +139,9 @@ pgDBQueryPlan ::
QueryDB ('Postgres pgKind) Void (UnpreparedValue ('Postgres pgKind)) ->
[HTTP.Header] ->
Maybe G.Name ->
TraceQueryStatus ->
m ((DBStepInfo ('Postgres pgKind)), [ModelInfoPart])
pgDBQueryPlan userInfo sourceName sourceConfig qrf reqHeaders operationName = do
pgDBQueryPlan userInfo sourceName sourceConfig qrf reqHeaders operationName traceQueryStatus = do
(preparedQuery, PlanningSt {_psPrepped = planVals}) <-
flip runStateT initPlanningSt $ traverse (prepareWithPlan userInfo) qrf
queryTagsComment <- ask
@ -157,26 +157,9 @@ pgDBQueryPlan userInfo sourceName sourceConfig qrf reqHeaders operationName = do
modelNames <- irToModelInfoGen sourceName ModelSourceTypePostgres preparedQuery
let modelInfo = getModelInfoPartfromModelNames modelNames (ModelOperationType G.OperationTypeQuery)
let preparedSQLWithQueryTags = appendPreparedSQLWithQueryTags rootFieldPlan queryTagsComment
let (action, preparedSQL) = mkCurPlanTx userInfo preparedSQLWithQueryTags
let (action, preparedSQL) = mkCurPlanTx userInfo preparedSQLWithQueryTags traceQueryStatus
pure $ (DBStepInfo @('Postgres pgKind) sourceName sourceConfig preparedSQL (fmap withNoStatistics action) resolvedConnectionTemplate, modelInfo)
-- | Used by the @dc-postgres-agent to compile a query.
pgDBQueryPlanSimple ::
(MonadError QErr m, MonadIO m) =>
UserInfo ->
QueryTagsComment ->
QueryDB ('Postgres 'Vanilla) Void (UnpreparedValue ('Postgres 'Vanilla)) ->
m (OnBaseMonad (PG.TxET QErr) EncJSON, Maybe PreparedSql)
pgDBQueryPlanSimple userInfo queryTagsComment query = do
(preparedQuery, PlanningSt {_psPrepped = planVals}) <-
flip runStateT initPlanningSt $ traverse (prepareWithPlan userInfo) query
rootFieldPlan <- irToRootFieldPlan userInfo planVals preparedQuery
-- seems like this function is not being used anywhere in graphql-engine, so we're not going to count the models used
let preparedSQLWithQueryTags =
appendPreparedSQLWithQueryTags rootFieldPlan queryTagsComment
let (action, preparedSQL) = mkCurPlanTx userInfo preparedSQLWithQueryTags
pure (action, preparedSQL)
pgDBQueryExplain ::
forall pgKind m.
( MonadError QErr m,
@ -401,11 +384,12 @@ convertFunction ::
SourceName ->
ModelSourceType ->
UserInfo ->
TraceQueryStatus ->
JsonAggSelect ->
-- | VOLATILE function as 'SelectExp'
IR.AnnSimpleSelectG ('Postgres pgKind) Void (UnpreparedValue ('Postgres pgKind)) ->
m (OnBaseMonad (PG.TxET QErr) EncJSON, [ModelNameInfo])
convertFunction sourceName modelSourceType userInfo jsonAggSelect unpreparedQuery = do
convertFunction sourceName modelSourceType userInfo traceQueryStatus jsonAggSelect unpreparedQuery = do
queryTags <- ask
-- Transform the RQL AST into a prepared SQL query
(preparedQuery, PlanningSt {_psPrepped = planVals}) <-
@ -419,7 +403,7 @@ convertFunction sourceName modelSourceType userInfo jsonAggSelect unpreparedQuer
modelNames <- irToModelInfoGen sourceName modelSourceType $ queryResultFn preparedQuery
let preparedSQLWithQueryTags = appendPreparedSQLWithQueryTags rootFieldPlan queryTags
pure
( fst (mkCurPlanTx userInfo preparedSQLWithQueryTags), -- forget (Maybe PreparedSql)
( fst (mkCurPlanTx userInfo preparedSQLWithQueryTags traceQueryStatus), -- forget (Maybe PreparedSql)
modelNames
)
@ -444,8 +428,9 @@ pgDBMutationPlan ::
Maybe G.Name ->
Maybe (HashMap G.Name (G.Value G.Variable)) ->
HeaderPrecedence ->
TraceQueryStatus ->
m (DBStepInfo ('Postgres pgKind), [ModelInfoPart])
pgDBMutationPlan env manager logger userInfo stringifyNum sourceName sourceConfig mrf reqHeaders operationName selSetArguments headerPrecedence = do
pgDBMutationPlan env manager logger userInfo stringifyNum sourceName sourceConfig mrf reqHeaders operationName selSetArguments headerPrecedence traceQueryStatus = do
resolvedConnectionTemplate <-
let connectionTemplateResolver =
connectionTemplateConfigResolver (_pscConnectionTemplateConfig sourceConfig)
@ -458,7 +443,7 @@ pgDBMutationPlan env manager logger userInfo stringifyNum sourceName sourceConfi
MDBInsert s -> convertInsert sourceName ModelSourceTypePostgres env manager logger userInfo s stringifyNum reqHeaders headerPrecedence
MDBUpdate s -> convertUpdate sourceName ModelSourceTypePostgres env manager logger userInfo s stringifyNum reqHeaders selSetArguments headerPrecedence
MDBDelete s -> convertDelete sourceName ModelSourceTypePostgres env manager logger userInfo s stringifyNum reqHeaders selSetArguments headerPrecedence
MDBFunction returnsSet s -> convertFunction sourceName ModelSourceTypePostgres userInfo returnsSet s
MDBFunction returnsSet s -> convertFunction sourceName ModelSourceTypePostgres userInfo traceQueryStatus returnsSet s
where
modelInfoList v = getModelInfoPartfromModelNames (snd v) (ModelOperationType G.OperationTypeMutation)
go resolvedConnectionTemplate v =
@ -647,8 +632,9 @@ testMultiplexedQueryTx (PGL.MultiplexedQuery query) cohortId cohortVariables = d
mkCurPlanTx ::
UserInfo ->
PreparedSql ->
TraceQueryStatus ->
(OnBaseMonad (PG.TxET QErr) EncJSON, Maybe PreparedSql)
mkCurPlanTx userInfo ps@(PreparedSql q prepMap) =
mkCurPlanTx userInfo ps@(PreparedSql q prepMap) traceQueryStatus =
-- generate the SQL and prepared vars or the bytestring
let args = withUserVars (_uiSession userInfo) prepMap
-- WARNING: this quietly assumes the intmap keys are contiguous
@ -656,6 +642,8 @@ mkCurPlanTx userInfo ps@(PreparedSql q prepMap) =
in (,Just ps) $ OnBaseMonad do
-- https://opentelemetry.io/docs/reference/specification/trace/semantic_conventions/database/#connection-level-attributes
Tracing.attachMetadata [("db.system", "postgresql")]
when (traceQueryStatus == TraceQueryEnabled)
$ Tracing.attachMetadata [("db.query", PG.getQueryText q)]
runIdentity
. PG.getRow
<$> PG.rawQE dmlTxErrorHandler q prepArgs True
@ -724,14 +712,15 @@ pgDBRemoteRelationshipPlan ::
[HTTP.Header] ->
Maybe G.Name ->
Options.StringifyNumbers ->
TraceQueryStatus ->
m (DBStepInfo ('Postgres pgKind), [ModelInfoPart])
pgDBRemoteRelationshipPlan userInfo sourceName sourceConfig lhs lhsSchema argumentId relationship reqHeaders operationName stringifyNumbers = do
pgDBRemoteRelationshipPlan userInfo sourceName sourceConfig lhs lhsSchema argumentId relationship reqHeaders operationName stringifyNumbers traceQueryStatus = do
-- NOTE: 'QueryTags' currently cannot support remote relationship queries.
--
-- In the future if we want to add support we'll need to add a new type of
-- metadata (e.g. 'ParameterizedQueryHash' doesn't make sense here) and find
-- a root field name that makes sense to attach to it.
(dbStepInfo, modelInfo) <- flip runReaderT emptyQueryTagsComment $ pgDBQueryPlan userInfo sourceName sourceConfig rootSelection reqHeaders operationName
(dbStepInfo, modelInfo) <- flip runReaderT emptyQueryTagsComment $ pgDBQueryPlan userInfo sourceName sourceConfig rootSelection reqHeaders operationName traceQueryStatus
pure (dbStepInfo, modelInfo)
where
coerceToColumn = Postgres.unsafePGCol . getFieldNameTxt

View File

@ -63,7 +63,7 @@ import Hasura.RQL.Types.Subscription
import Hasura.SQL.AnyBackend qualified as AB
import Hasura.Server.Init qualified as Init
import Hasura.Server.Prometheus (PrometheusMetrics)
import Hasura.Server.Types (HeaderPrecedence, MonadGetPolicies, ReadOnlyMode (..), RequestId (..))
import Hasura.Server.Types (HeaderPrecedence, MonadGetPolicies, ReadOnlyMode (..), RequestId (..), TraceQueryStatus)
import Hasura.Services
import Hasura.Session (BackendOnlyFieldAccess (..), UserInfo (..))
import Hasura.Tracing qualified as Tracing
@ -364,6 +364,7 @@ getResolvedExecPlan ::
RequestId ->
Init.ResponseInternalErrorsConfig ->
HeaderPrecedence ->
TraceQueryStatus ->
m (ParameterizedQueryHash, ResolvedExecutionPlan, [ModelInfoPart])
getResolvedExecPlan
env
@ -380,7 +381,8 @@ getResolvedExecPlan
maybeOperationName
reqId
responseErrorsConfig
headerPrecedence = do
headerPrecedence
traceQueryStatus = do
let gCtx = makeGQLContext userInfo sc queryType
tracesPropagator = getOtelTracesPropagator $ scOpenTelemetryConfig sc
@ -407,6 +409,7 @@ getResolvedExecPlan
maybeOperationName
responseErrorsConfig
headerPrecedence
traceQueryStatus
Tracing.attachMetadata [("graphql.operation.type", "query"), ("parameterized_query_hash", bsToTxt $ unParamQueryHash parameterizedQueryHash)]
pure (parameterizedQueryHash, QueryExecutionPlan executionPlan queryRootFields dirMap, modelInfoList)
G.TypedOperationDefinition G.OperationTypeMutation _ varDefs directives inlinedSelSet -> Tracing.newSpan "Resolve mutation execution plan" $ do
@ -430,6 +433,7 @@ getResolvedExecPlan
reqId
maybeOperationName
headerPrecedence
traceQueryStatus
Tracing.attachMetadata [("graphql.operation.type", "mutation")]
pure (parameterizedQueryHash, MutationExecutionPlan executionPlan, modelInfoList)
G.TypedOperationDefinition G.OperationTypeSubscription _ varDefs directives inlinedSelSet -> Tracing.newSpan "Resolve subscription execution plan" $ do

View File

@ -82,6 +82,7 @@ class
QueryDB b Void (UnpreparedValue b) ->
[HTTP.Header] ->
Maybe G.Name ->
TraceQueryStatus ->
m ((DBStepInfo b), [ModelInfoPart])
mkDBMutationPlan ::
forall m.
@ -103,6 +104,7 @@ class
Maybe G.Name ->
Maybe (HashMap G.Name (G.Value G.Variable)) ->
HeaderPrecedence ->
TraceQueryStatus ->
m (DBStepInfo b, [ModelInfoPart])
mkLiveQuerySubscriptionPlan ::
forall m.
@ -178,6 +180,7 @@ class
[HTTP.Header] ->
Maybe G.Name ->
Options.StringifyNumbers ->
TraceQueryStatus ->
m (DBStepInfo b, [ModelInfoPart])
-- | This is a helper function to convert a remote source's relationship to a

View File

@ -98,6 +98,7 @@ convertMutationSelectionSet ::
-- | Graphql Operation Name
Maybe G.Name ->
HeaderPrecedence ->
TraceQueryStatus ->
m (ExecutionPlan, ParameterizedQueryHash, [ModelInfoPart])
convertMutationSelectionSet
env
@ -115,7 +116,8 @@ convertMutationSelectionSet
introspectionDisabledRoles
reqId
maybeOperationName
headerPrecedence = do
headerPrecedence
traceQueryStatus = do
mutationParser <-
onNothing (gqlMutationParser gqlContext)
$ throw400 ValidationFailed "no mutations exist"
@ -146,7 +148,7 @@ convertMutationSelectionSet
httpManager <- askHTTPManager
let selSetArguments = getSelSetArgsFromRootField resolvedSelSet rootFieldName
(dbStepInfo, dbModelInfoList) <- flip runReaderT queryTagsComment $ mkDBMutationPlan @b env httpManager logger userInfo stringifyNum sourceName sourceConfig noRelsDBAST reqHeaders maybeOperationName selSetArguments headerPrecedence
(dbStepInfo, dbModelInfoList) <- flip runReaderT queryTagsComment $ mkDBMutationPlan @b env httpManager logger userInfo stringifyNum sourceName sourceConfig noRelsDBAST reqHeaders maybeOperationName selSetArguments headerPrecedence traceQueryStatus
pure $ (ExecStepDB [] (AB.mkAnyBackend dbStepInfo) remoteJoins, dbModelInfoList)
RFRemote (RemoteSchemaName rName) remoteField -> do
RemoteSchemaRootField remoteSchemaInfo resultCustomizer resolvedRemoteField <- runVariableCache $ resolveRemoteField userInfo remoteField

View File

@ -39,7 +39,7 @@ import Hasura.RemoteSchema.Metadata.Base (RemoteSchemaName (..))
import Hasura.SQL.AnyBackend qualified as AB
import Hasura.Server.Init.Config (ResponseInternalErrorsConfig (..))
import Hasura.Server.Prometheus (PrometheusMetrics (..))
import Hasura.Server.Types (HeaderPrecedence, MonadGetPolicies, RequestId (..))
import Hasura.Server.Types (HeaderPrecedence, MonadGetPolicies, RequestId (..), TraceQueryStatus)
import Hasura.Services.Network
import Hasura.Session
import Hasura.Tracing (MonadTrace)
@ -94,6 +94,7 @@ convertQuerySelSet ::
Maybe G.Name ->
ResponseInternalErrorsConfig ->
HeaderPrecedence ->
TraceQueryStatus ->
m (ExecutionPlan, [QueryRootField UnpreparedValue], DirectiveMap, ParameterizedQueryHash, [ModelInfoPart])
convertQuerySelSet
env
@ -112,7 +113,8 @@ convertQuerySelSet
reqId
maybeOperationName
responseErrorsConfig
headerPrecedence = do
headerPrecedence
traceQueryStatus = do
-- 1. Parse the GraphQL query into the 'RootFieldMap' and a 'SelectionSet'
(unpreparedQueries, normalizedDirectives, normalizedSelectionSet) <-
Tracing.newSpan "Parse query IR" $ parseGraphQLQuery nullInNonNullableVariables gqlContext varDefs (GH._grVariables gqlUnparsed) directives fields
@ -142,7 +144,7 @@ convertQuerySelSet
queryTagsAttributes = encodeQueryTags $ QTQuery $ QueryMetadata mReqId maybeOperationName rootFieldName parameterizedQueryHash
queryTagsComment = Tagged.untag $ createQueryTags @m queryTagsAttributes queryTagsConfig
(noRelsDBAST, remoteJoins) = RJ.getRemoteJoinsQueryDB db
(dbStepInfo, dbModelInfoList) <- flip runReaderT queryTagsComment $ mkDBQueryPlan @b userInfo sourceName sourceConfig noRelsDBAST reqHeaders maybeOperationName
(dbStepInfo, dbModelInfoList) <- flip runReaderT queryTagsComment $ mkDBQueryPlan @b userInfo sourceName sourceConfig noRelsDBAST reqHeaders maybeOperationName traceQueryStatus
pure $ (ExecStepDB [] (AB.mkAnyBackend dbStepInfo) remoteJoins, dbModelInfoList)
RFRemote (RemoteSchemaName rName) rf -> do
RemoteSchemaRootField remoteSchemaInfo resultCustomizer remoteField <- runVariableCache $ for rf $ resolveRemoteVariable userInfo

View File

@ -38,7 +38,7 @@ import Hasura.RQL.IR.ModelInformation (ModelInfoPart (..), ModelOperationType (M
import Hasura.RQL.Types.Common
import Hasura.RemoteSchema.SchemaCache
import Hasura.SQL.AnyBackend qualified as AB
import Hasura.Server.Types (MonadGetPolicies, RequestId)
import Hasura.Server.Types (MonadGetPolicies, RequestId, TraceQueryStatus)
import Hasura.Services.Network
import Hasura.Session
import Hasura.Tracing qualified as Tracing
@ -78,8 +78,9 @@ processRemoteJoins ::
Maybe RemoteJoins ->
GQLReqUnparsed ->
Tracing.HttpPropagator ->
TraceQueryStatus ->
m (EncJSON, [ModelInfoPart])
processRemoteJoins requestId logger agentLicenseKey env requestHeaders userInfo lhs maybeJoinTree gqlreq tracesPropagator =
processRemoteJoins requestId logger agentLicenseKey env requestHeaders userInfo lhs maybeJoinTree gqlreq tracesPropagator traceQueryStatus =
Tracing.newSpan "Process remote joins" $ forRemoteJoins maybeJoinTree (lhs, []) \joinTree -> do
lhsParsed <-
JO.eitherDecode (encJToLBS lhs)
@ -93,6 +94,7 @@ processRemoteJoins requestId logger agentLicenseKey env requestHeaders userInfo
joinTree
requestHeaders
(_unOperationName <$> _grOperationName gqlreq)
traceQueryStatus
pure $ (encJFromOrderedValue $ runIdentity jsonResult, (modelInfoList))
where
-- How to process a source join call over the network.
@ -153,8 +155,9 @@ foldJoinTreeWith ::
RemoteJoins ->
[HTTP.Header] ->
Maybe G.Name ->
TraceQueryStatus ->
m (f JO.Value, [ModelInfoPart])
foldJoinTreeWith callSource callRemoteSchema userInfo lhs joinTree reqHeaders operationName = do
foldJoinTreeWith callSource callRemoteSchema userInfo lhs joinTree reqHeaders operationName traceQueryStatus = do
(compositeValue, joins) <- collectJoinArguments (assignJoinIds joinTree) lhs
(joinIndices) <- fmap catMaybes
$ for joins
@ -167,7 +170,7 @@ foldJoinTreeWith callSource callRemoteSchema userInfo lhs joinTree reqHeaders op
let remoteSchemaModel = ModelInfoPart (toTxt $ _vrsdName remoteSchemaInfo) ModelTypeRemoteSchema Nothing Nothing (ModelOperationType G.OperationTypeQuery)
pure $ (fmap (childJoinTree,) maybeJoinIndex, Just [remoteSchemaModel])
RemoteJoinSource sourceJoin childJoinTree -> do
maybeJoinIndex <- S.makeSourceJoinCall callSource userInfo sourceJoin _jalFieldName joinArguments reqHeaders operationName
maybeJoinIndex <- S.makeSourceJoinCall callSource userInfo sourceJoin _jalFieldName joinArguments reqHeaders operationName traceQueryStatus
pure $ (fmap (childJoinTree,) $ fst <$> maybeJoinIndex, snd <$> maybeJoinIndex)
result <- for previousStep $ \((childJoinTree, joinIndex)) -> do
forRemoteJoins childJoinTree (joinIndex, []) $ \childRemoteJoins -> do
@ -180,6 +183,7 @@ foldJoinTreeWith callSource callRemoteSchema userInfo lhs joinTree reqHeaders op
childRemoteJoins
reqHeaders
operationName
traceQueryStatus
pure $ ((IntMap.fromAscList $ zip (IntMap.keys joinIndex) results), modelInfo)
pure $ fmap (\(iMap, newModelInfo) -> (iMap, newModelInfo <> fromMaybe [] modelInfo')) result
let (key, (compositeValue')) = unzip (IntMap.toList joinIndices)

View File

@ -70,9 +70,10 @@ makeSourceJoinCall ::
IntMap.IntMap JoinArgument ->
[HTTP.Header] ->
Maybe G.Name ->
TraceQueryStatus ->
-- | The resulting join index (see 'buildJoinIndex') if any.
m (Maybe (IntMap.IntMap AO.Value, [ModelInfoPart]))
makeSourceJoinCall networkFunction userInfo remoteSourceJoin jaFieldName joinArguments reqHeaders operationName =
makeSourceJoinCall networkFunction userInfo remoteSourceJoin jaFieldName joinArguments reqHeaders operationName traceQueryStatus =
Tracing.newSpan ("Remote join to data source " <> sourceName <<> " for field " <>> jaFieldName) do
-- step 1: create the SourceJoinCall
-- maybeSourceCall <-
@ -80,7 +81,7 @@ makeSourceJoinCall networkFunction userInfo remoteSourceJoin jaFieldName joinArg
-- buildSourceJoinCall @b userInfo jaFieldName joinArguments sjc
maybeSourceCall <-
AB.dispatchAnyBackend @EB.BackendExecute remoteSourceJoin
$ buildSourceJoinCall userInfo jaFieldName joinArguments reqHeaders operationName
$ buildSourceJoinCall userInfo jaFieldName joinArguments reqHeaders operationName traceQueryStatus
-- if there actually is a remote call:
for maybeSourceCall \(sourceCall, modelInfoList) -> do
-- step 2: send this call over the network
@ -115,9 +116,10 @@ buildSourceJoinCall ::
IntMap.IntMap JoinArgument ->
[HTTP.Header] ->
Maybe G.Name ->
TraceQueryStatus ->
RemoteSourceJoin b ->
m (Maybe (AB.AnyBackend SourceJoinCall, [ModelInfoPart]))
buildSourceJoinCall userInfo jaFieldName joinArguments reqHeaders operationName remoteSourceJoin = do
buildSourceJoinCall userInfo jaFieldName joinArguments reqHeaders operationName traceQueryStatus remoteSourceJoin = do
Tracing.newSpan "Resolve execution step for remote join field" do
let rows =
IntMap.toList joinArguments <&> \(argumentId, argument) ->
@ -142,6 +144,7 @@ buildSourceJoinCall userInfo jaFieldName joinArguments reqHeaders operationName
reqHeaders
operationName
(_rsjStringifyNum remoteSourceJoin)
traceQueryStatus
-- This should never fail, as field names in remote relationships are
-- validated when building the schema cache.
fieldName <-

View File

@ -95,7 +95,7 @@ import Hasura.Server.Prometheus
recordGraphqlOperationMetric,
)
import Hasura.Server.Telemetry.Counters qualified as Telem
import Hasura.Server.Types (HeaderPrecedence, ModelInfoLogState (..), MonadGetPolicies (..), ReadOnlyMode (..), RemoteSchemaResponsePriority (..), RequestId (..))
import Hasura.Server.Types (HeaderPrecedence, ModelInfoLogState (..), MonadGetPolicies (..), ReadOnlyMode (..), RemoteSchemaResponsePriority (..), RequestId (..), TraceQueryStatus)
import Hasura.Services
import Hasura.Session (SessionVariable, SessionVariableValue, SessionVariables, UserInfo (..), filterSessionVariables)
import Hasura.Tracing (MonadTrace, attachMetadata)
@ -320,6 +320,7 @@ runGQ ::
ReadOnlyMode ->
RemoteSchemaResponsePriority ->
HeaderPrecedence ->
TraceQueryStatus ->
PrometheusMetrics ->
L.Logger L.Hasura ->
Maybe (CredentialCache AgentLicenseKey) ->
@ -331,7 +332,7 @@ runGQ ::
GQLReqUnparsed ->
ResponseInternalErrorsConfig ->
m (GQLQueryOperationSuccessLog, HttpResponse (Maybe GQResponse, EncJSON))
runGQ env sqlGenCtx sc enableAL readOnlyMode remoteSchemaResponsePriority headerPrecedence prometheusMetrics logger agentLicenseKey reqId userInfo ipAddress reqHeaders queryType reqUnparsed responseErrorsConfig = do
runGQ env sqlGenCtx sc enableAL readOnlyMode remoteSchemaResponsePriority headerPrecedence traceQueryStatus prometheusMetrics logger agentLicenseKey reqId userInfo ipAddress reqHeaders queryType reqUnparsed responseErrorsConfig = do
granularPrometheusMetricsState <- runGetPrometheusMetricsGranularity
getModelInfoLogStatus' <- runGetModelInfoLogStatus
modelInfoLogStatus <- liftIO getModelInfoLogStatus'
@ -376,6 +377,7 @@ runGQ env sqlGenCtx sc enableAL readOnlyMode remoteSchemaResponsePriority header
reqId
responseErrorsConfig
headerPrecedence
traceQueryStatus
-- 4. Execute the execution plan producing a 'AnnotatedResponse'.
(response, queryCachedStatus, modelInfoFromExecution) <- executePlan reqParsed runLimits execPlan
@ -512,7 +514,7 @@ runGQ env sqlGenCtx sc enableAL readOnlyMode remoteSchemaResponsePriority header
\(EB.DBStepInfo _ sourceConfig genSql tx resolvedConnectionTemplate :: EB.DBStepInfo b) ->
runDBQuery @b reqId reqUnparsed fieldName userInfo logger agentLicenseKey sourceConfig (fmap (statsToAnyBackend @b) tx) genSql resolvedConnectionTemplate
(finalResponse, modelInfo) <-
RJ.processRemoteJoins reqId logger agentLicenseKey env reqHeaders userInfo resp remoteJoins reqUnparsed tracesPropagator
RJ.processRemoteJoins reqId logger agentLicenseKey env reqHeaders userInfo resp remoteJoins reqUnparsed tracesPropagator traceQueryStatus
pure $ (AnnotatedResponsePart telemTimeIO_DT Telem.Local finalResponse [], modelInfo)
E.ExecStepRemote rsi resultCustomizer gqlReq remoteJoins -> do
logQueryLog logger $ QueryLog reqUnparsed Nothing reqId QueryLogKindRemoteSchema
@ -522,7 +524,7 @@ runGQ env sqlGenCtx sc enableAL readOnlyMode remoteSchemaResponsePriority header
(time, resp, modelInfo) <- doQErr $ do
(time, (resp, _)) <- EA.runActionExecution userInfo aep
(finalResponse, modelInfo) <-
RJ.processRemoteJoins reqId logger agentLicenseKey env reqHeaders userInfo resp remoteJoins reqUnparsed tracesPropagator
RJ.processRemoteJoins reqId logger agentLicenseKey env reqHeaders userInfo resp remoteJoins reqUnparsed tracesPropagator traceQueryStatus
pure (time, finalResponse, modelInfo)
pure $ (AnnotatedResponsePart time Telem.Empty resp [], modelInfo)
E.ExecStepRaw json -> do
@ -546,7 +548,7 @@ runGQ env sqlGenCtx sc enableAL readOnlyMode remoteSchemaResponsePriority header
\(EB.DBStepInfo _ sourceConfig genSql tx resolvedConnectionTemplate :: EB.DBStepInfo b) ->
runDBMutation @b reqId reqUnparsed fieldName userInfo logger agentLicenseKey sourceConfig (fmap EB.arResult tx) genSql resolvedConnectionTemplate
(finalResponse, modelInfo) <-
RJ.processRemoteJoins reqId logger agentLicenseKey env reqHeaders userInfo resp remoteJoins reqUnparsed tracesPropagator
RJ.processRemoteJoins reqId logger agentLicenseKey env reqHeaders userInfo resp remoteJoins reqUnparsed tracesPropagator traceQueryStatus
pure $ (AnnotatedResponsePart telemTimeIO_DT Telem.Local finalResponse responseHeaders, modelInfo)
E.ExecStepRemote rsi resultCustomizer gqlReq remoteJoins -> do
logQueryLog logger $ QueryLog reqUnparsed Nothing reqId QueryLogKindRemoteSchema
@ -556,7 +558,7 @@ runGQ env sqlGenCtx sc enableAL readOnlyMode remoteSchemaResponsePriority header
(time, (resp, hdrs), modelInfo) <- doQErr $ do
(time, (resp, hdrs)) <- EA.runActionExecution userInfo aep
(finalResponse, modelInfo) <-
RJ.processRemoteJoins reqId logger agentLicenseKey env reqHeaders userInfo resp remoteJoins reqUnparsed tracesPropagator
RJ.processRemoteJoins reqId logger agentLicenseKey env reqHeaders userInfo resp remoteJoins reqUnparsed tracesPropagator traceQueryStatus
pure (time, (finalResponse, hdrs), modelInfo)
pure $ (AnnotatedResponsePart time Telem.Empty resp $ fromMaybe [] hdrs, modelInfo)
E.ExecStepRaw json -> do
@ -586,6 +588,7 @@ runGQ env sqlGenCtx sc enableAL readOnlyMode remoteSchemaResponsePriority header
remoteJoins
reqUnparsed
tracesPropagator
traceQueryStatus
let filteredHeaders = filter ((== "Set-Cookie") . fst) remoteResponseHeaders
pure $ (AnnotatedResponsePart telemTimeIO_DT Telem.Remote finalResponse filteredHeaders, modelInfo)
@ -809,6 +812,7 @@ runGQBatched ::
ResponseInternalErrorsConfig ->
RemoteSchemaResponsePriority ->
HeaderPrecedence ->
TraceQueryStatus ->
UserInfo ->
Wai.IpAddress ->
[HTTP.Header] ->
@ -816,10 +820,10 @@ runGQBatched ::
-- | the batched request with unparsed GraphQL query
GQLBatchedReqs (GQLReq GQLQueryText) ->
m (HttpLogGraphQLInfo, HttpResponse EncJSON)
runGQBatched env sqlGenCtx sc enableAL readOnlyMode prometheusMetrics logger agentLicenseKey reqId responseErrorsConfig remoteSchemaResponsePriority headerPrecedence userInfo ipAddress reqHdrs queryType query =
runGQBatched env sqlGenCtx sc enableAL readOnlyMode prometheusMetrics logger agentLicenseKey reqId responseErrorsConfig remoteSchemaResponsePriority headerPrecedence traceQueryStatus userInfo ipAddress reqHdrs queryType query =
case query of
GQLSingleRequest req -> do
(gqlQueryOperationLog, httpResp) <- runGQ env sqlGenCtx sc enableAL readOnlyMode remoteSchemaResponsePriority headerPrecedence prometheusMetrics logger agentLicenseKey reqId userInfo ipAddress reqHdrs queryType req responseErrorsConfig
(gqlQueryOperationLog, httpResp) <- runGQ env sqlGenCtx sc enableAL readOnlyMode remoteSchemaResponsePriority headerPrecedence traceQueryStatus prometheusMetrics logger agentLicenseKey reqId userInfo ipAddress reqHdrs queryType req responseErrorsConfig
let httpLoggingGQInfo = (CommonHttpLogMetadata L.RequestModeSingle (Just (GQLSingleRequest (GQLQueryOperationSuccess gqlQueryOperationLog))), (PQHSetSingleton (gqolParameterizedQueryHash gqlQueryOperationLog)))
pure (httpLoggingGQInfo, snd <$> httpResp)
GQLBatchedReqs reqs -> do
@ -832,7 +836,7 @@ runGQBatched env sqlGenCtx sc enableAL readOnlyMode prometheusMetrics logger age
flip HttpResponse []
. encJFromList
. map (either (encJFromJEncoding . encodeGQErr includeInternal) _hrBody)
responses <- for reqs \req -> fmap (req,) $ try $ (fmap . fmap . fmap) snd $ runGQ env sqlGenCtx sc enableAL readOnlyMode remoteSchemaResponsePriority headerPrecedence prometheusMetrics logger agentLicenseKey reqId userInfo ipAddress reqHdrs queryType req responseErrorsConfig
responses <- for reqs \req -> fmap (req,) $ try $ (fmap . fmap . fmap) snd $ runGQ env sqlGenCtx sc enableAL readOnlyMode remoteSchemaResponsePriority headerPrecedence traceQueryStatus prometheusMetrics logger agentLicenseKey reqId userInfo ipAddress reqHdrs queryType req responseErrorsConfig
let requestsOperationLogs = map fst $ rights $ map snd responses
batchOperationLogs =
map

View File

@ -98,9 +98,10 @@ createWSServerApp enabledLogTypes serverEnv connInitTimeout licenseKeyCache = \
onMessageHandler conn bs sp = do
headerPrecedence <- liftIO $ acHeaderPrecedence <$> getAppContext (_wseAppStateRef serverEnv)
traceQueryStatus <- liftIO $ acTraceQueryStatus <$> getAppContext (_wseAppStateRef serverEnv)
responseErrorsConfig <- liftIO $ acResponseInternalErrorsConfig <$> getAppContext (_wseAppStateRef serverEnv)
mask_
$ onMessage enabledLogTypes getAuthMode serverEnv conn bs (wsActions sp) licenseKeyCache responseErrorsConfig headerPrecedence
$ onMessage enabledLogTypes getAuthMode serverEnv conn bs (wsActions sp) licenseKeyCache responseErrorsConfig headerPrecedence traceQueryStatus
onCloseHandler conn = mask_ do
granularPrometheusMetricsState <- runGetPrometheusMetricsGranularity

View File

@ -105,7 +105,7 @@ import Hasura.Server.Prometheus
recordGraphqlOperationMetric,
)
import Hasura.Server.Telemetry.Counters qualified as Telem
import Hasura.Server.Types (GranularPrometheusMetricsState (..), HeaderPrecedence, ModelInfoLogState (..), MonadGetPolicies (..), RemoteSchemaResponsePriority, RequestId, getRequestId)
import Hasura.Server.Types (GranularPrometheusMetricsState (..), HeaderPrecedence, ModelInfoLogState (..), MonadGetPolicies (..), RemoteSchemaResponsePriority, RequestId, TraceQueryStatus, getRequestId)
import Hasura.Services.Network
import Hasura.Session
import Hasura.Tracing qualified as Tracing
@ -449,8 +449,9 @@ onStart ::
WS.WSActions WSConnData ->
ResponseInternalErrorsConfig ->
HeaderPrecedence ->
TraceQueryStatus ->
m ()
onStart enabledLogTypes agentLicenseKey serverEnv wsConn shouldCaptureVariables (StartMsg opId q) onMessageActions responseErrorsConfig headerPrecedence = catchAndIgnore $ do
onStart enabledLogTypes agentLicenseKey serverEnv wsConn shouldCaptureVariables (StartMsg opId q) onMessageActions responseErrorsConfig headerPrecedence traceQueryStatus = catchAndIgnore $ do
modelInfoLogStatus' <- runGetModelInfoLogStatus
modelInfoLogStatus <- liftIO modelInfoLogStatus'
granularPrometheusMetricsState <- runGetPrometheusMetricsGranularity
@ -521,6 +522,7 @@ onStart enabledLogTypes agentLicenseKey serverEnv wsConn shouldCaptureVariables
requestId
responseErrorsConfig
headerPrecedence
traceQueryStatus
(parameterizedQueryHash, execPlan, modelInfoList) <- onLeft execPlanE (withComplete . preExecErr granularPrometheusMetricsState requestId (Just gqlOpType) opName Nothing)
@ -564,7 +566,7 @@ onStart enabledLogTypes agentLicenseKey serverEnv wsConn shouldCaptureVariables
genSql
resolvedConnectionTemplate
(finalResponse, modelInfo) <-
RJ.processRemoteJoins requestId logger agentLicenseKey env reqHdrs userInfo resp remoteJoins q tracesPropagator
RJ.processRemoteJoins requestId logger agentLicenseKey env reqHdrs userInfo resp remoteJoins q tracesPropagator traceQueryStatus
pure $ (AnnotatedResponsePart telemTimeIO_DT Telem.Local finalResponse [], modelInfo)
E.ExecStepRemote rsi resultCustomizer gqlReq remoteJoins -> do
logQueryLog logger $ QueryLog q Nothing requestId QueryLogKindRemoteSchema
@ -574,7 +576,7 @@ onStart enabledLogTypes agentLicenseKey serverEnv wsConn shouldCaptureVariables
(time, (resp, _), modelInfo) <- doQErr $ do
(time, (resp, hdrs)) <- EA.runActionExecution userInfo actionExecPlan
(finalResponse, modelInfo) <-
RJ.processRemoteJoins requestId logger agentLicenseKey env reqHdrs userInfo resp remoteJoins q tracesPropagator
RJ.processRemoteJoins requestId logger agentLicenseKey env reqHdrs userInfo resp remoteJoins q tracesPropagator traceQueryStatus
pure (time, (finalResponse, hdrs), modelInfo)
pure $ (AnnotatedResponsePart time Telem.Empty resp [], modelInfo)
E.ExecStepRaw json -> do
@ -648,14 +650,14 @@ onStart enabledLogTypes agentLicenseKey serverEnv wsConn shouldCaptureVariables
genSql
resolvedConnectionTemplate
(finalResponse, modelInfo) <-
RJ.processRemoteJoins requestId logger agentLicenseKey env reqHdrs userInfo resp remoteJoins q tracesPropagator
RJ.processRemoteJoins requestId logger agentLicenseKey env reqHdrs userInfo resp remoteJoins q tracesPropagator traceQueryStatus
pure $ (AnnotatedResponsePart telemTimeIO_DT Telem.Local finalResponse [], modelInfo)
E.ExecStepAction actionExecPlan _ remoteJoins -> do
logQueryLog logger $ QueryLog q Nothing requestId QueryLogKindAction
(time, (resp, hdrs), modelInfo) <- doQErr $ do
(time, (resp, hdrs)) <- EA.runActionExecution userInfo actionExecPlan
(finalResponse, modelInfo) <-
RJ.processRemoteJoins requestId logger agentLicenseKey env reqHdrs userInfo resp remoteJoins q tracesPropagator
RJ.processRemoteJoins requestId logger agentLicenseKey env reqHdrs userInfo resp remoteJoins q tracesPropagator traceQueryStatus
pure (time, (finalResponse, hdrs), modelInfo)
pure $ (AnnotatedResponsePart time Telem.Empty resp $ fromMaybe [] hdrs, modelInfo)
E.ExecStepRemote rsi resultCustomizer gqlReq remoteJoins -> do
@ -859,6 +861,7 @@ onStart enabledLogTypes agentLicenseKey serverEnv wsConn shouldCaptureVariables
remoteJoins
reqUnparsed
tracesPropagator
traceQueryStatus
return $ (AnnotatedResponsePart telemTimeIO_DT Telem.Remote finalResponse [], modelInfo)
WSServerEnv
@ -1113,8 +1116,9 @@ onMessage ::
Maybe (CredentialCache AgentLicenseKey) ->
ResponseInternalErrorsConfig ->
HeaderPrecedence ->
TraceQueryStatus ->
m ()
onMessage enabledLogTypes authMode serverEnv wsConn msgRaw onMessageActions agentLicenseKey responseErrorsConfig headerPrecedence = do
onMessage enabledLogTypes authMode serverEnv wsConn msgRaw onMessageActions agentLicenseKey responseErrorsConfig headerPrecedence traceQueryStatus = do
Tracing.newTrace (_wseTraceSamplingPolicy serverEnv) "websocket" do
case J.eitherDecode msgRaw of
Left e -> do
@ -1138,7 +1142,7 @@ onMessage enabledLogTypes authMode serverEnv wsConn msgRaw onMessageActions agen
if _mcAnalyzeQueryVariables (scMetricsConfig schemaCache)
then CaptureQueryVariables
else DoNotCaptureQueryVariables
onStart enabledLogTypes agentLicenseKey serverEnv wsConn shouldCaptureVariables startMsg onMessageActions responseErrorsConfig headerPrecedence
onStart enabledLogTypes agentLicenseKey serverEnv wsConn shouldCaptureVariables startMsg onMessageActions responseErrorsConfig headerPrecedence traceQueryStatus
CMStop stopMsg -> do
granularPrometheusMetricsState <- runGetPrometheusMetricsGranularity
onStop serverEnv wsConn stopMsg granularPrometheusMetricsState

View File

@ -591,7 +591,7 @@ v1Alpha1GQHandler queryType query = do
reqHeaders <- asks hcReqHeaders
ipAddress <- asks hcSourceIpAddress
requestId <- asks hcRequestId
GH.runGQBatched acEnvironment acSQLGenCtx schemaCache acEnableAllowlist appEnvEnableReadOnlyMode appEnvPrometheusMetrics (_lsLogger appEnvLoggers) appEnvLicenseKeyCache requestId acResponseInternalErrorsConfig acRemoteSchemaResponsePriority acHeaderPrecedence userInfo ipAddress reqHeaders queryType query
GH.runGQBatched acEnvironment acSQLGenCtx schemaCache acEnableAllowlist appEnvEnableReadOnlyMode appEnvPrometheusMetrics (_lsLogger appEnvLoggers) appEnvLicenseKeyCache requestId acResponseInternalErrorsConfig acRemoteSchemaResponsePriority acHeaderPrecedence acTraceQueryStatus userInfo ipAddress reqHeaders queryType query
v1GQHandler ::
( MonadIO m,
@ -960,7 +960,7 @@ httpApp setupHook appStateRef AppEnv {..} consoleType ekgStore closeWebsocketsOn
Spock.PATCH -> pure EP.PATCH
other -> throw400 BadRequest $ "Method " <> tshow other <> " not supported."
_ -> throw400 BadRequest $ "Nonstandard method not allowed for REST endpoints"
fmap JSONResp <$> runCustomEndpoint acEnvironment acSQLGenCtx schemaCache acEnableAllowlist appEnvEnableReadOnlyMode acRemoteSchemaResponsePriority acHeaderPrecedence appEnvPrometheusMetrics (_lsLogger appEnvLoggers) appEnvLicenseKeyCache requestId userInfo reqHeaders ipAddress req endpoints responseErrorsConfig
fmap JSONResp <$> runCustomEndpoint acEnvironment acSQLGenCtx schemaCache acEnableAllowlist appEnvEnableReadOnlyMode acRemoteSchemaResponsePriority acHeaderPrecedence acTraceQueryStatus appEnvPrometheusMetrics (_lsLogger appEnvLoggers) appEnvLicenseKeyCache requestId userInfo reqHeaders ipAddress req endpoints responseErrorsConfig
-- See Issue #291 for discussion around restified feature
Spock.hookRouteAll ("api" <//> "rest" <//> Spock.wildcard) $ \wildcard -> do

View File

@ -225,6 +225,7 @@ mkServeOptions sor@ServeOptionsRaw {..} = do
soPersistedQueriesTtl <- withOptionDefault rsoPersistedQueriesTtl persistedQueriesTtlOption
soRemoteSchemaResponsePriority <- withOptionDefault rsoRemoteSchemaResponsePriority remoteSchemaResponsePriorityOption
soHeaderPrecedence <- withOptionDefault rsoHeaderPrecedence configuredHeaderPrecedenceOption
soTraceQueryStatus <- withOptionDefault rsoTraceQueryStatus traceQueryStatusOption
pure ServeOptions {..}
-- | Fetch Postgres 'Query.ConnParams' components from the environment

View File

@ -71,6 +71,7 @@ module Hasura.Server.Init.Arg.Command.Serve
persistedQueriesTtlOption,
remoteSchemaResponsePriorityOption,
configuredHeaderPrecedenceOption,
traceQueryStatusOption,
-- * Pretty Printer
serveCmdFooter,
@ -167,6 +168,7 @@ serveCommandParser =
<*> parsePersistedQueriesTtl
<*> parseRemoteSchemaResponsePriority
<*> parseConfiguredHeaderPrecedence
<*> parseTraceQueryStatus
--------------------------------------------------------------------------------
-- Serve Options
@ -1341,6 +1343,14 @@ parseConfiguredHeaderPrecedence =
<> Opt.help (Config._helpMessage configuredHeaderPrecedenceOption)
)
parseTraceQueryStatus :: Opt.Parser (Maybe Types.TraceQueryStatus)
parseTraceQueryStatus =
(bool Nothing (Just Types.TraceQueryEnabled))
<$> Opt.switch
( Opt.long "trace-sql-query"
<> Opt.help (Config._helpMessage traceQueryStatusOption)
)
configuredHeaderPrecedenceOption :: Config.Option Types.HeaderPrecedence
configuredHeaderPrecedenceOption =
Config.Option
@ -1351,6 +1361,15 @@ configuredHeaderPrecedenceOption =
<> "when delivering payload to webhook for actions and input validations. (default: false)"
}
traceQueryStatusOption :: Config.Option Types.TraceQueryStatus
traceQueryStatusOption =
Config.Option
{ Config._default = Types.TraceQueryDisabled,
Config._envVar = "HASURA_GRAPHQL_ENABLE_QUERY_TRACING",
Config._helpMessage =
"Enable query tracing for all queries. (default: false)"
}
--------------------------------------------------------------------------------
-- Pretty Printer

View File

@ -332,7 +332,8 @@ data ServeOptionsRaw impl = ServeOptionsRaw
rsoPersistedQueries :: Maybe Server.Types.PersistedQueriesState,
rsoPersistedQueriesTtl :: Maybe Int,
rsoRemoteSchemaResponsePriority :: Maybe Server.Types.RemoteSchemaResponsePriority,
rsoHeaderPrecedence :: Maybe Server.Types.HeaderPrecedence
rsoHeaderPrecedence :: Maybe Server.Types.HeaderPrecedence,
rsoTraceQueryStatus :: Maybe Server.Types.TraceQueryStatus
}
deriving stock instance (Show (Logging.EngineLogType impl)) => Show (ServeOptionsRaw impl)
@ -643,7 +644,8 @@ data ServeOptions impl = ServeOptions
soPersistedQueries :: Server.Types.PersistedQueriesState,
soPersistedQueriesTtl :: Int,
soRemoteSchemaResponsePriority :: Server.Types.RemoteSchemaResponsePriority,
soHeaderPrecedence :: Server.Types.HeaderPrecedence
soHeaderPrecedence :: Server.Types.HeaderPrecedence,
soTraceQueryStatus :: Server.Types.TraceQueryStatus
}
-- | 'ResponseInternalErrorsConfig' represents the encoding of the

View File

@ -393,3 +393,6 @@ instance FromEnv Server.Types.RemoteSchemaResponsePriority where
instance FromEnv Server.Types.HeaderPrecedence where
fromEnv = fmap (bool Server.Types.ClientHeadersFirst Server.Types.ConfiguredHeadersFirst) . fromEnv @Bool
instance FromEnv Server.Types.TraceQueryStatus where
fromEnv = fmap (bool Server.Types.TraceQueryDisabled Server.Types.TraceQueryEnabled) . fromEnv @Bool

View File

@ -120,6 +120,7 @@ runCustomEndpoint ::
ReadOnlyMode ->
RemoteSchemaResponsePriority ->
HeaderPrecedence ->
TraceQueryStatus ->
PrometheusMetrics ->
L.Logger L.Hasura ->
Maybe (CredentialCache AgentLicenseKey) ->
@ -131,7 +132,7 @@ runCustomEndpoint ::
EndpointTrie GQLQueryWithText ->
Init.ResponseInternalErrorsConfig ->
m (HttpLogGraphQLInfo, HttpResponse EncJSON)
runCustomEndpoint env sqlGenCtx sc enableAL readOnlyMode remoteSchemaResponsePriority headerPrecedence prometheusMetrics logger agentLicenseKey requestId userInfo reqHeaders ipAddress RestRequest {..} endpoints responseErrorsConfig = do
runCustomEndpoint env sqlGenCtx sc enableAL readOnlyMode remoteSchemaResponsePriority headerPrecedence traceQueryStatus prometheusMetrics logger agentLicenseKey requestId userInfo reqHeaders ipAddress RestRequest {..} endpoints responseErrorsConfig = do
-- First match the path to an endpoint.
case matchPath reqMethod (T.split (== '/') reqPath) endpoints of
MatchFound (queryx :: EndpointMetadata GQLQueryWithText) matches ->
@ -161,7 +162,7 @@ runCustomEndpoint env sqlGenCtx sc enableAL readOnlyMode remoteSchemaResponsePri
-- with the query string from the schema cache, and pass it
-- through to the /v1/graphql endpoint.
(httpLoggingMetadata, handlerResp) <- do
(gqlOperationLog, resp) <- GH.runGQ env sqlGenCtx sc enableAL readOnlyMode remoteSchemaResponsePriority headerPrecedence prometheusMetrics logger agentLicenseKey requestId userInfo ipAddress reqHeaders E.QueryHasura (mkPassthroughRequest queryx resolvedVariables) responseErrorsConfig
(gqlOperationLog, resp) <- GH.runGQ env sqlGenCtx sc enableAL readOnlyMode remoteSchemaResponsePriority headerPrecedence traceQueryStatus prometheusMetrics logger agentLicenseKey requestId userInfo ipAddress reqHeaders E.QueryHasura (mkPassthroughRequest queryx resolvedVariables) responseErrorsConfig
let httpLoggingGQInfo = (CommonHttpLogMetadata RequestModeNonBatchable Nothing, (PQHSetSingleton (gqolParameterizedQueryHash gqlOperationLog)))
return (httpLoggingGQInfo, fst <$> resp)
case sequence handlerResp of

View File

@ -33,6 +33,7 @@ module Hasura.Server.Types
MonadGetPolicies (..),
RemoteSchemaResponsePriority (..),
HeaderPrecedence (..),
TraceQueryStatus (..),
)
where
@ -398,3 +399,18 @@ instance ToJSON HeaderPrecedence where
toJSON = \case
ConfiguredHeadersFirst -> Bool True
ClientHeadersFirst -> Bool False
data TraceQueryStatus
= TraceQueryEnabled
| TraceQueryDisabled
deriving (Eq, Show, Generic)
instance FromJSON TraceQueryStatus where
parseJSON = withBool "TraceQueryStatus" $ \case
False -> pure TraceQueryDisabled
True -> pure TraceQueryEnabled
instance ToJSON TraceQueryStatus where
toJSON = \case
TraceQueryDisabled -> Bool False
TraceQueryEnabled -> Bool True

View File

@ -101,7 +101,8 @@ emptyServeOptionsRaw =
rsoPersistedQueries = Nothing,
rsoPersistedQueriesTtl = Nothing,
rsoRemoteSchemaResponsePriority = Nothing,
rsoHeaderPrecedence = Nothing
rsoHeaderPrecedence = Nothing,
rsoTraceQueryStatus = Nothing
}
mkServeOptionsSpec :: Hspec.Spec

View File

@ -100,7 +100,8 @@ serveOptions =
soPersistedQueries = Init._default Init.persistedQueriesOption,
soPersistedQueriesTtl = Init._default Init.persistedQueriesTtlOption,
soRemoteSchemaResponsePriority = Init._default Init.remoteSchemaResponsePriorityOption,
soHeaderPrecedence = Init._default Init.configuredHeaderPrecedenceOption
soHeaderPrecedence = Init._default Init.configuredHeaderPrecedenceOption,
soTraceQueryStatus = Init._default Init.traceQueryStatusOption
}
-- | What log level should be used by the engine; this is not exported, and