packages feed

katip 0.6.1.0 → 0.6.2.0

raw patch · 7 files changed

+92/−24 lines, 7 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Katip: bracketFormat :: LogItem a => ItemFormatter a
+ Katip: jsonFormat :: LogItem a => ItemFormatter a
+ Katip: mkHandleScribeWithFormatter :: (forall a. LogItem a => ItemFormatter a) -> ColorStrategy -> Handle -> Severity -> Verbosity -> IO Scribe
+ Katip: type ItemFormatter a = Bool -> Verbosity -> Item a -> Builder
+ Katip.Scribes.Handle: bracketFormat :: LogItem a => ItemFormatter a
+ Katip.Scribes.Handle: colorBySeverity :: Bool -> Severity -> Text -> Text
+ Katip.Scribes.Handle: jsonFormat :: LogItem a => ItemFormatter a
+ Katip.Scribes.Handle: mkHandleScribeWithFormatter :: (forall a. LogItem a => ItemFormatter a) -> ColorStrategy -> Handle -> Severity -> Verbosity -> IO Scribe
+ Katip.Scribes.Handle: type ItemFormatter a = Bool -> Verbosity -> Item a -> Builder
- Katip: itemApp :: forall a_ae53. Lens' (Item a_ae53) Namespace
+ Katip: itemApp :: forall a_ae56. Lens' (Item a_ae56) Namespace
- Katip: itemEnv :: forall a_ae53. Lens' (Item a_ae53) Environment
+ Katip: itemEnv :: forall a_ae56. Lens' (Item a_ae56) Environment
- Katip: itemHost :: forall a_ae53. Lens' (Item a_ae53) HostName
+ Katip: itemHost :: forall a_ae56. Lens' (Item a_ae56) HostName
- Katip: itemLoc :: forall a_ae53. Lens' (Item a_ae53) (Maybe Loc)
+ Katip: itemLoc :: forall a_ae56. Lens' (Item a_ae56) (Maybe Loc)
- Katip: itemMessage :: forall a_ae53. Lens' (Item a_ae53) LogStr
+ Katip: itemMessage :: forall a_ae56. Lens' (Item a_ae56) LogStr
- Katip: itemNamespace :: forall a_ae53. Lens' (Item a_ae53) Namespace
+ Katip: itemNamespace :: forall a_ae56. Lens' (Item a_ae56) Namespace
- Katip: itemPayload :: forall a_ae53 a_ak79. Lens (Item a_ae53) (Item a_ak79) a_ae53 a_ak79
+ Katip: itemPayload :: forall a_ae56 a_ak7c. Lens (Item a_ae56) (Item a_ak7c) a_ae56 a_ak7c
- Katip: itemProcess :: forall a_ae53. Lens' (Item a_ae53) ProcessID
+ Katip: itemProcess :: forall a_ae56. Lens' (Item a_ae56) ProcessID
- Katip: itemSeverity :: forall a_ae53. Lens' (Item a_ae53) Severity
+ Katip: itemSeverity :: forall a_ae56. Lens' (Item a_ae56) Severity
- Katip: itemThread :: forall a_ae53. Lens' (Item a_ae53) ThreadIdText
+ Katip: itemThread :: forall a_ae56. Lens' (Item a_ae56) ThreadIdText
- Katip: itemTime :: forall a_ae53. Lens' (Item a_ae53) UTCTime
+ Katip: itemTime :: forall a_ae56. Lens' (Item a_ae56) UTCTime
- Katip.Core: itemApp :: forall a_ae53. Lens' (Item a_ae53) Namespace
+ Katip.Core: itemApp :: forall a_ae56. Lens' (Item a_ae56) Namespace
- Katip.Core: itemEnv :: forall a_ae53. Lens' (Item a_ae53) Environment
+ Katip.Core: itemEnv :: forall a_ae56. Lens' (Item a_ae56) Environment
- Katip.Core: itemHost :: forall a_ae53. Lens' (Item a_ae53) HostName
+ Katip.Core: itemHost :: forall a_ae56. Lens' (Item a_ae56) HostName
- Katip.Core: itemLoc :: forall a_ae53. Lens' (Item a_ae53) (Maybe Loc)
+ Katip.Core: itemLoc :: forall a_ae56. Lens' (Item a_ae56) (Maybe Loc)
- Katip.Core: itemMessage :: forall a_ae53. Lens' (Item a_ae53) LogStr
+ Katip.Core: itemMessage :: forall a_ae56. Lens' (Item a_ae56) LogStr
- Katip.Core: itemNamespace :: forall a_ae53. Lens' (Item a_ae53) Namespace
+ Katip.Core: itemNamespace :: forall a_ae56. Lens' (Item a_ae56) Namespace
- Katip.Core: itemPayload :: forall a_ae53 a_ak79. Lens (Item a_ae53) (Item a_ak79) a_ae53 a_ak79
+ Katip.Core: itemPayload :: forall a_ae56 a_ak7c. Lens (Item a_ae56) (Item a_ak7c) a_ae56 a_ak7c
- Katip.Core: itemProcess :: forall a_ae53. Lens' (Item a_ae53) ProcessID
+ Katip.Core: itemProcess :: forall a_ae56. Lens' (Item a_ae56) ProcessID
- Katip.Core: itemSeverity :: forall a_ae53. Lens' (Item a_ae53) Severity
+ Katip.Core: itemSeverity :: forall a_ae56. Lens' (Item a_ae56) Severity
- Katip.Core: itemThread :: forall a_ae53. Lens' (Item a_ae53) ThreadIdText
+ Katip.Core: itemThread :: forall a_ae56. Lens' (Item a_ae56) ThreadIdText
- Katip.Core: itemTime :: forall a_ae53. Lens' (Item a_ae53) UTCTime
+ Katip.Core: itemTime :: forall a_ae56. Lens' (Item a_ae56) UTCTime
- Katip.Scribes.Handle: formatItem :: LogItem a => Bool -> Verbosity -> Item a -> Builder
+ Katip.Scribes.Handle: formatItem :: LogItem a => ItemFormatter a

