module Ecluse.Runtime.Log.Internal (
LogFormat (..),
parseLogFormat,
LogLevel (..),
parseLogLevel,
severityFloor,
severityStatus,
newLogEnv,
newScribe,
formatterFor,
moduleField,
moduleContext,
logLine,
moduleLog,
DdContext (..),
DdSpan (..),
ddField,
ddObject,
) where
import Data.Aeson (Value (Object, String), object, toJSON, (.=))
import Data.Aeson.Key (Key)
import Data.Aeson.KeyMap qualified as KeyMap
import Data.Aeson.Text (encodeToLazyText)
import Data.Text.Lazy.Builder qualified as TB
import Data.Universe.Class (Universe (..))
import Data.Universe.Generic (universeGeneric)
import Katip (
ColorStrategy (ColorLog),
Environment,
Item (..),
LogEnv,
LogItem,
Namespace (Namespace),
Scribe,
Severity (AlertS, CriticalS, DebugS, EmergencyS, ErrorS, InfoS, NoticeS, WarningS),
SimpleLogPayload,
Verbosity (V2),
defaultScribeSettings,
initLogEnv,
itemJson,
logFM,
ls,
permitItem,
registerScribe,
sl,
unLogStr,
)
import Katip.Monadic (KatipContextT, runKatipContextT)
import Katip.Scribes.Handle (ItemFormatter, bracketFormat, mkHandleScribeWithFormatter)
import Ecluse.Core.Wire (WireVocab (..), parseWire)
data LogFormat
=
JsonLog
|
ConsoleLog
deriving stock (LogFormat -> LogFormat -> Bool
(LogFormat -> LogFormat -> Bool)
-> (LogFormat -> LogFormat -> Bool) -> Eq LogFormat
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: LogFormat -> LogFormat -> Bool
== :: LogFormat -> LogFormat -> Bool
$c/= :: LogFormat -> LogFormat -> Bool
/= :: LogFormat -> LogFormat -> Bool
Eq, (forall x. LogFormat -> Rep LogFormat x)
-> (forall x. Rep LogFormat x -> LogFormat) -> Generic LogFormat
forall x. Rep LogFormat x -> LogFormat
forall x. LogFormat -> Rep LogFormat x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. LogFormat -> Rep LogFormat x
from :: forall x. LogFormat -> Rep LogFormat x
$cto :: forall x. Rep LogFormat x -> LogFormat
to :: forall x. Rep LogFormat x -> LogFormat
Generic, Int -> LogFormat -> ShowS
[LogFormat] -> ShowS
LogFormat -> String
(Int -> LogFormat -> ShowS)
-> (LogFormat -> String)
-> ([LogFormat] -> ShowS)
-> Show LogFormat
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LogFormat -> ShowS
showsPrec :: Int -> LogFormat -> ShowS
$cshow :: LogFormat -> String
show :: LogFormat -> String
$cshowList :: [LogFormat] -> ShowS
showList :: [LogFormat] -> ShowS
Show)
instance Universe LogFormat where universe :: [LogFormat]
universe = [LogFormat]
forall a. (Generic a, GUniverse (Rep a)) => [a]
universeGeneric
instance WireVocab LogFormat where
wireKind :: Text
wireKind = Text
"log format"
wireTable :: NonEmpty (LogFormat, Text)
wireTable =
(LogFormat
JsonLog, Text
"json")
(LogFormat, Text)
-> [(LogFormat, Text)] -> NonEmpty (LogFormat, Text)
forall a. a -> [a] -> NonEmpty a
:| [(LogFormat
ConsoleLog, Text
"console")]
parseLogFormat :: Text -> Either Text LogFormat
parseLogFormat :: Text -> Either Text LogFormat
parseLogFormat = Text -> Either Text LogFormat
forall a. WireVocab a => Text -> Either Text a
parseWire
data LogLevel
=
DebugLevel
|
InfoLevel
|
WarnLevel
|
ErrorLevel
deriving stock (LogLevel -> LogLevel -> Bool
(LogLevel -> LogLevel -> Bool)
-> (LogLevel -> LogLevel -> Bool) -> Eq LogLevel
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: LogLevel -> LogLevel -> Bool
== :: LogLevel -> LogLevel -> Bool
$c/= :: LogLevel -> LogLevel -> Bool
/= :: LogLevel -> LogLevel -> Bool
Eq, (forall x. LogLevel -> Rep LogLevel x)
-> (forall x. Rep LogLevel x -> LogLevel) -> Generic LogLevel
forall x. Rep LogLevel x -> LogLevel
forall x. LogLevel -> Rep LogLevel x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. LogLevel -> Rep LogLevel x
from :: forall x. LogLevel -> Rep LogLevel x
$cto :: forall x. Rep LogLevel x -> LogLevel
to :: forall x. Rep LogLevel x -> LogLevel
Generic, Eq LogLevel
Eq LogLevel =>
(LogLevel -> LogLevel -> Ordering)
-> (LogLevel -> LogLevel -> Bool)
-> (LogLevel -> LogLevel -> Bool)
-> (LogLevel -> LogLevel -> Bool)
-> (LogLevel -> LogLevel -> Bool)
-> (LogLevel -> LogLevel -> LogLevel)
-> (LogLevel -> LogLevel -> LogLevel)
-> Ord LogLevel
LogLevel -> LogLevel -> Bool
LogLevel -> LogLevel -> Ordering
LogLevel -> LogLevel -> LogLevel
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: LogLevel -> LogLevel -> Ordering
compare :: LogLevel -> LogLevel -> Ordering
$c< :: LogLevel -> LogLevel -> Bool
< :: LogLevel -> LogLevel -> Bool
$c<= :: LogLevel -> LogLevel -> Bool
<= :: LogLevel -> LogLevel -> Bool
$c> :: LogLevel -> LogLevel -> Bool
> :: LogLevel -> LogLevel -> Bool
$c>= :: LogLevel -> LogLevel -> Bool
>= :: LogLevel -> LogLevel -> Bool
$cmax :: LogLevel -> LogLevel -> LogLevel
max :: LogLevel -> LogLevel -> LogLevel
$cmin :: LogLevel -> LogLevel -> LogLevel
min :: LogLevel -> LogLevel -> LogLevel
Ord, Int -> LogLevel -> ShowS
[LogLevel] -> ShowS
LogLevel -> String
(Int -> LogLevel -> ShowS)
-> (LogLevel -> String) -> ([LogLevel] -> ShowS) -> Show LogLevel
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LogLevel -> ShowS
showsPrec :: Int -> LogLevel -> ShowS
$cshow :: LogLevel -> String
show :: LogLevel -> String
$cshowList :: [LogLevel] -> ShowS
showList :: [LogLevel] -> ShowS
Show)
instance Universe LogLevel where universe :: [LogLevel]
universe = [LogLevel]
forall a. (Generic a, GUniverse (Rep a)) => [a]
universeGeneric
instance WireVocab LogLevel where
wireKind :: Text
wireKind = Text
"log level"
wireTable :: NonEmpty (LogLevel, Text)
wireTable =
(LogLevel
DebugLevel, Text
"debug")
(LogLevel, Text) -> [(LogLevel, Text)] -> NonEmpty (LogLevel, Text)
forall a. a -> [a] -> NonEmpty a
:| [ (LogLevel
InfoLevel, Text
"info")
, (LogLevel
WarnLevel, Text
"warn")
, (LogLevel
ErrorLevel, Text
"error")
]
parseLogLevel :: Text -> Either Text LogLevel
parseLogLevel :: Text -> Either Text LogLevel
parseLogLevel = Text -> Either Text LogLevel
forall a. WireVocab a => Text -> Either Text a
parseWire
severityFloor :: LogLevel -> Severity
severityFloor :: LogLevel -> Severity
severityFloor = \case
LogLevel
DebugLevel -> Severity
DebugS
LogLevel
InfoLevel -> Severity
InfoS
LogLevel
WarnLevel -> Severity
WarningS
LogLevel
ErrorLevel -> Severity
ErrorS
severityStatus :: Severity -> Text
severityStatus :: Severity -> Text
severityStatus = \case
Severity
DebugS -> Text
"debug"
Severity
InfoS -> Text
"info"
Severity
NoticeS -> Text
"info"
Severity
WarningS -> Text
"warn"
Severity
ErrorS -> Text
"error"
Severity
CriticalS -> Text
"error"
Severity
AlertS -> Text
"error"
Severity
EmergencyS -> Text
"error"
newLogEnv :: LogFormat -> LogLevel -> DdContext -> Environment -> IO LogEnv
newLogEnv :: LogFormat -> LogLevel -> DdContext -> Environment -> IO LogEnv
newLogEnv LogFormat
format LogLevel
level DdContext
logIdentity Environment
environment = do
scribe <- LogFormat -> LogLevel -> DdContext -> IO Scribe
newScribe LogFormat
format LogLevel
level DdContext
logIdentity
base <- initLogEnv (Namespace ["ecluse"]) environment
registerScribe "stdout" scribe defaultScribeSettings base
newScribe :: LogFormat -> LogLevel -> DdContext -> IO Scribe
newScribe :: LogFormat -> LogLevel -> DdContext -> IO Scribe
newScribe LogFormat
format LogLevel
level DdContext
logIdentity =
(forall a. LogItem a => ItemFormatter a)
-> ColorStrategy -> Handle -> PermitFunc -> Verbosity -> IO Scribe
mkHandleScribeWithFormatter
(LogFormat -> DdContext -> ItemFormatter a
forall a. LogItem a => LogFormat -> DdContext -> ItemFormatter a
formatterFor LogFormat
format DdContext
logIdentity)
(Bool -> ColorStrategy
ColorLog Bool
False)
Handle
stdout
(Severity -> Item a -> IO Bool
forall (m :: * -> *) a. Monad m => Severity -> Item a -> m Bool
permitItem (LogLevel -> Severity
severityFloor LogLevel
level))
Verbosity
V2
formatterFor :: (LogItem a) => LogFormat -> DdContext -> ItemFormatter a
formatterFor :: forall a. LogItem a => LogFormat -> DdContext -> ItemFormatter a
formatterFor LogFormat
format DdContext
logIdentity = case LogFormat
format of
LogFormat
JsonLog -> DdContext -> ItemFormatter a
forall a. LogItem a => DdContext -> ItemFormatter a
jsonLineFormat DdContext
logIdentity
LogFormat
ConsoleLog -> ItemFormatter a
forall a. LogItem a => ItemFormatter a
bracketFormat
jsonLineFormat :: (LogItem a) => DdContext -> ItemFormatter a
jsonLineFormat :: forall a. LogItem a => DdContext -> ItemFormatter a
jsonLineFormat DdContext
logIdentity Bool
_colourise Verbosity
verb Item a
logItem =
Text -> Builder
TB.fromLazyText (Value -> Text
forall a. ToJSON a => a -> Text
encodeToLazyText (DdContext -> Verbosity -> Item a -> Value
forall a. LogItem a => DdContext -> Verbosity -> Item a -> Value
jsonLine DdContext
logIdentity Verbosity
verb Item a
logItem))
jsonLine :: (LogItem a) => DdContext -> Verbosity -> Item a -> Value
jsonLine :: forall a. LogItem a => DdContext -> Verbosity -> Item a -> Value
jsonLine DdContext
logIdentity Verbosity
verb Item a
logItem =
Object -> Value
Object ([Pair] -> Object
forall v. [(Key, v)] -> KeyMap v
KeyMap.fromList (DdContext -> Item a -> Object -> Object -> [Pair]
forall a. DdContext -> Item a -> Object -> Object -> [Pair]
reservedFields DdContext
context Item a
logItem Object
structured Object
katipObject [Pair] -> [Pair] -> [Pair]
forall a. Semigroup a => a -> a -> a
<> DdContext -> [Pair]
whenPresent DdContext
context))
where
katipObject :: KeyMap.KeyMap Value
katipObject :: Object
katipObject = case Verbosity -> Item a -> Value
forall a. LogItem a => Verbosity -> Item a -> Value
itemJson Verbosity
verb Item a
logItem of
Object Object
o -> Object
o
Value
_ -> Object
forall v. KeyMap v
KeyMap.empty
structured :: KeyMap.KeyMap Value
structured :: Object
structured = case Key -> Object -> Maybe Value
forall v. Key -> KeyMap v -> Maybe v
KeyMap.lookup Key
"data" Object
katipObject of
Just (Object Object
o) -> Object
o
Maybe Value
_ -> Object
forall v. KeyMap v
KeyMap.empty
context :: DdContext
context :: DdContext
context = DdContext
logIdentity{ddSpan = payloadSpan structured <|> ddSpan logIdentity}
reservedFields :: DdContext -> Item a -> KeyMap.KeyMap Value -> KeyMap.KeyMap Value -> [(Key, Value)]
reservedFields :: forall a. DdContext -> Item a -> Object -> Object -> [Pair]
reservedFields DdContext
context Item a
logItem Object
structured Object
katipObject =
[ (Key
"timestamp", UTCTime -> Value
forall a. ToJSON a => a -> Value
toJSON (Item a -> UTCTime
forall a. Item a -> UTCTime
_itemTime Item a
logItem))
, (Key
"status", Text -> Value
forall a. ToJSON a => a -> Value
toJSON (Severity -> Text
severityStatus (Item a -> Severity
forall a. Item a -> Severity
_itemSeverity Item a
logItem)))
, (Key
"message", Text -> Value
forall a. ToJSON a => a -> Value
toJSON (Builder -> Text
TB.toLazyText (LogStr -> Builder
unLogStr (Item a -> LogStr
forall a. Item a -> LogStr
_itemMessage Item a
logItem))))
, (Key
"service", Text -> Value
forall a. ToJSON a => a -> Value
toJSON (DdContext -> Text
ddService DdContext
context))
, (Key
"env", Value -> (Text -> Value) -> Maybe Text -> Value
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Environment -> Value
forall a. ToJSON a => a -> Value
toJSON (Item a -> Environment
forall a. Item a -> Environment
_itemEnv Item a
logItem)) Text -> Value
forall a. ToJSON a => a -> Value
toJSON (DdContext -> Maybe Text
ddEnv DdContext
context))
, (Key
"data", Object -> Value
Object (Key -> Object -> Object
forall v. Key -> KeyMap v -> KeyMap v
KeyMap.delete Key
"dd" Object
structured))
, (Key
"katip", Object -> Value
Object ((Key -> Value -> Bool) -> Object -> Object
forall v. (Key -> v -> Bool) -> KeyMap v -> KeyMap v
KeyMap.filterWithKey (\Key
key Value
_ -> Key
key Key -> [Key] -> Bool
forall (f :: * -> *) a.
(Foldable f, DisallowElem f, Eq a) =>
a -> f a -> Bool
`notElem` [Key]
promoted) Object
katipObject))
]
whenPresent :: DdContext -> [(Key, Value)]
whenPresent :: DdContext -> [Pair]
whenPresent DdContext
context =
[Maybe Pair] -> [Pair]
forall a. [Maybe a] -> [a]
catMaybes
[ (Key
"version",) (Value -> Pair) -> (Text -> Value) -> Text -> Pair
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Value
forall a. ToJSON a => a -> Value
toJSON (Text -> Pair) -> Maybe Text -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DdContext -> Maybe Text
ddVersion DdContext
context
, (Key
"dd",) (Value -> Pair) -> (DdSpan -> Value) -> DdSpan -> Pair
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DdSpan -> Value
spanObject (DdSpan -> Pair) -> Maybe DdSpan -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DdContext -> Maybe DdSpan
ddSpan DdContext
context
]
promoted :: [Key]
promoted :: [Key]
promoted = [Key
"at", Key
"data", Key
"env", Key
"msg", Key
"sev"]
spanObject :: DdSpan -> Value
spanObject :: DdSpan -> Value
spanObject DdSpan
theSpan = [Pair] -> Value
object [Key
"trace_id" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= DdSpan -> Text
ddTraceId DdSpan
theSpan, Key
"span_id" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= DdSpan -> Text
ddSpanId DdSpan
theSpan]
payloadSpan :: KeyMap.KeyMap Value -> Maybe DdSpan
payloadSpan :: Object -> Maybe DdSpan
payloadSpan Object
structured = case Key -> Object -> Maybe Value
forall v. Key -> KeyMap v -> Maybe v
KeyMap.lookup Key
"dd" Object
structured of
Just (Object Object
dd) -> Text -> Text -> DdSpan
DdSpan (Text -> Text -> DdSpan) -> Maybe Text -> Maybe (Text -> DdSpan)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Key -> Object -> Maybe Text
textAt Key
"trace_id" Object
dd Maybe (Text -> DdSpan) -> Maybe Text -> Maybe DdSpan
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Key -> Object -> Maybe Text
textAt Key
"span_id" Object
dd
Maybe Value
_ -> Maybe DdSpan
forall a. Maybe a
Nothing
where
textAt :: Key -> KeyMap.KeyMap Value -> Maybe Text
textAt :: Key -> Object -> Maybe Text
textAt Key
key Object
o = case Key -> Object -> Maybe Value
forall v. Key -> KeyMap v -> Maybe v
KeyMap.lookup Key
key Object
o of
Just (String Text
t) -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
t
Maybe Value
_ -> Maybe Text
forall a. Maybe a
Nothing
moduleField :: Text -> SimpleLogPayload
moduleField :: Text -> SimpleLogPayload
moduleField = Text -> Text -> SimpleLogPayload
forall a. ToJSON a => Text -> a -> SimpleLogPayload
sl Text
"module"
moduleContext :: LogEnv -> Text -> KatipContextT m a -> m a
moduleContext :: forall (m :: * -> *) a. LogEnv -> Text -> KatipContextT m a -> m a
moduleContext LogEnv
logEnv Text
name = LogEnv -> SimpleLogPayload -> Namespace -> KatipContextT m a -> m a
forall c (m :: * -> *) a.
LogItem c =>
LogEnv -> c -> Namespace -> KatipContextT m a -> m a
runKatipContextT LogEnv
logEnv (Text -> SimpleLogPayload
moduleField Text
name) Namespace
forall a. Monoid a => a
mempty
logLine :: LogEnv -> SimpleLogPayload -> Severity -> Text -> IO ()
logLine :: LogEnv -> SimpleLogPayload -> Severity -> Text -> IO ()
logLine LogEnv
logEnv SimpleLogPayload
payload Severity
severity Text
message =
LogEnv
-> SimpleLogPayload -> Namespace -> KatipContextT IO () -> IO ()
forall c (m :: * -> *) a.
LogItem c =>
LogEnv -> c -> Namespace -> KatipContextT m a -> m a
runKatipContextT LogEnv
logEnv SimpleLogPayload
payload Namespace
forall a. Monoid a => a
mempty (Severity -> LogStr -> KatipContextT IO ()
forall (m :: * -> *).
(Applicative m, KatipContext m) =>
Severity -> LogStr -> m ()
logFM Severity
severity (Text -> LogStr
forall a. StringConv a Text => a -> LogStr
ls Text
message))
moduleLog :: LogEnv -> Text -> Severity -> Text -> IO ()
moduleLog :: LogEnv -> Text -> Severity -> Text -> IO ()
moduleLog LogEnv
logEnv Text
name Severity
severity Text
message = LogEnv -> Text -> KatipContextT IO () -> IO ()
forall (m :: * -> *) a. LogEnv -> Text -> KatipContextT m a -> m a
moduleContext LogEnv
logEnv Text
name (Severity -> LogStr -> KatipContextT IO ()
forall (m :: * -> *).
(Applicative m, KatipContext m) =>
Severity -> LogStr -> m ()
logFM Severity
severity (Text -> LogStr
forall a. StringConv a Text => a -> LogStr
ls Text
message))
data DdContext = DdContext
{ DdContext -> Text
ddService :: Text
, DdContext -> Maybe Text
ddEnv :: Maybe Text
, DdContext -> Maybe Text
ddVersion :: Maybe Text
, DdContext -> Maybe DdSpan
ddSpan :: Maybe DdSpan
}
deriving stock (DdContext -> DdContext -> Bool
(DdContext -> DdContext -> Bool)
-> (DdContext -> DdContext -> Bool) -> Eq DdContext
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DdContext -> DdContext -> Bool
== :: DdContext -> DdContext -> Bool
$c/= :: DdContext -> DdContext -> Bool
/= :: DdContext -> DdContext -> Bool
Eq, Int -> DdContext -> ShowS
[DdContext] -> ShowS
DdContext -> String
(Int -> DdContext -> ShowS)
-> (DdContext -> String)
-> ([DdContext] -> ShowS)
-> Show DdContext
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DdContext -> ShowS
showsPrec :: Int -> DdContext -> ShowS
$cshow :: DdContext -> String
show :: DdContext -> String
$cshowList :: [DdContext] -> ShowS
showList :: [DdContext] -> ShowS
Show)
data DdSpan = DdSpan
{ DdSpan -> Text
ddTraceId :: Text
, DdSpan -> Text
ddSpanId :: Text
}
deriving stock (DdSpan -> DdSpan -> Bool
(DdSpan -> DdSpan -> Bool)
-> (DdSpan -> DdSpan -> Bool) -> Eq DdSpan
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DdSpan -> DdSpan -> Bool
== :: DdSpan -> DdSpan -> Bool
$c/= :: DdSpan -> DdSpan -> Bool
/= :: DdSpan -> DdSpan -> Bool
Eq, Int -> DdSpan -> ShowS
[DdSpan] -> ShowS
DdSpan -> String
(Int -> DdSpan -> ShowS)
-> (DdSpan -> String) -> ([DdSpan] -> ShowS) -> Show DdSpan
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DdSpan -> ShowS
showsPrec :: Int -> DdSpan -> ShowS
$cshow :: DdSpan -> String
show :: DdSpan -> String
$cshowList :: [DdSpan] -> ShowS
showList :: [DdSpan] -> ShowS
Show)
ddObject :: DdContext -> Value
ddObject :: DdContext -> Value
ddObject DdContext
ctx =
[Pair] -> Value
object ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$
[Maybe Pair] -> [Pair]
forall a. [Maybe a] -> [a]
catMaybes
[ Pair -> Maybe Pair
forall a. a -> Maybe a
Just (Key
"service" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= DdContext -> Text
ddService DdContext
ctx)
, (Key
"env" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Text -> Pair) -> Maybe Text -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DdContext -> Maybe Text
ddEnv DdContext
ctx
, (Key
"version" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Text -> Pair) -> Maybe Text -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DdContext -> Maybe Text
ddVersion DdContext
ctx
, (Key
"trace_id" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Text -> Pair) -> (DdSpan -> Text) -> DdSpan -> Pair
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DdSpan -> Text
ddTraceId (DdSpan -> Pair) -> Maybe DdSpan -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DdContext -> Maybe DdSpan
ddSpan DdContext
ctx
, (Key
"span_id" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Text -> Pair) -> (DdSpan -> Text) -> DdSpan -> Pair
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DdSpan -> Text
ddSpanId (DdSpan -> Pair) -> Maybe DdSpan -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DdContext -> Maybe DdSpan
ddSpan DdContext
ctx
]
ddField :: DdContext -> SimpleLogPayload
ddField :: DdContext -> SimpleLogPayload
ddField = Text -> Value -> SimpleLogPayload
forall a. ToJSON a => Text -> a -> SimpleLogPayload
sl Text
"dd" (Value -> SimpleLogPayload)
-> (DdContext -> Value) -> DdContext -> SimpleLogPayload
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DdContext -> Value
ddObject