@@ -26,9 +26,7 @@ module Katip
2626 (
2727
2828 -- * Framework Types
29−
30− Katip (..)
31− , Namespace (..)
29+ Namespace (..)
3230 , Environment (..)
3331 , Severity (..)
3432 , renderSeverity
@@ -41,9 +39,6 @@ module Katip
4139 , PayloadSelection (..)
4240 , Scribe (..)
4341 , LogEnv (..)
44− , KatipContext(..)
45− , AnyLogContext
46− , LogContexts, liftPayload
4742 , SimpleLogPayload, sl
4843
4944 -- ** @lens@-compatible Lenses
@@ -60,7 +55,7 @@ module Katip
6055 , itemLoc
6156 , logEnvHost
6257 , logEnvPid
63− , logEnvNs
58+ , logEnvApp
6459 , logEnvEnv
6560 , logEnvTimer
6661 , logEnvScribes
@@ -79,15 +74,23 @@ module Katip
7974 , LogStr (..)
8075 , logStr, ls, showLS
8176
77+ -- ** 'Katip' LoggingFunctions
78+ -- $katiplogging
79+ , Katip (..)
8280 , logF
8381 , logMsg
8482 , logT
8583 , logItem
8684 , logException
85+ -- ** 'KatipContext' Logging Functions
86+ -- $katipcontextlogging
87+ , KatipContext (..)
8788 , logFM
8889 , logTM
8990 , logItemM
9091 , logExceptionM
92+ , AnyLogContext
93+ , LogContexts, liftPayload
9194
9295 -- * Included Scribes
9396 , mkHandleScribe
@@ -101,6 +104,8 @@ module Katip
101104 -- * KatipContextT - Utility transformer that provides Katip and KatipContext instances
102105 , KatipContextT
103106 , runKatipContextT
107+ , katipAddNamespace
108+ , katipAddContext
104109 ) where
105110
106111-------------------------------------------------------------------------------
@@ -108,3 +113,91 @@ import Katip.Core
108113import Katip.Monadic
109114import Katip.Scribes.Handle
110115-------------------------------------------------------------------------------
116+
117+
118+{- $katiplogging
119+
120+ These logging functions use the basic 'Katip' constraint and thus
121+will require varying degrees of explicit detail such as 'Namespace'
122+and individual log items to be passed in. These can be described as
123+the primitives of Katip logging. If you find yourself making multiple
124+log statements within a logical logging context for your app, you may
125+want to look into the 'KatipContext' family of logging functions like
126+'logFM' and 'logTM'. 'KatipContext' in most applications should be
127+considered the default. Here's an example of the pain point:
128+
129+@
130+doDatabaseThings = do
131+ connId <- getConnectionId
132+ logF (ConnectionIDContext connId) "database" InfoS "Doing database stuff"
133+ \-\- ...
134+ logF (ConnectionIDContext connId) "database" InfoS "Wow, passing in the same context is getting tedious"
135+@
136+
137+Another pain point to look out for is nesting actions that log in
138+eachother. Let's say you were writing a web app. You want to capture
139+some detail such as the user's ID in the logs, but you also want that
140+info to show up in doDatabaseThings' logs so you can associate those
141+two pieces of information:
142+
143+
144+@
145+webRequestHandler = do
146+ uid <- getUserId
147+ logF (UserIDContext uid) "web" InfoS "Starting web request"
148+ doDatabaseThings
149+@
150+
151+In the above example, doDatabaseThings would overwrite that
152+UderIDContext with its own context and namespace. Sometimes this is
153+what you want and that's why 'logF' and other functions which only
154+require 'Katip' exist. If you are interested in combining log
155+contexts and namespaces, see 'KatipContext'.
156+-}
157+
158+
159+{- $katipcontextlogging
160+
161+ These logging functions use the 'KatipContext' constraint which is a
162+superclass of 'Katip' that also has a mechanism for keeping track of
163+the current context and namespace. This means a few things:
164+
165+1. Functions that use 'KatipContext' like 'logFM' and 'logTM' do not
166+require you to pass in 'LogItem's or 'Namespaces', they pull them from
167+the monadic environment.
168+
169+2. It becomes easy to add functions which add namespaces and/or
170+contexts to the current stack of them. You can (and should) make that
171+action scoped to a monadic action so that when it finishes, the
172+previous context and namespace will be automatically restored.
173+
174+
175+'KatipContextT' provides a simple, 'ReaderT'-based implementation of
176+the 'KatipContext' typeclass, and provides 'katipAddContext' and
177+'katipAddNamespace' functions to append to the context for the
178+duration of a block:
179+
180+
181+@
182+main = do
183+ le <- initLogEnv "MyApp" "production"
184+ \-\- set up scribes here
185+ runKatipContext le () "main" $ do
186+ katipAddNamespace "nextlevel" $ do
187+ $(logTM) InfoS "Logs here will have namespace MyApp.main.nextlevel"
188+
189+ katipAddContext TrivialContext $ do
190+ $(logTM) InfoS "Logs here will have context from TrivialContext"
191+
192+ katipAddContext AnotherContext $ do
193+ $(logTM) InfoS "Logs here will have context from TrivialContext *merged with* context from AnotherContext!"
194+
195+ $(logTM) InfoS "Log context restored to () and namespace to MyApp.main"
196+@
197+
198+'katipAddNamespace' and 'katipAddContext' are one-liners, implemented
199+in terms of 'local' from 'MonadReader'. If you have a custom monad
200+transformer stack and want to add your own version of these, check out
201+<https://github.com/Soostone/katip/tree/master/katip/examples these
202+examples>.
203+-}