mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-16 09:51:59 +03:00
982b5a3d15
https://github.com/hasura/graphql-engine-mono/pull/2306 GitOrigin-RevId: 066a02fc57711b1faad447e6e448e3e004376c74
538 lines
20 KiB
Haskell
538 lines
20 KiB
Haskell
-- This is taken from wai-logger and customised for our use
|
|
|
|
module Hasura.Server.Logging
|
|
( StartupLog(..)
|
|
, PGLog(..)
|
|
, RequestMode(..)
|
|
, mkInconsMetadataLog
|
|
, mkHttpAccessLogContext
|
|
, mkHttpErrorLogContext
|
|
, mkHttpLog
|
|
, HttpInfoLog(..)
|
|
, OperationLog(..)
|
|
, HttpLogContext(..)
|
|
, WebHookLog(..)
|
|
, HttpException
|
|
, HttpLog (..)
|
|
, GQLBatchQueryOperationLog (..)
|
|
, GQLQueryOperationSuccessLog (..)
|
|
, GQLQueryOperationErrorLog (..)
|
|
, MetadataLog(..)
|
|
, EnvVarsMovedToMetadata(..)
|
|
, DeprecatedEnvVars(..)
|
|
, logDeprecatedEnvVars
|
|
, CommonHttpLogMetadata(..)
|
|
, HttpLogMetadata
|
|
, buildHttpLogMetadata
|
|
, emptyHttpLogMetadata
|
|
) where
|
|
|
|
import Hasura.Prelude
|
|
|
|
import qualified Data.ByteString.Lazy as BL
|
|
import qualified Data.Environment as Env
|
|
import qualified Data.HashMap.Strict as HM
|
|
import qualified Data.HashSet as Set
|
|
import qualified Data.List.NonEmpty as NE
|
|
import qualified Data.TByteString as TBS
|
|
import qualified Data.Text as T
|
|
import qualified Network.HTTP.Types as HTTP
|
|
import qualified Network.Wai.Extended as Wai
|
|
|
|
import Data.Aeson
|
|
import Data.Aeson.TH
|
|
import Data.Int (Int64)
|
|
import Data.Text.Extended
|
|
|
|
import qualified Hasura.GraphQL.Transport.HTTP.Protocol as GH
|
|
|
|
import Hasura.Base.Error
|
|
import Hasura.GraphQL.ParameterizedQueryHash
|
|
import Hasura.HTTP
|
|
import Hasura.Logging
|
|
import Hasura.Metadata.Class
|
|
import Hasura.RQL.Types
|
|
import Hasura.Server.Compression
|
|
import Hasura.Server.Types
|
|
import Hasura.Server.Utils (DeprecatedEnvVars (..),
|
|
EnvVarsMovedToMetadata (..),
|
|
deprecatedEnvVars, envVarsMovedToMetadata)
|
|
import Hasura.Session
|
|
import Hasura.Tracing (TraceT)
|
|
|
|
|
|
data StartupLog
|
|
= StartupLog
|
|
{ slLogLevel :: !LogLevel
|
|
, slKind :: !Text
|
|
, slInfo :: !Value
|
|
} deriving (Show, Eq)
|
|
|
|
instance ToJSON StartupLog where
|
|
toJSON (StartupLog _ k info) =
|
|
object [ "kind" .= k
|
|
, "info" .= info
|
|
]
|
|
|
|
instance ToEngineLog StartupLog Hasura where
|
|
toEngineLog startupLog =
|
|
(slLogLevel startupLog, ELTStartup, toJSON startupLog)
|
|
|
|
data PGLog
|
|
= PGLog
|
|
{ plLogLevel :: !LogLevel
|
|
, plMessage :: !Text
|
|
} deriving (Show, Eq)
|
|
|
|
instance ToJSON PGLog where
|
|
toJSON (PGLog _ msg) =
|
|
object ["message" .= msg]
|
|
|
|
instance ToEngineLog PGLog Hasura where
|
|
toEngineLog pgLog =
|
|
(plLogLevel pgLog, ELTInternal ILTPgClient, toJSON pgLog)
|
|
|
|
data MetadataLog
|
|
= MetadataLog
|
|
{ mlLogLevel :: !LogLevel
|
|
, mlMessage :: !Text
|
|
, mlInfo :: !Value
|
|
} deriving (Show, Eq)
|
|
|
|
instance ToJSON MetadataLog where
|
|
toJSON (MetadataLog _ msg infoVal) =
|
|
object [ "message" .= msg
|
|
, "info" .= infoVal
|
|
]
|
|
|
|
instance ToEngineLog MetadataLog Hasura where
|
|
toEngineLog ml =
|
|
(mlLogLevel ml, ELTInternal ILTMetadata, toJSON ml)
|
|
|
|
mkInconsMetadataLog :: [InconsistentMetadata] -> MetadataLog
|
|
mkInconsMetadataLog objs =
|
|
MetadataLog LevelWarn "Inconsistent Metadata!" $
|
|
object [ "objects" .= objs]
|
|
|
|
data WebHookLog
|
|
= WebHookLog
|
|
{ whlLogLevel :: !LogLevel
|
|
, whlStatusCode :: !(Maybe HTTP.Status)
|
|
, whlUrl :: !Text
|
|
, whlMethod :: !HTTP.StdMethod
|
|
, whlError :: !(Maybe HttpException)
|
|
, whlResponse :: !(Maybe Text)
|
|
, whlMessage :: !(Maybe Text)
|
|
} deriving (Show)
|
|
|
|
instance ToEngineLog WebHookLog Hasura where
|
|
toEngineLog webHookLog =
|
|
(whlLogLevel webHookLog, ELTWebhookLog, toJSON webHookLog)
|
|
|
|
instance ToJSON WebHookLog where
|
|
toJSON whl =
|
|
object [ "status_code" .= (HTTP.statusCode <$> whlStatusCode whl)
|
|
, "url" .= whlUrl whl
|
|
, "method" .= show (whlMethod whl)
|
|
, "http_error" .= whlError whl
|
|
, "response" .= whlResponse whl
|
|
, "message" .= whlMessage whl
|
|
]
|
|
|
|
-- | GQLQueryOperationSuccessLog captures all the data required to construct
|
|
-- an HTTP success log.
|
|
data GQLQueryOperationSuccessLog
|
|
= GQLQueryOperationSuccessLog
|
|
{ gqolQuery :: !GH.GQLReqUnparsed
|
|
, gqolQueryExecutionTime :: !DiffTime
|
|
, gqolResponseSize :: !Int64
|
|
, gqolRequestSize :: !Int64
|
|
, gqolParameterizedQueryHash :: !ParameterizedQueryHash
|
|
} deriving (Show, Eq)
|
|
$(deriveToJSON hasuraJSON{omitNothingFields = True} ''GQLQueryOperationSuccessLog)
|
|
|
|
-- | GQLQueryOperationErrorLog captures the request along with the error message
|
|
data GQLQueryOperationErrorLog
|
|
= GQLQueryOperationErrorLog
|
|
{ gqelQuery :: !GH.GQLReqUnparsed
|
|
, gqelError :: !QErr
|
|
} deriving (Show, Eq)
|
|
$(deriveToJSON hasuraJSON ''GQLQueryOperationErrorLog)
|
|
|
|
data GQLBatchQueryOperationLog
|
|
= GQLQueryOperationSuccess !GQLQueryOperationSuccessLog
|
|
| GQLQueryOperationError !GQLQueryOperationErrorLog
|
|
deriving (Show, Eq)
|
|
|
|
instance ToJSON GQLBatchQueryOperationLog where
|
|
toJSON = \case
|
|
GQLQueryOperationSuccess successLog -> toJSON successLog
|
|
GQLQueryOperationError errorLog -> toJSON errorLog
|
|
|
|
-- | whether a request is executed in batched mode or not
|
|
data RequestMode
|
|
= RequestModeBatched
|
|
-- ^ this request is batched
|
|
| RequestModeSingle
|
|
-- ^ this is a single request
|
|
| RequestModeNonBatchable
|
|
-- ^ this request is of a kind for which batching is not done or does not make sense
|
|
| RequestModeError
|
|
-- ^ the execution of this request failed
|
|
deriving (Show, Eq)
|
|
|
|
instance ToJSON RequestMode where
|
|
toJSON = \case
|
|
RequestModeBatched -> "batched"
|
|
RequestModeSingle -> "single"
|
|
RequestModeNonBatchable -> "non-graphql"
|
|
RequestModeError -> "error"
|
|
|
|
data CommonHttpLogMetadata
|
|
= CommonHttpLogMetadata
|
|
{ _chlmRequestMode :: !RequestMode
|
|
, _chlmBatchOperationLog :: !(Maybe (GH.GQLBatchedReqs GQLBatchQueryOperationLog))
|
|
}
|
|
deriving (Show, Eq)
|
|
|
|
-- | The http-log metadata attached to HTTP requests running in the monad 'm', split into a
|
|
-- common portion that is present regardless of 'm', and a monad-specific one defined in the
|
|
-- 'HttpLog' instance.
|
|
--
|
|
-- This allows us to not have to duplicate the code that generates the common part of the metadata
|
|
-- across OSS and Pro, so that instances only have to implement the part of it unique to them.
|
|
type HttpLogMetadata m = (CommonHttpLogMetadata, ExtraHttpLogMetadata m)
|
|
|
|
buildHttpLogMetadata
|
|
:: forall m
|
|
. HttpLog m
|
|
=> ParameterizedQueryHashList
|
|
-> RequestMode
|
|
-> Maybe (GH.GQLBatchedReqs GQLBatchQueryOperationLog)
|
|
-> HttpLogMetadata m
|
|
buildHttpLogMetadata paramQueryHashList requestMode batchQueryOperationLog =
|
|
(CommonHttpLogMetadata requestMode batchQueryOperationLog, buildExtraHttpLogMetadata @m paramQueryHashList)
|
|
|
|
-- | synonym for clarity, writing `emptyHttpLogMetadata @m` instead of `def @(HttpLogMetadata m)`
|
|
emptyHttpLogMetadata :: forall m. HttpLog m => HttpLogMetadata m
|
|
emptyHttpLogMetadata = (CommonHttpLogMetadata RequestModeNonBatchable Nothing, emptyExtraHttpLogMetadata @m)
|
|
|
|
{- Note [Disable query printing when query-log is disabled]
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
As a temporary hack (as per https://github.com/hasura/graphql-engine-mono/issues/1770),
|
|
we want to print the graphql query string in `http-log` or `websocket-log` only
|
|
when `query-log` is enabled.
|
|
-}
|
|
|
|
class Monad m => HttpLog m where
|
|
|
|
-- | Extra http-log metadata that we attach when operating in 'm'.
|
|
type ExtraHttpLogMetadata m
|
|
|
|
emptyExtraHttpLogMetadata :: ExtraHttpLogMetadata m
|
|
|
|
buildExtraHttpLogMetadata :: ParameterizedQueryHashList -> ExtraHttpLogMetadata m
|
|
|
|
logHttpError
|
|
:: Logger Hasura
|
|
-- ^ the logger
|
|
-> HashSet (EngineLogType Hasura)
|
|
-- ^ this is only required for the short-term fix in https://github.com/hasura/graphql-engine-mono/issues/1770
|
|
-> Maybe UserInfo
|
|
-- ^ user info may or may not be present (error can happen during user resolution)
|
|
-> RequestId
|
|
-- ^ request id of the request
|
|
-> Wai.Request
|
|
-- ^ the Wai.Request object
|
|
-> (BL.ByteString, Maybe Value)
|
|
-- ^ the request body and parsed request
|
|
-> QErr
|
|
-- ^ the error
|
|
-> [HTTP.Header]
|
|
-- ^ list of request headers
|
|
-> m ()
|
|
|
|
logHttpSuccess
|
|
:: Logger Hasura
|
|
-- ^ the logger
|
|
-> HashSet (EngineLogType Hasura)
|
|
-- ^ this is only required for the short-term fix in https://github.com/hasura/graphql-engine-mono/issues/1770
|
|
-> Maybe UserInfo
|
|
-- ^ user info may or may not be present (error can happen during user resolution)
|
|
-> RequestId
|
|
-- ^ request id of the request
|
|
-> Wai.Request
|
|
-- ^ the Wai.Request object
|
|
-> (BL.ByteString, Maybe Value)
|
|
-- ^ the request body and parsed request
|
|
-> BL.ByteString
|
|
-- ^ the response bytes
|
|
-> BL.ByteString
|
|
-- ^ the compressed response bytes
|
|
-- ^ TODO (from master): make the above two type represented
|
|
-> Maybe (DiffTime, DiffTime)
|
|
-- ^ IO/network wait time and service time (respectively) for this request, if available.
|
|
-> Maybe CompressionType
|
|
-- ^ possible compression type
|
|
-> [HTTP.Header]
|
|
-- ^ list of request headers
|
|
-> HttpLogMetadata m
|
|
-> m ()
|
|
|
|
instance HttpLog m => HttpLog (TraceT m) where
|
|
|
|
type ExtraHttpLogMetadata (TraceT m) = ExtraHttpLogMetadata m
|
|
|
|
buildExtraHttpLogMetadata a = buildExtraHttpLogMetadata @m a
|
|
emptyExtraHttpLogMetadata = emptyExtraHttpLogMetadata @m
|
|
|
|
logHttpError a b c d e f g h = lift $ logHttpError a b c d e f g h
|
|
|
|
logHttpSuccess a b c d e f g h i j k l = lift $ logHttpSuccess a b c d e f g h i j k l
|
|
|
|
instance HttpLog m => HttpLog (ReaderT r m) where
|
|
|
|
type ExtraHttpLogMetadata (ReaderT r m) = ExtraHttpLogMetadata m
|
|
|
|
buildExtraHttpLogMetadata a = buildExtraHttpLogMetadata @m a
|
|
emptyExtraHttpLogMetadata = emptyExtraHttpLogMetadata @m
|
|
|
|
logHttpError a b c d e f g h = lift $ logHttpError a b c d e f g h
|
|
|
|
logHttpSuccess a b c d e f g h i j k l = lift $ logHttpSuccess a b c d e f g h i j k l
|
|
|
|
instance HttpLog m => HttpLog (MetadataStorageT m) where
|
|
|
|
type ExtraHttpLogMetadata (MetadataStorageT m) = ExtraHttpLogMetadata m
|
|
|
|
buildExtraHttpLogMetadata a = buildExtraHttpLogMetadata @m a
|
|
emptyExtraHttpLogMetadata = emptyExtraHttpLogMetadata @m
|
|
|
|
logHttpError a b c d e f g h = lift $ logHttpError a b c d e f g h
|
|
|
|
logHttpSuccess a b c d e f g h i j k l = lift $ logHttpSuccess a b c d e f g h i j k l
|
|
|
|
-- | Log information about the HTTP request
|
|
data HttpInfoLog
|
|
= HttpInfoLog
|
|
{ hlStatus :: !HTTP.Status
|
|
, hlMethod :: !Text
|
|
, hlSource :: !Wai.IpAddress
|
|
, hlPath :: !Text
|
|
, hlHttpVersion :: !HTTP.HttpVersion
|
|
, hlCompression :: !(Maybe CompressionType)
|
|
, hlHeaders :: ![HTTP.Header]
|
|
-- ^ all the request headers
|
|
} deriving (Show, Eq)
|
|
|
|
instance ToJSON HttpInfoLog where
|
|
toJSON (HttpInfoLog st met src path hv compressTypeM _) =
|
|
object [ "status" .= HTTP.statusCode st
|
|
, "method" .= met
|
|
, "ip" .= Wai.showIPAddress src
|
|
, "url" .= path
|
|
, "http_version" .= show hv
|
|
, "content_encoding" .= (compressionTypeToTxt <$> compressTypeM)
|
|
]
|
|
|
|
-- | Information about a GraphQL/Hasura metadata operation over HTTP
|
|
data OperationLog
|
|
= OperationLog
|
|
{ olRequestId :: !RequestId
|
|
, olUserVars :: !(Maybe SessionVariables)
|
|
, olResponseSize :: !(Maybe Int64)
|
|
, olRequestReadTime :: !(Maybe Seconds)
|
|
-- ^ Request IO wait time, i.e. time spent reading the full request from the socket.
|
|
, olQueryExecutionTime :: !(Maybe Seconds)
|
|
-- ^ Service time, not including request IO wait time.
|
|
, olQuery :: !(Maybe Value)
|
|
, olRawQuery :: !(Maybe Text)
|
|
, olError :: !(Maybe QErr)
|
|
, olRequestMode :: !RequestMode
|
|
} deriving (Show, Eq)
|
|
|
|
$(deriveToJSON hasuraJSON{omitNothingFields = True} ''OperationLog)
|
|
|
|
-- | @BatchOperationSuccessLog@ contains the information required for a single
|
|
-- successful operation in a batch request for OSS. This type is a subset of the @GQLQueryOperationSuccessLog@
|
|
data BatchOperationSuccessLog
|
|
= BatchOperationSuccessLog
|
|
{ bolQuery :: !(Maybe Value)
|
|
, bolResponseSize :: !Int64
|
|
, bolQueryExecutionTime :: !Seconds
|
|
} deriving (Show, Eq)
|
|
$(deriveToJSON hasuraJSON{omitNothingFields = True} ''BatchOperationSuccessLog)
|
|
|
|
-- | @BatchOperationSuccessLog@ contains the information required for a single
|
|
-- erroneous operation in a batch request for OSS. This type is a subset of the @GQLQueryOperationErrorLog@
|
|
data BatchOperationErrorLog
|
|
= BatchOperationErrorLog
|
|
{ belQuery :: !(Maybe Value)
|
|
, belError :: !QErr
|
|
} deriving (Show, Eq)
|
|
$(deriveToJSON hasuraJSON{omitNothingFields = True} ''BatchOperationErrorLog)
|
|
|
|
data BatchOperationLog
|
|
= BatchOperationSuccess !BatchOperationSuccessLog
|
|
| BatchOperationError !BatchOperationErrorLog
|
|
deriving (Show, Eq)
|
|
|
|
instance ToJSON BatchOperationLog where
|
|
toJSON = \case
|
|
BatchOperationSuccess successLog -> toJSON successLog
|
|
BatchOperationError errorLog -> toJSON errorLog
|
|
|
|
data HttpLogContext
|
|
= HttpLogContext
|
|
{ hlcHttpInfo :: !HttpInfoLog
|
|
, hlcOperation :: !OperationLog
|
|
, hlcRequestId :: !RequestId
|
|
, hlcBatchedOperations :: !(Maybe (NE.NonEmpty BatchOperationLog))
|
|
} deriving (Show, Eq)
|
|
$(deriveToJSON hasuraJSON {omitNothingFields = True} ''HttpLogContext)
|
|
|
|
mkHttpAccessLogContext
|
|
:: Maybe UserInfo
|
|
-- ^ Maybe because it may not have been resolved
|
|
-> HashSet (EngineLogType Hasura)
|
|
-> RequestId
|
|
-> Wai.Request
|
|
-> (BL.ByteString, Maybe Value)
|
|
-> BL.ByteString
|
|
-> Maybe (DiffTime, DiffTime)
|
|
-> Maybe CompressionType
|
|
-> [HTTP.Header]
|
|
-> RequestMode
|
|
-> Maybe (GH.GQLBatchedReqs GQLBatchQueryOperationLog)
|
|
-> HttpLogContext
|
|
mkHttpAccessLogContext userInfoM enabledLogTypes reqId req (_, parsedReq) res mTiming compressTypeM headers batching queryLogMetadata =
|
|
let http = HttpInfoLog
|
|
{ hlStatus = status
|
|
, hlMethod = bsToTxt $ Wai.requestMethod req
|
|
, hlSource = Wai.getSourceFromFallback req
|
|
, hlPath = bsToTxt $ Wai.rawPathInfo req
|
|
, hlHttpVersion = Wai.httpVersion req
|
|
, hlCompression = compressTypeM
|
|
, hlHeaders = headers
|
|
}
|
|
op = OperationLog
|
|
{ olRequestId = reqId
|
|
, olUserVars = _uiSession <$> userInfoM
|
|
, olResponseSize = respSize
|
|
, olRequestReadTime = Seconds . fst <$> mTiming
|
|
, olQueryExecutionTime = Seconds . snd <$> mTiming
|
|
, olRequestMode = batching
|
|
-- See Note [Disable query printing when query-log is disabled]
|
|
, olQuery = bool Nothing parsedReq $ Set.member ELTQueryLog enabledLogTypes
|
|
, olRawQuery = Nothing
|
|
, olError = Nothing
|
|
}
|
|
batchOpLog =
|
|
queryLogMetadata >>= (\case
|
|
GH.GQLSingleRequest _ -> Nothing -- This case is aleady handled in the `OperationLog`
|
|
GH.GQLBatchedReqs opLogs ->
|
|
NE.nonEmpty $
|
|
map (\opLog ->
|
|
case opLog of
|
|
GQLQueryOperationSuccess (GQLQueryOperationSuccessLog {..}) ->
|
|
BatchOperationSuccess $
|
|
BatchOperationSuccessLog
|
|
((bool Nothing (Just $ toJSON gqolQuery)) $ Set.member ELTQueryLog enabledLogTypes)
|
|
gqolResponseSize
|
|
(convertDuration gqolQueryExecutionTime)
|
|
GQLQueryOperationError (GQLQueryOperationErrorLog {..}) ->
|
|
BatchOperationError $
|
|
BatchOperationErrorLog
|
|
(bool Nothing (Just $ toJSON gqelQuery) $ Set.member ELTQueryLog enabledLogTypes)
|
|
gqelError
|
|
) opLogs)
|
|
in HttpLogContext http op reqId batchOpLog
|
|
where
|
|
status = HTTP.status200
|
|
respSize = Just $ BL.length res
|
|
|
|
mkHttpErrorLogContext
|
|
:: Maybe UserInfo
|
|
-- ^ Maybe because it may not have been resolved
|
|
-> HashSet (EngineLogType Hasura)
|
|
-> RequestId
|
|
-> Wai.Request
|
|
-> (BL.ByteString, Maybe Value)
|
|
-> QErr
|
|
-> Maybe (DiffTime, DiffTime)
|
|
-> Maybe CompressionType
|
|
-> [HTTP.Header]
|
|
-> HttpLogContext
|
|
mkHttpErrorLogContext userInfoM enabledLogTypes reqId waiReq (reqBody, parsedReq) err mTiming compressTypeM headers =
|
|
let http = HttpInfoLog
|
|
{ hlStatus = qeStatus err
|
|
, hlMethod = bsToTxt $ Wai.requestMethod waiReq
|
|
, hlSource = Wai.getSourceFromFallback waiReq
|
|
, hlPath = bsToTxt $ Wai.rawPathInfo waiReq
|
|
, hlHttpVersion = Wai.httpVersion waiReq
|
|
, hlCompression = compressTypeM
|
|
, hlHeaders = headers
|
|
}
|
|
op = OperationLog
|
|
{ olRequestId = reqId
|
|
, olUserVars = _uiSession <$> userInfoM
|
|
, olResponseSize = Just $ BL.length $ encode err
|
|
, olRequestReadTime = Seconds . fst <$> mTiming
|
|
, olQueryExecutionTime = Seconds . snd <$> mTiming
|
|
, olQuery = reqToLog parsedReq
|
|
-- if parsedReq is Nothing, add the raw query
|
|
, olRawQuery = maybe (reqToLog $ Just $ bsToTxt $ BL.toStrict reqBody) (const Nothing) parsedReq
|
|
, olError = Just err
|
|
, olRequestMode = RequestModeError
|
|
}
|
|
|
|
-- See Note [Disable query printing when query-log is disabled]
|
|
reqToLog :: Maybe a -> Maybe a
|
|
reqToLog req = bool Nothing req $ Set.member ELTQueryLog enabledLogTypes
|
|
in HttpLogContext http op reqId Nothing -- Batched operation logs are always reported in logHttpSuccess even if there are errors
|
|
|
|
data HttpLogLine
|
|
= HttpLogLine
|
|
{ _hlLogLevel :: !LogLevel
|
|
, _hlLogLine :: !HttpLogContext
|
|
}
|
|
|
|
instance ToEngineLog HttpLogLine Hasura where
|
|
toEngineLog (HttpLogLine logLevel logLine) =
|
|
(logLevel, ELTHttpLog, toJSON logLine)
|
|
|
|
mkHttpLog :: HttpLogContext -> HttpLogLine
|
|
mkHttpLog httpLogCtx =
|
|
let isError = isJust $ olError $ hlcOperation httpLogCtx
|
|
logLevel = bool LevelInfo LevelError isError
|
|
in HttpLogLine logLevel httpLogCtx
|
|
|
|
-- | Log warning messages for deprecated environment variables
|
|
logDeprecatedEnvVars
|
|
:: Logger Hasura
|
|
-> Env.Environment
|
|
-> SourceCache
|
|
-> IO ()
|
|
logDeprecatedEnvVars logger env sources = do
|
|
let toText envVars = commaSeparated envVars
|
|
-- The environment variables that have been initialized by user
|
|
envVarsInitialized = fmap fst (Env.toList env)
|
|
checkDeprecatedEnvVars envs = T.pack <$> envVarsInitialized `intersect` envs
|
|
|
|
-- When a source named 'default' is present, it means that it is a migrated v2
|
|
-- hasura project. In such cases log those environment variables that are moved
|
|
-- to the metadata
|
|
onJust (HM.lookup SNDefault sources) $ \_defSource -> do
|
|
let deprecated = checkDeprecatedEnvVars (unEnvVarsMovedToMetadata envVarsMovedToMetadata)
|
|
unless (null deprecated) $
|
|
unLogger logger $ UnstructuredLog LevelWarn $ TBS.fromText $
|
|
"The following environment variables are deprecated and moved to metadata: " <>
|
|
toText deprecated
|
|
|
|
-- Log when completely deprecated environment variables are present
|
|
let deprecated = checkDeprecatedEnvVars (unDeprecatedEnvVars deprecatedEnvVars)
|
|
unless (null deprecated) $
|
|
unLogger logger $ UnstructuredLog LevelWarn $ TBS.fromText $
|
|
"The following environment variables are deprecated: " <>
|
|
toText deprecated
|