Safe Haskell | None |
---|---|
Language | Haskell2010 |
This module is dedicated to logging information in production, to help
understand what the application is doing when something goes wrong. This sets
it apart from the Debug
module which provide helpers for debugging problems
in development.
This module does not have an Elm counterpart.
Synopsis
- info :: HasCallStack => Text -> [Context] -> Task e ()
- userIsAnnoyed :: HasCallStack => Text -> Text -> [Context] -> Task e ()
- userIsConfused :: HasCallStack => Text -> Text -> [Context] -> Task e ()
- userIsPained :: HasCallStack => Text -> Text -> [Context] -> Task e ()
- userIsBlocked :: HasCallStack => Text -> Text -> [Context] -> Task e ()
- withContext :: HasCallStack => Text -> [Context] -> Task e b -> Task e b
- context :: ToJSON a => Text -> a -> Context
- data Secret a
- mkSecret :: a -> Secret a
- unSecret :: Secret a -> a
- data Context where
- newtype LogContexts = LogContexts [Context]
- data TriageInfo = TriageInfo {}
- data Impact
Logging
info :: HasCallStack => Text -> [Context] -> Task e () Source #
A log message useful for when things have gone off the rails. We should have a ton of messages at this level. It should help us out when we're dealing with something hard.
In addition to a log message you can pass additional key-value pairs with information that might be relevant for debugging.
info "I added 1 and 1" [context "answer" 2]
userIsAnnoyed :: HasCallStack => Text -> Text -> [Context] -> Task e () Source #
A log message when the user is annoyed, but not blocked.
Log.userIsAnnoyed "We poked the user unnecessarily." "Try to stop poking the user." [ Log.context "The type of poking stick" poker ]
userIsConfused :: HasCallStack => Text -> Text -> [Context] -> Task e () Source #
Like userIsAnnoyed
, but when the user is userIsConfused.
userIsPained :: HasCallStack => Text -> Text -> [Context] -> Task e () Source #
Like userIsAnnoyed
, but when the user is in pain.
userIsBlocked :: HasCallStack => Text -> Text -> [Context] -> Task e () Source #
Like userIsAnnoyed
, but when the user is blocked.
withContext :: HasCallStack => Text -> [Context] -> Task e b -> Task e b Source #
Mark a block of code as a logical unit by giving it a name. This name will be used in logs and monitoring dashboards, so use this function to help debug production problems.
In addition to a name you can pass this function a list of context. A context is a key-value pair you want to attach to all logs made inside of the block of code wrapped.
Example usage:
withContext "play-music" [context "artist" "The Beatles"] <| do -- your code here!
Additionally, this function adds an entry to our homemade stack trace for if something errors.
Why not use the built-in stack trace? Well, the built-in stack trace only records a frame if you
add Stack.HasCallStack =>
to the function, so if we want a full stack trace, we need to add
that to literally all functions. Instead of doing that, we will use withContext
to collect
the stack trace, since it is used fairly often already. It will not be complete either, but
it's the best we can do without too much trouble.
context :: ToJSON a => Text -> a -> Context Source #
A key-value pair that can be added to a log context. All log expressions within the context will always log this key-value pair.
Secrets
Distinguishes data that is secret and should not be logged.
Please be careful when defining or altering instances for this data type. There's a good chance we will leak credentials, PII, or other equally sensitive information.
Instances
Functor Secret Source # | |
Applicative Secret Source # | |
Eq a => Eq (Secret a) Source # | |
Show (Secret a) Source # | N.B. This instance of This instance exists because we sometimes use This is not a pattern to follow; it's an exception. |
ToJSON (Secret a) Source # | |
mkSecret :: a -> Secret a Source #
Wrap a value in a secret to prevent it from being accidentally logged.
Debug.log "Logging a secret" (mkSecret "My PIN is 1234") --> Logging a secret: Secret *****
unSecret :: Secret a -> a Source #
Retrieve the original value from a secret. Be very careful with this and ask yourself: is there really no way I can pass this value on as a secret further before I need to unwrap it?
The longer a value is wrapped in a Secret, the smaller the odds of it accidentally being logged.
For use in observability modules
Extra information to attach to a log message. It is passed a string key
defining what the data is and a value with a ToJSON
instance.
newtype LogContexts Source #
A set of log contexts.
Instances
ToJSON LogContexts Source # | |
Defined in Log toJSON :: LogContexts -> Value # toEncoding :: LogContexts -> Encoding # toJSONList :: [LogContexts] -> Value # toEncodingList :: [LogContexts] -> Encoding # | |
TracingSpanDetails LogContexts Source # | |
Defined in Log |
data TriageInfo Source #
A logged message for log levels warning and above. Because these levels indicate a (potential) problem we want to provide some additional data that would help a triager figure out what next steps to take.
Instances
Generic TriageInfo Source # | |
Defined in Log type Rep TriageInfo :: Type -> Type # from :: TriageInfo -> Rep TriageInfo x # to :: Rep TriageInfo x -> TriageInfo # | |
ToJSON TriageInfo Source # | |
Defined in Log toJSON :: TriageInfo -> Value # toEncoding :: TriageInfo -> Encoding # toJSONList :: [TriageInfo] -> Value # toEncodingList :: [TriageInfo] -> Encoding # | |
type Rep TriageInfo Source # | |
Defined in Log type Rep TriageInfo = D1 (MetaData "TriageInfo" "Log" "nri-prelude-0.1.0.1-6sddSkuGI59682UILeXQuc" False) (C1 (MetaCons "TriageInfo" PrefixI True) (S1 (MetaSel (Just "impact") NoSourceUnpackedness NoSourceStrictness DecidedStrict) (Rec0 Impact) :*: S1 (MetaSel (Just "advisory") NoSourceUnpackedness NoSourceStrictness DecidedStrict) (Rec0 Text))) |