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
- debug :: HasCallStack => Text -> [Context] -> Task e ()
- info :: HasCallStack => Text -> [Context] -> Task e ()
- warn :: HasCallStack => Text -> [Context] -> Task e ()
- error :: HasCallStack => Text -> [Context] -> Task e ()
- withContext :: HasCallStack => Text -> [Context] -> Task e b -> Task e b
- context :: (Show a, ToJSON a) => Text -> a -> Context
- data Secret a
- mkSecret :: a -> Secret a
- unSecret :: Secret a -> a
- data Context where
- newtype LogContexts = LogContexts [Context]
Logging
debug :: HasCallStack => Text -> [Context] -> Task e () Source #
A log message that is probably only useful in development, or when we're really confused about something and need ALL THE CONTEXT.
In addition to a log message you can pass additional key-value pairs with information that might be relevant for debugging.
debug "Computation partially succeeded" [context "answer" 2]
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]
warn :: HasCallStack => Text -> [Context] -> Task e () Source #
A log message when something went wrong, but it did not go wrong in a way to totally break the thing we're doing. These should be triaged and fixed soon, but aren't show-stoppers.
In addition to a log message you can pass additional key-value pairs with information that might be relevant for debugging.
warn "This field was sent, but we're gonna deprecate it!" []
error :: HasCallStack => Text -> [Context] -> Task e () Source #
A log message when we can't continue with what we were trying to do because of a problem.
In addition to a log message you can pass additional key-value pairs with information that might be relevant for debugging.
error "The user tried to request this thing, but they aren't allowed!" []
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 :: (Show a, 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 |