on master help sign in
More fine touches for release
b6e415eMichael Xavier
katip/examples/example.hs+17−1
@@ -12,6 +12,7 @@ module Main
12import Control.Monad.Reader
12import Control.Monad.Reader
13import Data.Aeson
13import Data.Aeson
14import Data.Monoid as M
14import Data.Monoid as M
15+import System.IO (stdout)
15-------------------------------------------------------------------------------
16-------------------------------------------------------------------------------
16import Katip
17import Katip
17-------------------------------------------------------------------------------
18-------------------------------------------------------------------------------
@@ -21,9 +22,24 @@ import Katip
21-- lens_example for a slightly cleaner and more general pattern.
22-- lens_example for a slightly cleaner and more general pattern.
22main :: IO ()
23main :: IO ()
23main = do
24main = do
25+ le <- initLogEnv "main" "production"
26+ -- We'll set up a scribe that logs to stdout and will only log item
27+ -- fields permitted for Verbosity 2 and will throw out Debug
28+ -- messages entirely. Note that katip provides facilities like
29+ -- 'unregisterScribe' and 'registerScribe' to make it possible to
30+ -- hot-swap scribes at runtime if you need to.
31+ handleScribe <- mkHandleScribe ColorIfTerminal stdout InfoS V2
32+ let le' = registerScribe "stdout" handleScribe le
24− s <- MyState M.mempty mempty <$> initLogEnv mempty (Environment "production")
33+ let s = MyState M.mempty mempty le'
25 runStack s $ do
34 runStack s $ do
26 $(logTM) InfoS "Started"
35 $(logTM) InfoS "Started"
36+ -- this will add "confrabulation" to the current namespace, making
37+ -- logs made under this block have the namespace of
38+ -- "main.confrabulation". Further, ConfrabLogCTX's key/value
39+ -- context will also get merged with the context above it. You can
40+ -- use this to stack up various contextual details throughout your
41+ -- code and they will be flattened out and combined in the log
42+ -- output.
27 addNamespace "confrabulation" $ addContext (ConfrabLogCTX 42) $ do
43 addNamespace "confrabulation" $ addContext (ConfrabLogCTX 42) $ do
28 $(logTM) DebugS "Confrabulating widgets, with extra namespace and context"
44 $(logTM) DebugS "Confrabulating widgets, with extra namespace and context"
29 confrabulateWidgets
45 confrabulateWidgets
katip/examples/example_lens.hs+17−1
@@ -13,6 +13,7 @@ import Control.Lens hiding ((.=))
13import Control.Monad.Reader
13import Control.Monad.Reader
14import Data.Aeson
14import Data.Aeson
15import Data.Monoid as M
15import Data.Monoid as M
16+import System.IO (stdout)
16-------------------------------------------------------------------------------
17-------------------------------------------------------------------------------
17import Katip
18import Katip
18-------------------------------------------------------------------------------
19-------------------------------------------------------------------------------
@@ -37,9 +38,24 @@ makeClassy ''MyState
37-- lens_example for a slightly cleaner and more general pattern.
38-- lens_example for a slightly cleaner and more general pattern.
38main :: IO ()
39main :: IO ()
39main = do
40main = do
41+ le <- initLogEnv "main" "production"
42+ -- We'll set up a scribe that logs to stdout and will only log item
43+ -- fields permitted for Verbosity 2 and will throw out Debug
44+ -- messages entirely. Note that katip provides facilities like
45+ -- 'unregisterScribe' and 'registerScribe' to make it possible to
46+ -- hot-swap scribes at runtime if you need to.
47+ handleScribe <- mkHandleScribe ColorIfTerminal stdout InfoS V2
48+ let le' = registerScribe "stdout" handleScribe le
40− s <- MyState M.mempty mempty <$> initLogEnv mempty (Environment "production")
49+ let s = MyState M.mempty mempty le'
41 runStack s $ do
50 runStack s $ do
42 $(logTM) InfoS "Started"
51 $(logTM) InfoS "Started"
52+ -- this will add "confrabulation" to the current namespace, making
53+ -- logs made under this block have the namespace of
54+ -- "main.confrabulation". Further, ConfrabLogCTX's key/value
55+ -- context will also get merged with the context above it. You can
56+ -- use this to stack up various contextual details throughout your
57+ -- code and they will be flattened out and combined in the log
58+ -- output.
43 addNamespace "confrabulation" $ addContext (ConfrabLogCTX 42) $ do
59 addNamespace "confrabulation" $ addContext (ConfrabLogCTX 42) $ do
44 $(logTM) DebugS "Confrabulating widgets, with extra namespace and context"
60 $(logTM) DebugS "Confrabulating widgets, with extra namespace and context"
45 confrabulateWidgets
61 confrabulateWidgets
katip/katip.cabal+3−1
@@ -21,7 +21,9 @@ description:
21 * Designed to be highly configurable. Can be adjusted both with
21 * Designed to be highly configurable. Can be adjusted both with
22 verbosity, which dictates how much of the log structure should
22 verbosity, which dictates how much of the log structure should
23 actually get logged, and severity. Each individual scribe can be
23 actually get logged, and severity. Each individual scribe can be
24− configured to a different log severity.
24+ configured to a different log severity. It is even possible to at
25+ runtime swap out and replace loggers, allowing for swapping in
26+ verbose debug logging at runtime if you want.
25
27
26 A note on the name: Katip is Turkish for scribe.
28 A note on the name: Katip is Turkish for scribe.
27
29
katip/src/Katip.hs+20
@@ -1,3 +1,23 @@
1+-- | Includes all of the API's youll need to use Katip. Be sure to
2+-- check out the included @examples@ directory for an example of
3+-- usage.
4+--
5+-- To get up and running, the workflow is generally:
6+--
7+-- * Set up a 'LogEnv' using 'initLogEnv'.
8+--
9+-- * Add 'Scribe's using 'registerScribe'.
10+--
11+-- * Either use 'KatipT' or 'KatipContextT' for a pre-built
12+-- transformer stack or add 'Katip' and 'KatipContext' instances to
13+-- your own transformer stack. If you do the latter, you may want to
14+-- look in the @examples@ dir for some tips on composing contexts and
15+-- namespaces.
16+--
17+-- * Define some structured log data throughout your application and
18+-- implement 'ToObject' and 'LogItem' for them.
19+--
20+-- * Begin logging with 'logT', 'logTM', etc.
1module Katip
21module Katip
2 (
22 (
3
23
katip/src/Katip/Core.hs+17−2
@@ -53,6 +53,11 @@ import System.Posix
53
53
54
54
55-------------------------------------------------------------------------------
55-------------------------------------------------------------------------------
56+-- | Represents a heirarchy of namespaces going from general to
57+-- specific. For instance: ["processname", "subsystem"]. Note that
58+-- single-segment namespaces can be created using
59+-- IsString/OverloadedStrings, so "foo" will result in Namespace
60+-- ["foo"].
56newtype Namespace = Namespace { unNamespace :: [Text] }
61newtype Namespace = Namespace { unNamespace :: [Text] }
57 deriving (Eq,Show,Read,Ord,Generic,ToJSON,FromJSON,Monoid)
62 deriving (Eq,Show,Read,Ord,Generic,ToJSON,FromJSON,Monoid)
58
63
@@ -168,6 +173,7 @@ ls = logStr
168
173
169
174
170-------------------------------------------------------------------------------
175-------------------------------------------------------------------------------
176+-- | Convert any showable type into a LogStr.
171showLS :: Show a => a -> LogStr
177showLS :: Show a => a -> LogStr
172showLS = ls . show
178showLS = ls . show
173
179
@@ -181,6 +187,7 @@ newtype ThreadIdText = ThreadIdText {
181mkThreadIdText :: ThreadId -> ThreadIdText
187mkThreadIdText :: ThreadId -> ThreadIdText
182mkThreadIdText = ThreadIdText . T.pack . show
188mkThreadIdText = ThreadIdText . T.pack . show
183
189
190+
184-------------------------------------------------------------------------------
191-------------------------------------------------------------------------------
185-- | This has everything each log message will contain.
192-- | This has everything each log message will contain.
186data Item a = Item {
193data Item a = Item {
@@ -341,7 +348,15 @@ instance ToObject ()
341instance ToObject A.Object
348instance ToObject A.Object
342
349
343-------------------------------------------------------------------------------
350-------------------------------------------------------------------------------
344−-- | Payload objects need instances of this class.
351+-- | Payload objects need instances of this class. LogItem makes it so
352+-- that you can have very verbose items getting logged with lots of
353+-- extra fields but under normal circumstances, if your scribe is
354+-- configured for a lower verbosity level, it will only log a
355+-- selection of those keys. Furthermore, each 'Scribe' can be
356+-- configured with a different 'Verbosity' level. You could even use
357+-- 'registerScribe', 'unregisterScribe', and 'clearScribes' to at
358+-- runtime swap out your existing scribes for more verbose debugging
359+-- scribes if you wanted to.
345--
360--
346-- When defining 'payloadKeys', don't redundantly declare the same
361-- When defining 'payloadKeys', don't redundantly declare the same
347-- keys for higher levels of verbosity. Each level of verbosity
362-- keys for higher levels of verbosity. Each level of verbosity
@@ -666,7 +681,7 @@ getLoc = [| $(location >>= liftLoc) |]
666
681
667
682
668-------------------------------------------------------------------------------
683-------------------------------------------------------------------------------
669−-- | 'Loc'-tagged logging when using template-haskell is OK.
684+-- | 'Loc'-tagged logging when using template-haskell.
670--
685--
671-- @$(logT) obj mempty InfoS "Hello world"@
686-- @$(logT) obj mempty InfoS "Hello world"@
672logT :: ExpQ
687logT :: ExpQ
katip/src/Katip/Monadic.hs+8−3
@@ -69,7 +69,10 @@ data AnyLogContext where
69
69
70-------------------------------------------------------------------------------
70-------------------------------------------------------------------------------
71-- | Heterogeneous list of log contexts that provides a smart
71-- | Heterogeneous list of log contexts that provides a smart
72−-- 'LogContext' instance for combining multiple payload policies.
72+-- 'LogContext' instance for combining multiple payload policies. This
73+-- is critical for log contexts deep down in a stack to be able to
74+-- inject their own context without worrying about other context that
75+-- has already been set.
73newtype LogContexts = LogContexts [AnyLogContext] deriving (Monoid)
76newtype LogContexts = LogContexts [AnyLogContext] deriving (Monoid)
74
77
75instance ToJSON LogContexts where
78instance ToJSON LogContexts where
@@ -90,7 +93,8 @@ instance LogItem LogContexts where
90
93
91
94
92-------------------------------------------------------------------------------
95-------------------------------------------------------------------------------
93−-- | Lift a log context into the generic wrapper
96+-- | Lift a log context into the generic wrapper so that it can
97+-- combine with the existing log context.
94liftPayload :: (LogItem a) => a -> LogContexts
98liftPayload :: (LogItem a) => a -> LogContexts
95liftPayload = LogContexts . (:[]) . AnyLogContext
99liftPayload = LogContexts . (:[]) . AnyLogContext
96
100
@@ -164,7 +168,8 @@ logFM sev msg = do
164
168
165
169
166-------------------------------------------------------------------------------
170-------------------------------------------------------------------------------
167−-- | 'Loc'-tagged logging when using template-haskell is OK. Automatically supplies payload and namespace.
171+-- | 'Loc'-tagged logging when using template-haskell. Automatically
172+-- supplies payload and namespace.
168--
173--
169-- @$(logt) InfoS "Hello world"@
174-- @$(logt) InfoS "Hello world"@
170logTM :: ExpQ
175logTM :: ExpQ
katip/src/Katip/Scribes/Handle.hs+1
@@ -49,6 +49,7 @@ data ColorStrategy
49
49
50
50
51-------------------------------------------------------------------------------
51-------------------------------------------------------------------------------
52+-- | Logs to a file handle such as stdout, stderr, or a file.
52mkHandleScribe :: ColorStrategy -> Handle -> Severity -> Verbosity -> IO Scribe
53mkHandleScribe :: ColorStrategy -> Handle -> Severity -> Verbosity -> IO Scribe
53mkHandleScribe cs h sev verb = do
54mkHandleScribe cs h sev verb = do
54 hSetBuffering h LineBuffering
55 hSetBuffering h LineBuffering