Files

README.md view
@@ -84,3 +84,4 @@ * [Leonid Onokhov](https://github.com/sopvop) * [Alexander Vershilov](https://github.com/qnikst) * [Chris Martin](https://github.com/chris-martin)+* [Domen Kožar](https://github.com/domenkozar)
changelog.md view
@@ -1,3 +1,11 @@+0.6.2.0+=======+* Add `mkHandleScribeWithFormatter`. This allows control over the+  format of log items going to a handle. Credit to [Domen+  Kožar](https://github.com/domenkozar) for the implementation.+* Add `jsonFormat` handle formatter.+* Deprecate `formatItem` which is now replaced by `bracketFormat`.+ 0.6.1.0 ======= * Loosen deps
katip.cabal view
@@ -1,5 +1,5 @@ name:                katip-version:             0.6.1.0+version:             0.6.2.0 synopsis:            A structured logging framework. description:   Katip is a structured logging framework. See README.md for more details.
src/Katip.hs view
@@ -177,8 +177,12 @@      -- * Included Scribes     , mkHandleScribe+    , mkHandleScribeWithFormatter     , mkFileScribe     , ColorStrategy (..)+    , ItemFormatter+    , bracketFormat+    , jsonFormat      -- * Tools for implementing Scribes     , permitItem
src/Katip/Monadic.hs view
@@ -272,16 +272,14 @@   ---------------------------------------------------------------------------------- | 'Loc'-tagged logging when using template-haskell. Automatically--- supplies payload and namespace.+-- | 'Loc'-tagged logging when using <https://hackage.haskell.org/package/base-4.8.2.0/docs/GHC-Stack.html#v:getCallStack implicit-callstacks>.+--   Automatically supplies payload and namespace. -- -- Same consideration as `logLoc` applies. ----- This function does not require template-haskell as it--- automatically uses <https://hackage.haskell.org/package/base-4.8.2.0/docs/GHC-Stack.html#v:getCallStack implicit-callstacks>--- when the code is compiled using GHC > 7.8. Using an older version of the--- compiler will result in the emission of a log line without any location information,--- so be aware of it. Users using GHC <= 7.8 may want to use the template-haskell function+-- This function does not require template-haskell. Using GHC <= 7.8 will result+-- in the emission of a log line without any location information.+-- Users using GHC <= 7.8 may want to use the template-haskell function -- `logTM` for maximum compatibility. -- -- @logLocM InfoS "Hello world"@
src/Katip/Scribes/Handle.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE RecordWildCards #-}- module Katip.Scribes.Handle where  -------------------------------------------------------------------------------@@ -8,6 +6,8 @@ import           Control.Exception      (bracket_, finally) import           Control.Monad import           Data.Aeson+import           Data.Text.Lazy         (toStrict)+import           Data.Text.Lazy.Encoding     (decodeUtf8) import qualified Data.HashMap.Strict    as HM import           Data.Monoid            as M import           Data.Scientific        as S@@ -64,7 +64,15 @@ -- Returns the newly-created `Scribe`. The finalizer flushes the -- handle. Handle mode is set to 'LineBuffering' automatically. mkHandleScribe :: ColorStrategy -> Handle -> Severity -> Verbosity -> IO Scribe-mkHandleScribe cs h sev verb = do+mkHandleScribe = mkHandleScribeWithFormatter bracketFormat++-- | Logs to a file handle such as stdout, stderr, or a file. Takes a custom+-- `ItemFormatter` that can be used to format `Item` as needed.+--+-- Returns the newly-created `Scribe`. The finalizer flushes the+-- handle. Handle mode is set to 'LineBuffering' automatically.+mkHandleScribeWithFormatter :: (forall a . LogItem a => ItemFormatter a) -> ColorStrategy -> Handle -> Severity -> Verbosity -> IO Scribe+mkHandleScribeWithFormatter itemFormatter cs h sev verb = do     hSetBuffering h LineBuffering     colorize <- case cs of       ColorIfTerminal -> hIsTerminalDevice h@@ -72,7 +80,7 @@     lock <- newMVar ()     let logger i@Item{..} = do           when (permitItem sev i) $ bracket_ (takeMVar lock) (putMVar lock ()) $-            T.hPutStrLn h $ toLazyText $ formatItem colorize verb i+            T.hPutStrLn h $ toLazyText $ itemFormatter colorize verb i     return $ Scribe logger (hFlush h)  @@ -90,8 +98,26 @@   --------------------------------------------------------------------------------formatItem :: LogItem a => Bool -> Verbosity -> Item a -> Builder-formatItem withColor verb Item{..} =+-- | A custom ItemFormatter for logging `Item`s. Takes a `Bool` indicating+-- whether to colorize the output, `Verbosity` of output, and an `Item` to+-- format.+--+-- See `bracketFormat` and `jsonFormat` for examples.+type ItemFormatter a = Bool -> Verbosity -> Item a -> Builder+++formatItem :: LogItem a => ItemFormatter a+formatItem = bracketFormat+{-# DEPRECATED formatItem "Use bracketFormat instead" #-}++-- | A traditional 'bracketed' log format. Contexts and other information will+-- be flattened out into bracketed fields. For example:+--+-- > [2016-05-11 21:01:15][MyApp][Info][myhost.example.com][1724][ThreadId 1154][main:Helpers.Logging Helpers/Logging.hs:32:7] Started+-- > [2016-05-11 21:01:15][MyApp.confrabulation][Debug][myhost.example.com][1724][ThreadId 1154][confrab_factor:42.0][main:Helpers.Logging Helpers/Logging.hs:41:9] Confrabulating widgets, with extra namespace and context+-- > [2016-05-11 21:01:15][MyApp][Info][myhost.example.com][1724][ThreadId 1154][main:Helpers.Logging Helpers/Logging.hs:43:7] Namespace and context are back to normal+bracketFormat :: LogItem a => ItemFormatter a+bracketFormat withColor verb Item{..} =     brackets nowStr <>     brackets (mconcat $ map fromText $ intercalateNs _itemNamespace) <>     brackets (fromText (renderSeverity' _itemSeverity)) <>@@ -104,13 +130,34 @@   where     nowStr = fromText (formatAsLogTime _itemTime)     ks = map brackets $ getKeys verb _itemPayload-    renderSeverity' s = case s of-      EmergencyS -> red $ renderSeverity s-      AlertS     -> red $ renderSeverity s-      CriticalS  -> red $ renderSeverity s-      ErrorS     -> red $ renderSeverity s-      WarningS   -> yellow $ renderSeverity s-      _          -> renderSeverity s+    renderSeverity' severity =+      colorBySeverity withColor severity (renderSeverity severity)++-- | Logs items as JSON. This can be useful in circumstances where you already+-- have infrastructure that is expecting JSON to be logged to a standard stream+-- or file. For example:+--+-- > {"at":"2018-10-02T21:50:30.4523848Z","env":"production","ns":["MyApp"],"data":{},"app":["MyApp"],"msg":"Started","pid":"10456","loc":{"loc_col":9,"loc_pkg":"main","loc_mod":"Helpers.Logging","loc_fn":"Helpers\\Logging.hs","loc_ln":44},"host":"myhost.example.com","sev":"Info","thread":"ThreadId 139"}+-- > {"at":"2018-10-02T21:50:30.4523848Z","env":"production","ns":["MyApp","confrabulation"],"data":{"confrab_factor":42},"app":["MyApp"],"msg":"Confrabulating widgets, with extra namespace and context","pid":"10456","loc":{"loc_col":11,"loc_pkg":"main","loc_mod":"Helpers.Logging","loc_fn":"Helpers\\Logging.hs","loc_ln":53},"host":"myhost.example.com","sev":"Debug","thread":"ThreadId 139"}+-- > {"at":"2018-10-02T21:50:30.4523848Z","env":"production","ns":["MyApp"],"data":{},"app":["MyApp"],"msg":"Namespace and context are back to normal","pid":"10456","loc":{"loc_col":9,"loc_pkg":"main","loc_mod":"Helpers.Logging","loc_fn":"Helpers\\Logging.hs","loc_ln":55},"host":"myhost.example.com","sev":"Info","thread":"ThreadId 139"}+jsonFormat :: LogItem a => ItemFormatter a+jsonFormat withColor verb i =+  fromText $+  colorBySeverity withColor (_itemSeverity i) $+  toStrict $ decodeUtf8 $ encode $ itemJson verb i++-- | Color a text message based on `Severity`. `ErrorS` and more severe errors+-- are colored red, `WarningS` is colored yellow, and all other messages are+-- rendered in the default color.+colorBySeverity :: Bool -> Severity -> Text -> Text+colorBySeverity withColor severity msg = case severity of+  EmergencyS -> red msg+  AlertS     -> red msg+  CriticalS  -> red msg+  ErrorS     -> red msg+  WarningS   -> yellow msg+  _          -> msg+  where     red = colorize "31"     yellow = colorize "33"     colorize c s
test/Katip/Tests/Scribes/Handle.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes #-} module Katip.Tests.Scribes.Handle     ( tests     ) where@@ -25,7 +26,6 @@ import           Text.Regex.TDFA ------------------------------------------------------------------------------- import           Katip-import           Katip.Scribes.Handle -------------------------------------------------------------------------------  @@ -55,6 +55,10 @@       goldenVsString "Text-golden"                      "test/Katip/Tests/Scribes/Handle-text.golden"                      (setupFn >>= writeTextLog)+  , withResource setupTempFile teardownTempFile $ \setupFn ->+      goldenVsString "Json-golden"+                     "test/Katip/Tests/Scribes/Handle-json.golden"+                     (setupFn >>= writeJsonLog)   ]  @@ -234,14 +238,20 @@  ------------------------------------------------------------------------------- writeTextLog :: (FilePath, Handle) -> IO (BL.ByteString)-writeTextLog (path, h) = do+writeTextLog = writeFormattedLog bracketFormat++writeJsonLog :: (FilePath, Handle) -> IO (BL.ByteString)+writeJsonLog = writeFormattedLog jsonFormat++writeFormattedLog :: (forall a . LogItem a => ItemFormatter a) -> (FilePath, Handle) -> IO (BL.ByteString)+writeFormattedLog format (path, h) = do     mapM_ (put . formatOne) genItems     mapM_ (put . formatOne) genTypedItems     hClose h     BL.readFile path   where     formatOne :: LogItem a => Item a -> Text-    formatOne = LT.toStrict . LT.toLazyText . formatItem False V3+    formatOne = LT.toStrict . LT.toLazyText . format False V3     put = B.hPutStrLn h . T.encodeUtf8  setupTempFile :: IO (FilePath, Handle)