{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE StandaloneDeriving #-}
module Log
(
debug,
info,
warn,
error,
withContext,
context,
Secret,
mkSecret,
unSecret,
Context (..),
LogContexts (..),
)
where
import Data.Aeson ((.=))
import qualified Data.Aeson as Aeson
import qualified GHC.Stack as Stack
import NriPrelude
import qualified Platform
import qualified Platform.Internal as Internal
import qualified Task
import qualified Text.Show
import qualified Prelude
debug :: Stack.HasCallStack => Text -> [Context] -> Task e ()
debug :: Text -> [Context] -> Task e ()
debug Text
message [Context]
contexts =
(HasCallStack => Text -> ReportStatus -> [Context] -> Task e ())
-> Text -> ReportStatus -> [Context] -> Task e ()
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack
HasCallStack => Text -> ReportStatus -> [Context] -> Task e ()
forall e.
HasCallStack =>
Text -> ReportStatus -> [Context] -> Task e ()
log
Text
message
ReportStatus
ReportAsSucceeded
(Text -> LogLevel -> Context
forall a. (Show a, ToJSON a) => Text -> a -> Context
Context Text
"level" LogLevel
Debug Context -> [Context] -> [Context]
forall a. a -> [a] -> [a]
: [Context]
contexts)
info :: Stack.HasCallStack => Text -> [Context] -> Task e ()
info :: Text -> [Context] -> Task e ()
info Text
message [Context]
contexts =
(HasCallStack => Text -> ReportStatus -> [Context] -> Task e ())
-> Text -> ReportStatus -> [Context] -> Task e ()
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack
HasCallStack => Text -> ReportStatus -> [Context] -> Task e ()
forall e.
HasCallStack =>
Text -> ReportStatus -> [Context] -> Task e ()
log
Text
message
ReportStatus
ReportAsSucceeded
(Text -> LogLevel -> Context
forall a. (Show a, ToJSON a) => Text -> a -> Context
Context Text
"level" LogLevel
Info Context -> [Context] -> [Context]
forall a. a -> [a] -> [a]
: [Context]
contexts)
warn :: Stack.HasCallStack => Text -> [Context] -> Task e ()
warn :: Text -> [Context] -> Task e ()
warn Text
message [Context]
contexts =
(HasCallStack => Text -> ReportStatus -> [Context] -> Task e ())
-> Text -> ReportStatus -> [Context] -> Task e ()
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack
HasCallStack => Text -> ReportStatus -> [Context] -> Task e ()
forall e.
HasCallStack =>
Text -> ReportStatus -> [Context] -> Task e ()
log
Text
message
ReportStatus
ReportAsFailed
(Text -> LogLevel -> Context
forall a. (Show a, ToJSON a) => Text -> a -> Context
Context Text
"level" LogLevel
Warn Context -> [Context] -> [Context]
forall a. a -> [a] -> [a]
: [Context]
contexts)
error :: Stack.HasCallStack => Text -> [Context] -> Task e ()
error :: Text -> [Context] -> Task e ()
error Text
message [Context]
contexts =
(HasCallStack => Text -> ReportStatus -> [Context] -> Task e ())
-> Text -> ReportStatus -> [Context] -> Task e ()
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack
HasCallStack => Text -> ReportStatus -> [Context] -> Task e ()
forall e.
HasCallStack =>
Text -> ReportStatus -> [Context] -> Task e ()
log
Text
message
ReportStatus
ReportAsFailed
(Text -> LogLevel -> Context
forall a. (Show a, ToJSON a) => Text -> a -> Context
Context Text
"level" LogLevel
Error Context -> [Context] -> [Context]
forall a. a -> [a] -> [a]
: [Context]
contexts)
withContext ::
Stack.HasCallStack =>
Text ->
[Context] ->
Task e b ->
Task e b
withContext :: Text -> [Context] -> Task e b -> Task e b
withContext Text
name [Context]
contexts Task e b
task =
(HasCallStack => Text -> Task e b -> Task e b)
-> Text -> Task e b -> Task e b
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack
HasCallStack => Text -> Task e b -> Task e b
forall e a. HasCallStack => Text -> Task e a -> Task e a
Internal.tracingSpan
Text
name
( Task e b -> Task e () -> Task e b
forall e a b. Task e a -> Task e b -> Task e a
Platform.finally
Task e b
task
( do
LogContexts -> Task e ()
forall d e. TracingSpanDetails d => d -> Task e ()
Platform.setTracingSpanDetails ([Context] -> LogContexts
LogContexts [Context]
contexts)
Text -> Task e ()
forall e. Text -> Task e ()
Platform.setTracingSpanSummary Text
name
)
)
context :: (Show a, Aeson.ToJSON a) => Text -> a -> Context
context :: Text -> a -> Context
context = Text -> a -> Context
forall a. (Show a, ToJSON a) => Text -> a -> Context
Context
data Context where
Context :: (Show a, Aeson.ToJSON a) => Text -> a -> Context
deriving instance Show Context
newtype LogContexts
= LogContexts [Context]
instance Aeson.ToJSON LogContexts where
toJSON :: LogContexts -> Value
toJSON (LogContexts [Context]
contexts) =
[Context]
contexts
[Context] -> ([Context] -> [Pair]) -> [Pair]
forall a b. a -> (a -> b) -> b
|> (Context -> Pair) -> [Context] -> [Pair]
forall (m :: * -> *) a value.
Functor m =>
(a -> value) -> m a -> m value
map (\(Context Text
key a
val) -> Text
key Text -> a -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= a
val)
[Pair] -> ([Pair] -> Value) -> Value
forall a b. a -> (a -> b) -> b
|> [Pair] -> Value
Aeson.object
toEncoding :: LogContexts -> Encoding
toEncoding (LogContexts [Context]
contexts) =
[Context]
contexts
[Context] -> ([Context] -> Series) -> Series
forall a b. a -> (a -> b) -> b
|> (Context -> Series) -> [Context] -> Series
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
Prelude.foldMap (\(Context Text
key a
val) -> Text
key Text -> a -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= a
val)
Series -> (Series -> Encoding) -> Encoding
forall a b. a -> (a -> b) -> b
|> Series -> Encoding
Aeson.pairs
instance Internal.TracingSpanDetails LogContexts
mkSecret :: a -> Secret a
mkSecret :: a -> Secret a
mkSecret = a -> Secret a
forall a. a -> Secret a
Secret
unSecret :: Secret a -> a
unSecret :: Secret a -> a
unSecret (Secret a
x) = a
x
newtype Secret a
= Secret a
deriving (Secret a -> Secret a -> Bool
(Secret a -> Secret a -> Bool)
-> (Secret a -> Secret a -> Bool) -> Eq (Secret a)
forall a. Eq a => Secret a -> Secret a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Secret a -> Secret a -> Bool
$c/= :: forall a. Eq a => Secret a -> Secret a -> Bool
== :: Secret a -> Secret a -> Bool
$c== :: forall a. Eq a => Secret a -> Secret a -> Bool
Prelude.Eq, a -> Secret b -> Secret a
(a -> b) -> Secret a -> Secret b
(forall a b. (a -> b) -> Secret a -> Secret b)
-> (forall a b. a -> Secret b -> Secret a) -> Functor Secret
forall a b. a -> Secret b -> Secret a
forall a b. (a -> b) -> Secret a -> Secret b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Secret b -> Secret a
$c<$ :: forall a b. a -> Secret b -> Secret a
fmap :: (a -> b) -> Secret a -> Secret b
$cfmap :: forall a b. (a -> b) -> Secret a -> Secret b
Prelude.Functor)
instance Prelude.Applicative Secret where
Secret a -> b
f <*> :: Secret (a -> b) -> Secret a -> Secret b
<*> Secret a
x = b -> Secret b
forall a. a -> Secret a
Secret (a -> b
f a
x)
pure :: a -> Secret a
pure = a -> Secret a
forall a. a -> Secret a
Secret
instance Show (Secret a) where
showsPrec :: Int -> Secret a -> ShowS
showsPrec Int
p Secret a
_ =
Bool -> ShowS -> ShowS
Text.Show.showParen (Int
p Int -> Int -> Bool
forall comparable.
Ord comparable =>
comparable -> comparable -> Bool
> Int
10) (String -> ShowS
Text.Show.showString String
"Secret \"*****\"")
instance Aeson.ToJSON (Secret a) where
toJSON :: Secret a -> Value
toJSON Secret a
_ = Text -> Value
Aeson.String Text
"Secret *****"
data LogLevel
= Debug
| Info
| Warn
| Error
deriving ((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
$cto :: forall x. Rep LogLevel x -> LogLevel
$cfrom :: forall x. LogLevel -> Rep LogLevel x
Generic, 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
showList :: [LogLevel] -> ShowS
$cshowList :: [LogLevel] -> ShowS
show :: LogLevel -> String
$cshow :: LogLevel -> String
showsPrec :: Int -> LogLevel -> ShowS
$cshowsPrec :: Int -> LogLevel -> ShowS
Show)
instance Aeson.ToJSON LogLevel
data ReportStatus = ReportAsFailed | ReportAsSucceeded
log :: Stack.HasCallStack => Text -> ReportStatus -> [Context] -> Task e ()
log :: Text -> ReportStatus -> [Context] -> Task e ()
log Text
msg ReportStatus
reportStatus [Context]
contexts =
Text -> Task e () -> Task e ()
forall e a. HasCallStack => Text -> Task e a -> Task e a
Internal.tracingSpan Text
msg (Task e () -> Task e ()) -> Task e () -> Task e ()
forall a b. (a -> b) -> a -> b
<| do
LogContexts -> Task e ()
forall d e. TracingSpanDetails d => d -> Task e ()
Platform.setTracingSpanDetails ([Context] -> LogContexts
LogContexts [Context]
contexts)
case ReportStatus
reportStatus of
ReportStatus
ReportAsSucceeded -> () -> Task e ()
forall a x. a -> Task x a
Task.succeed ()
ReportStatus
ReportAsFailed -> Task e ()
forall e. Task e ()
Platform.markTracingSpanFailed