on master help sign in
23 files changed+224−271
since splitsnapshots
unifiedsplit
.gitignore+1 .travis.yml+8−9 katip-datadog/changelog.md+4 katip-datadog/katip-datadog.cabal+1−1 katip-datadog/src/Katip/Scribes/Datadog/TCP.hs+1−1 katip-elasticsearch/bench/Main.hs+3−3 katip-elasticsearch/changelog.md+10 katip-elasticsearch/docker-compose.yml+10 katip-elasticsearch/examples/example.hs+1−1 katip-elasticsearch/katip-elasticsearch.cabal+1−4 katip-elasticsearch/src/Katip/Scribes/ElasticSearch.hs+5 katip-elasticsearch/src/Katip/Scribes/ElasticSearch/Internal.hs+18−7 katip-elasticsearch/test/Main.hs+23−7 katip/README.md+1−1 katip/changelog.md+13 katip/katip.cabal+28−30 katip/src/Katip.hs+1−1 katip/src/Katip/Core.hs+36−19 katip/src/Katip/Monadic.hs+20−6 katip/src/Katip/Scribes/Handle.hs+26−43 katip/src/Katip/Scribes/RotatingHandler.hs−126 katip/test/Katip/Tests/Scribes/Handle.hs+8−6 stack.yaml+5−6
.gitignore+1
@@ -7,3 +7,4 @@ TAGS
77*.hi
88*.dyn_o
99*.dyn_hi
10+stack.yaml.lock
.travis.yml+8−9
@@ -9,21 +9,19 @@ addons:
99 apt:
1010 packages:
1111 - libgmp-dev
12− - oracle-java8-installer
1312
1413# The different configurations we want to test. You could also do things like
1514# change flags or use --stack-yaml to point to a different file.
1615matrix:
1716 include:
18− - env: ARGS="--resolver=lts-10" ESVERSION=1.5.2 ESURL=https://download.elastic.co/elasticsearch/elasticsearch ESTESTARGS="--es-version 1"
19− - env: ARGS="--resolver=lts-11" ESVERSION=1.5.2 ESURL=https://download.elastic.co/elasticsearch/elasticsearch ESTESTARGS="--es-version 1"
20− - env: ARGS="--resolver=lts-12" ESVERSION=1.5.2 ESURL=https://download.elastic.co/elasticsearch/elasticsearch ESTESTARGS="--es-version 1"
21− - env: ARGS="--resolver=nightly" ESVERSION=5.5.0 ESURL=https://artifacts.elastic.co/downloads/elasticsearch ESTESTARGS="--es-version 5" ES_JAVA_OPTS="-Xms500m -Xmx750m" JAVA_HOME=/usr/lib/jvm/java-8-oracle
22− - env: ARGS="--resolver=nightly" ESVERSION=6.2.2 ESURL=https://artifacts.elastic.co/downloads/elasticsearch ESTESTARGS="--es-version 5" ES_JAVA_OPTS="-Xms500m -Xmx750m" JAVA_HOME=/usr/lib/jvm/java-8-oracle
23− # nightlies may fail from time to time
17+ - env: ARGS="--resolver=lts-16" ESVERSION=5.5.0 ESURL=https://artifacts.elastic.co/downloads/elasticsearch ESTESTARGS="--es-version 5" ES_JAVA_OPTS="-Xms500m -Xmx750m"
18+ - env: ARGS="--resolver=lts-16" ESVERSION=6.2.2 ESURL=https://artifacts.elastic.co/downloads/elasticsearch ESTESTARGS="--es-version 5" ES_JAVA_OPTS="-Xms500m -Xmx750m"
19+ - env: ARGS="--resolver=nightly" ESVERSION=5.5.0 ESURL=https://artifacts.elastic.co/downloads/elasticsearch ESTESTARGS="--es-version 5" ES_JAVA_OPTS="-Xms500m -Xmx750m"
20+ - env: ARGS="--resolver=nightly" ESVERSION=6.2.2 ESURL=https://artifacts.elastic.co/downloads/elasticsearch ESTESTARGS="--es-version 5" ES_JAVA_OPTS="-Xms500m -Xmx750m"
21+ # nightlies may fail usually due to lagging dependencies
2422 allow_failures:
25− - env: ARGS="--resolver=nightly" ESVERSION=5.5.0 ESURL=https://artifacts.elastic.co/downloads/elasticsearch ESTESTARGS="--es-version 5" ES_JAVA_OPTS="-Xms500m -Xmx750m" JAVA_HOME=/usr/lib/jvm/java-8-oracle
26− - env: ARGS="--resolver=nightly" ESVERSION=6.2.2 ESURL=https://artifacts.elastic.co/downloads/elasticsearch ESTESTARGS="--es-version 5" ES_JAVA_OPTS="-Xms500m -Xmx750m" JAVA_HOME=/usr/lib/jvm/java-8-oracle
23+ - env: ARGS="--resolver=nightly" ESVERSION=5.5.0 ESURL=https://artifacts.elastic.co/downloads/elasticsearch ESTESTARGS="--es-version 5" ES_JAVA_OPTS="-Xms500m -Xmx750m"
24+ - env: ARGS="--resolver=nightly" ESVERSION=6.2.2 ESURL=https://artifacts.elastic.co/downloads/elasticsearch ESTESTARGS="--es-version 5" ES_JAVA_OPTS="-Xms500m -Xmx750m"
2725
2826before_install:
2927# Download and unpack the stack executable
@@ -36,6 +34,7 @@ install:
3634 - tar xzf elasticsearch-$ESVERSION.tar.gz
3735 # set up a repo for snapshot testing. Required in ES >= 1.6
3836 - echo "path.repo = [\"/tmp\"]" >> ./elasticsearch-$ESVERSION/elasticsearch.yml
37+ - java -version
3938 - ./elasticsearch-$ESVERSION/bin/elasticsearch &
4039 # Bloodhound seems to take a while to build and can sometimes stall out the build when travis detects no output.
4140
katip-datadog/changelog.md+4
@@ -1,3 +1,7 @@
1+0.2.0.0
2+==========
3+* Remove import of deprecated Network module
4+
150.1.0.0
26==========
37* Initial release
katip-datadog/katip-datadog.cabal+1−1
@@ -1,5 +1,5 @@
11name: katip-datadog
2−version: 0.1.0.0
2+version: 0.2.0.0
33synopsis: Datadog scribe for the Katip logging framework
44description: See README.md for more details.
55license: BSD3
katip-datadog/src/Katip/Scribes/Datadog/TCP.hs+1−1
@@ -33,8 +33,8 @@ import qualified Data.Text.Lazy.Builder as B
3333import Data.Time (NominalDiffTime)
3434import Katip
3535import Katip.Core (LocJs (..))
36−import qualified Network as Net
3736import qualified Network.Connection as C
37+import qualified Network.Socket as Net
3838import qualified System.Posix.Types as POSIX
3939-------------------------------------------------------------------------------
4040
katip-elasticsearch/bench/Main.hs+3−3
@@ -15,11 +15,11 @@ import qualified Data.HashMap.Strict as HM
1515import Data.Proxy (Proxy (..))
1616import System.Random
1717import qualified Data.Text as T
18−import Database.V1.Bloodhound.Types
18+import Database.Bloodhound.Types
1919import Numeric
2020-------------------------------------------------------------------------------
2121import Katip.Scribes.ElasticSearch
22−import Katip.Scribes.ElasticSearch.Internal (ESV1)
22+import Katip.Scribes.ElasticSearch.Internal (ESV5)
2323-------------------------------------------------------------------------------
2424
2525main :: IO ()
@@ -34,7 +34,7 @@ main = do
3434mkDocIdBenchmark :: Benchmark
3535mkDocIdBenchmark = bgroup "mkDocId"
3636 [
37− bench "mkDocId (randomIO)" $ nfIO (mkDocId (Proxy :: Proxy ESV1))
37+ bench "mkDocId (randomIO)" $ nfIO (mkDocId (Proxy :: Proxy ESV5))
3838 , bench "mkDocId' (shared )" $ nfIO mkDocId'
3939 ]
4040
katip-elasticsearch/changelog.md+10
@@ -1,3 +1,13 @@
1+0.7.0.0
2+=======
3+* Make compatible with unreleased bloodhound 0.17
4+* Deprecate use of ES version 1 which has been removed from bloodhound
5+ 0.17. All users should move over to ESV5 which should work for
6+ versions 5 and up.
7+* Default configuration to ESV5
8+* Add deprecation warnings for ESV1. Support for ESV1 will be removed
9+ in the future.
10+
1110.6.0.0
212=======
313* Update to katip-0.8.0.0 `PermitFunc` convention. To update, for
katip-elasticsearch/docker-compose.ymlnew file+10
@@ -0,0 +1,10 @@
1+version: "3.7"
2+services:
3+ # https://hub.docker.com/_/elasticsearch
4+ elasticsearch:
5+ image: elasticsearch:5-alpine
6+ ports:
7+ - target: 9200
8+ published: 9200
9+ protocol: tcp
10+ mode: host
katip-elasticsearch/examples/example.hs+1−1
@@ -6,7 +6,7 @@ module Main
66
77-------------------------------------------------------------------------------
88import Control.Exception
9−import Database.V5.Bloodhound
9+import Database.Bloodhound
1010import Network.HTTP.Client
1111-------------------------------------------------------------------------------
1212import Katip
katip-elasticsearch/katip-elasticsearch.cabal+1−4
@@ -1,7 +1,7 @@
11name: katip-elasticsearch
22synopsis: ElasticSearch scribe for the Katip logging framework.
33description: See README.md for more details.
4−version: 0.6.0.0
4+version: 0.7.0.0
55license: BSD3
66license-file: LICENSE
77author: Ozgun Ataman, Michael Xavier
@@ -108,7 +108,4 @@ test-suite test
108108 , bytestring
109109 , tagged
110110
111− if flag(lib-Werror)
112− ghc-options: -Wall -Werror
113−
114111 ghc-options: -threaded -rtsopts
katip-elasticsearch/src/Katip/Scribes/ElasticSearch.hs+5
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
12-- | Includes a scribe that can be used to log structured, JSON log
23-- messages to ElasticSearch. These logs can be explored easily using
34-- <https://www.elastic.co/products/kibana kibana> or your tool of
@@ -67,12 +68,16 @@ module Katip.Scribes.ElasticSearch
6768 , essIndexSettings
6869 , essIndexSharding
6970 , defaultEsScribeCfg
71+#if !MIN_VERSION_bloodhound(0,17,0)
7072 , defaultEsScribeCfgV1
73+#endif
7174 , defaultEsScribeCfgV5
7275 -- ** Version-Proxied APIS
7376 -- $versionproxies
7477 , defaultEsScribeCfg'
78+#if !MIN_VERSION_bloodhound(0,17,0)
7579 , ESV1
80+#endif
7681 , ESV5
7782 -- * Utilities
7883 , mkDocId
katip-elasticsearch/src/Katip/Scribes/ElasticSearch/Internal.hs+18−7
@@ -28,7 +28,7 @@ import Control.Retry (RetryPolicy,
2828import Data.Aeson
2929import Data.ByteString.Lazy (ByteString)
3030import Data.List.NonEmpty (NonEmpty (..))
31−import Data.Monoid ((<>))
31+import Data.Monoid as Monoid
3232import Data.Text (Text)
3333import qualified Data.Text as T
3434import qualified Data.Text.Encoding as T
@@ -37,8 +37,12 @@ import Data.Time.Calendar.WeekDate
3737import Data.Typeable as Typeable
3838import Data.UUID
3939import qualified Data.UUID.V4 as UUID4
40+#if MIN_VERSION_bloodhound(0,17,0)
41+import qualified Database.Bloodhound as V5
42+#else
4043import qualified Database.V1.Bloodhound as V1
4144import qualified Database.V5.Bloodhound as V5
45+#endif
4246import Network.HTTP.Client
4347import Network.HTTP.Types.Status
4448import Text.Printf (printf)
@@ -95,7 +99,7 @@ data EsScribeCfg v = EsScribeCfg {
9599-- * DailyIndexSharding
96100defaultEsScribeCfg' :: ESVersion v => proxy v -> EsScribeCfg v
97101defaultEsScribeCfg' prx = EsScribeCfg {
98− essRetryPolicy = exponentialBackoff 25000 <> limitRetries 5
102+ essRetryPolicy = exponentialBackoff 25000 Monoid.<> limitRetries 5
99103 , essQueueSize = EsQueueSize 1000
100104 , essPoolSize = EsPoolSize 2
101105 , essAnnotateTypes = False
@@ -104,19 +108,22 @@ defaultEsScribeCfg' prx = EsScribeCfg {
104108 }
105109
106110
111+
112+
107113-------------------------------------------------------------------------------
108−-- | Alias of 'defaultEsScribeCfgV1' to minimize API
114+-- | Alias of 'defaultEsScribeCfgV5' to minimize API
109115-- breakage. Previous versions of katip-elasticsearch only supported
110−-- ES version 1.
111−defaultEsScribeCfg :: EsScribeCfg ESV1
112−defaultEsScribeCfg = defaultEsScribeCfgV1
116+-- ES version 1 and defaulted to it.
117+defaultEsScribeCfg :: EsScribeCfg ESV5
118+defaultEsScribeCfg = defaultEsScribeCfgV5
113119
114120
115121-------------------------------------------------------------------------------
122+#if !MIN_VERSION_bloodhound(0,17,0)
116123-- | EsScribeCfg that will use ElasticSearch V1
117124defaultEsScribeCfgV1 :: EsScribeCfg ESV1
118125defaultEsScribeCfgV1 = defaultEsScribeCfg' (Typeable.Proxy :: Typeable.Proxy ESV1)
119−
126+#endif
120127
121128-------------------------------------------------------------------------------
122129-- | EsScribeCfg that will use ElasticSearch V5
@@ -484,7 +491,10 @@ class ESVersion v where
484491
485492
486493
494+#if !MIN_VERSION_bloodhound(0,17,0)
487495data ESV1 = ESV1
496+{-# DEPRECATED ESV1 "ESV1 is deprecated and removed in bloodhound >= 0.17.0" #-}
497+
488498
489499instance ESVersion ESV1 where
490500 type BHEnv ESV1 = V1.BHEnv
@@ -524,6 +534,7 @@ instance ESVersion ESV1 where
524534 [ "type" .= String "string"
525535 , "index" .= String "analyzed"
526536 ]
537+#endif
527538
528539
529540data ESV5 = ESV5
katip-elasticsearch/test/Main.hs+23−7
@@ -34,8 +34,12 @@ import Data.Time
3434import Data.Time.Calendar.WeekDate
3535import Data.Typeable as Typeable
3636import qualified Data.Vector as V
37+#if MIN_VERSION_bloodhound(0,17,0)
38+import qualified Database.Bloodhound as V5
39+#else
3740import qualified Database.V1.Bloodhound as V1
3841import qualified Database.V5.Bloodhound as V5
42+#endif
3943import Network.HTTP.Client
4044import Network.HTTP.Types.Status
4145import Test.QuickCheck.Instances ()
@@ -54,8 +58,10 @@ main :: IO ()
5458main = defaultMainWithIngredients ings $ askOption $ \vers -> testGroup "katip-elasticsearch"
5559 [
5660 case vers of
57− TestV1 -> esTests (Typeable.Proxy :: Typeable.Proxy ESV1)
58− TestV5 -> esTests (Typeable.Proxy :: Typeable.Proxy ESV5)
61+#if !MIN_VERSION_bloodhound(0,17,0)
62+ TestV1 -> esTests (Typeable.Proxy :: Typeable.Proxy ESV1)
63+#endif
64+ TestV5 -> esTests (Typeable.Proxy :: Typeable.Proxy ESV5)
5965 , typeAnnotatedTests
6066 , roundToSundayTests
6167 ]
@@ -64,18 +70,26 @@ main = defaultMainWithIngredients ings $ askOption $ \vers -> testGroup "katip-e
6470
6571
6672-------------------------------------------------------------------------------
67−data TestWithESVersion = TestV1
68− | TestV5
69− deriving (Typeable)
73+data TestWithESVersion = TestV5
74+#if !MIN_VERSION_bloodhound(0,17,0)
75+ | TestV1
76+#endif
77+ deriving (Typeable)
7078
7179
7280instance IsOption TestWithESVersion where
73− defaultValue = TestV1
81+ defaultValue = TestV5
82+#if !MIN_VERSION_bloodhound(0,17,0)
7483 parseValue "1" = Just TestV1
84+#endif
7585 parseValue "5" = Just TestV5
7686 parseValue _ = Nothing
7787 optionName = Tagged "es-version"
78− optionHelp = Tagged "Version of ES to test against, either 1 or 5, defaulting to 1."
88+#if MIN_VERSION_bloodhound(0,17,0)
89+ optionHelp = Tagged "Version of ES to test against, either 1 or 5, defaulting to 5."
90+#else
91+ optionHelp = Tagged "Version of ES to test against, only v5 is supported, but should work for higher versions."
92+#endif
7993
8094
8195class ESVersion v => TestESVersion v where
@@ -101,6 +115,7 @@ class ESVersion v => TestESVersion v where
101115 searchByIndex :: proxy v -> IndexName v -> Search v -> BH v IO (Response ByteString)
102116
103117
118+#if !MIN_VERSION_bloodhound(0,17,0)
104119instance TestESVersion ESV1 where
105120 type Server ESV1 = V1.Server
106121 toServer _ = V1.Server
@@ -122,6 +137,7 @@ instance TestESVersion ESV1 where
122137 refreshIndex _ = V1.refreshIndex
123138 withBH _ = V1.withBH
124139 searchByIndex _ = V1.searchByIndex
140+#endif
125141
126142
127143instance TestESVersion ESV5 where
katip/README.md+1−1
@@ -16,7 +16,7 @@ Kâtip (pronounced kah-tip) is the Turkish word for scribe.
1616 add context that will be automatically merged in with existing log
1717 context.
1818
19−* *Easy to Integration:* Katip was designed to be easily integrated
19+* *Easy Integration:* Katip was designed to be easily integrated
2020 into existing monads. By using typeclasses for logging facilities,
2121 individual subsystems and even libraries can easily add their own
2222 namespacing and context without having any knowledge of their
katip/changelog.md+13
@@ -1,3 +1,16 @@
1+0.8.5.0
2+=======
3+* Add MonadResource instances [#121](https://github.com/Soostone/katip/pull/121)
4+
5+0.8.4.0
6+=======
7+* Add support for unliftio-core 0.2 while maintaining backwards-compatible support for 0.1
8+
9+0.8.3.0
10+=======
11+
12+* Add `logKatipItem` function and reimplement `logItem` to use it. [vlatkoB](https://github.com/vlatkoB)
13+
1140.8.2.0
215=======
316* Add `MonadFail` instances for `base` >= 4.9.0.0 [Koray Al](https://github.com/korayal)
katip/katip.cabal+28−30
@@ -1,5 +1,5 @@
11name: katip
2−version: 0.8.2.0
2+version: 0.8.5.0
33synopsis: A structured logging framework.
44description:
55 Katip is a structured logging framework. See README.md for more details.
@@ -36,23 +36,22 @@ flag lib-Werror
3636 manual: True
3737
3838library
39− exposed-modules: Katip
40− , Katip.Core
41− , Katip.Format.Time
42− , Katip.Monadic
43− , Katip.Scribes.Handle
44− , Katip.Scribes.RotatingHandler
39+ exposed-modules:
40+ Katip
41+ Katip.Core
42+ Katip.Format.Time
43+ Katip.Monadic
44+ Katip.Scribes.Handle
4545
46− default-extensions: DeriveGeneric
47− , FlexibleContexts
48− , GeneralizedNewtypeDeriving
49− , LambdaCase
50− , MultiParamTypeClasses
51− , OverloadedStrings
52− , RankNTypes
53− , RecordWildCards
54− , ScopedTypeVariables
55− , TemplateHaskell
46+ default-extensions:
47+ DeriveGeneric
48+ FlexibleContexts
49+ GeneralizedNewtypeDeriving
50+ MultiParamTypeClasses
51+ RankNTypes
52+ RecordWildCards
53+ TemplateHaskell
54+ OverloadedStrings
5655
5756 build-depends: base >=4.9.0.0 && <5
5857 , aeson >=0.6
@@ -60,28 +59,27 @@ library
6059 , auto-update >= 0.1
6160 , bytestring >= 0.9
6261 , containers >=0.4
63− , deepseq
6462 , either >= 4
63+ , safe-exceptions >= 0.1.0.0
6564 , hostname >=1.0
66− , microlens >= 0.2.0.0
67− , microlens-th >= 0.1.0.0
68− , monad-control >= 1.0
69− , mtl >= 2.0
7065 , old-locale >= 1.0
71− , resourcet >= 1.1
72− , safe-exceptions >= 0.1.0.0
73− , scientific >= 0.3.3.0
74− , semigroups
75− , stm >= 2.4 && < 2.5
7666 , string-conv >= 0.1
7767 , template-haskell >= 2.8
7868 , text >= 0.11
7969 , time >= 1
8070 , transformers >= 0.3
81− , transformers-base >= 0.3
8271 , transformers-compat
83− , unliftio-core >= 0.1
8472 , unordered-containers >= 0.2
73+ , monad-control >= 1.0
74+ , mtl >= 2.0
75+ , transformers-base >= 0.3
76+ , resourcet >= 1.1
77+ , scientific >= 0.3.3.0
78+ , microlens >= 0.2.0.0
79+ , microlens-th >= 0.1.0.0
80+ , semigroups
81+ , unliftio-core >= 0.1
82+ , stm >= 2.4
8583
8684 hs-source-dirs: src
8785 default-language: Haskell2010
@@ -89,7 +87,7 @@ library
8987 if flag(lib-Werror)
9088 ghc-options: -Werror
9189 if os(windows)
92− build-depends: Win32 >=2.3 && <2.6
90+ build-depends: Win32 >=2.3 && <2.9
9391 exposed-modules: Katip.Compat
9492 else
9593 build-depends: unix >= 2.5 && <2.8
katip/src/Katip.hs+1−1
@@ -161,6 +161,7 @@ module Katip
161161 , logT
162162 , logLoc
163163 , logItem
164+ , logKatipItem
164165 , logException
165166 -- ** 'KatipContext': Logging With Context
166167 -- $katipcontextlogging
@@ -181,7 +182,6 @@ module Katip
181182 , mkHandleScribe
182183 , mkHandleScribeWithFormatter
183184 , mkFileScribe
184− , mkFileScribeWithFormatter
185185 , ColorStrategy (..)
186186 , ItemFormatter
187187 , bracketFormat
katip/src/Katip/Core.hs+36−19
@@ -44,7 +44,8 @@ import Control.Monad.Trans.Either
4444import Control.Monad.Trans.Except
4545import Control.Monad.Trans.Maybe
4646import Control.Monad.Trans.Reader
47−import Control.Monad.Trans.Resource (ResourceT, transResourceT)
47+import Control.Monad.Trans.Resource (MonadResource, ResourceT,
48+ transResourceT)
4849import Control.Monad.Trans.RWS.Lazy (RWST, mapRWST)
4950import qualified Control.Monad.Trans.RWS.Strict as Strict (RWST, mapRWST)
5051import Control.Monad.Trans.State.Lazy (StateT, mapStateT)
@@ -664,7 +665,7 @@ makeLenses ''LogEnv
664665
665666
666667-------------------------------------------------------------------------------
667−-- | Create a reasonable default InitLogEnv. Uses an 'AutoUdate' which
668+-- | Create a reasonable default InitLogEnv. Uses an 'AutoUpdate' which
668669-- updates the timer every 1ms. If you need even more timestamp
669670-- precision at the cost of performance, consider setting
670671-- '_logEnvTimer' with 'getCurrentTime'.
@@ -879,7 +880,8 @@ instance (Katip m) => Katip (ResourceT m) where
879880-- opposed to implementing 'Katip' for your monad.
880881newtype KatipT m a = KatipT { unKatipT :: ReaderT LogEnv m a }
881882 deriving ( Functor, Applicative, Monad, MonadIO
882− , MonadMask, MonadCatch, MonadThrow, MonadTrans, MonadBase b)
883+ , MonadMask, MonadCatch, MonadThrow, MonadResource, MonadTrans
884+ , MonadBase b)
883885
884886
885887instance MonadIO m => Katip (KatipT m) where
@@ -901,9 +903,14 @@ instance (MonadBaseControl b m) => MonadBaseControl b (KatipT m) where
901903 restoreM = defaultRestoreM
902904
903905instance MonadUnliftIO m => MonadUnliftIO (KatipT m) where
906+#if MIN_VERSION_unliftio_core(0, 2, 0)
907+ withRunInIO inner = KatipT $ ReaderT $ \le -> withRunInIO $ \run ->
908+ inner (run . runKatipT le)
909+#else
904910 askUnliftIO = KatipT $
905− withUnliftIO $ \u ->
906− pure (UnliftIO (unliftIO u . unKatipT))
911+ withUnliftIO $ \u ->
912+ pure (UnliftIO (unliftIO u . unKatipT))
913+#endif
907914
908915#if MIN_VERSION_base(4, 9, 0)
909916instance MF.MonadFail m => MF.MonadFail (KatipT m) where
@@ -941,19 +948,29 @@ logItem
941948 -> m ()
942949logItem a ns loc sev msg = do
943950 LogEnv{..} <- getLogEnv
944− liftIO $ do
945− item <- Item
946− <$> pure _logEnvApp
947− <*> pure _logEnvEnv
948− <*> pure sev
949− <*> (mkThreadIdText <$> myThreadId)
950− <*> pure _logEnvHost
951− <*> pure _logEnvPid
952− <*> pure a
953− <*> pure msg
954− <*> _logEnvTimer
955− <*> pure (_logEnvApp <> ns)
956− <*> pure loc
951+ logKatipItem =<< liftIO
952+ (Item <$> pure _logEnvApp
953+ <*> pure _logEnvEnv
954+ <*> pure sev
955+ <*> (mkThreadIdText <$> myThreadId)
956+ <*> pure _logEnvHost
957+ <*> pure _logEnvPid
958+ <*> pure a
959+ <*> pure msg
960+ <*> _logEnvTimer
961+ <*> pure (_logEnvApp <> ns)
962+ <*> pure loc)
963+
964+-- | Log already constructed 'Item'. This is the lowest level function that other log*
965+-- functions use.
966+-- It can be useful when implementing centralised logging services.
967+logKatipItem
968+ :: (A.Applicative m, LogItem a, Katip m)
969+ => Item a
970+ -> m ()
971+logKatipItem item = do
972+ LogEnv{..} <- getLogEnv
973+ liftIO $
957974 FT.forM_ (M.elems _logEnvScribes) $ \ ScribeHandle {..} -> do
958975 whenM (scribePermitItem shScribe item) $
959976 void $ atomically (tryWriteTBQueue shChan (NewItem item))
@@ -1002,7 +1019,7 @@ logException
10021019logException a ns sev action = action `catchAny` \e -> f e >> throwM e
10031020 where
10041021 f e = logF a ns sev (msg e)
1005− msg e = ls (T.pack "An exception has occured: ") <> showLS e
1022+ msg e = ls (T.pack "An exception has occurred: ") <> showLS e
10061023
10071024
10081025-------------------------------------------------------------------------------
katip/src/Katip/Monadic.hs+20−6
@@ -58,7 +58,8 @@ import Control.Monad.Trans.Either (EitherT, mapEitherT)
5858import Control.Monad.Trans.Except (ExceptT, mapExceptT)
5959import Control.Monad.Trans.Identity (IdentityT, mapIdentityT)
6060import Control.Monad.Trans.Maybe (MaybeT, mapMaybeT)
61−import Control.Monad.Trans.Resource (ResourceT, transResourceT)
61+import Control.Monad.Trans.Resource (MonadResource,
62+ ResourceT, transResourceT)
6263import Control.Monad.Trans.RWS (RWST, mapRWST)
6364import qualified Control.Monad.Trans.RWS.Strict as Strict (RWST, mapRWST)
6465import qualified Control.Monad.Trans.State.Strict as Strict (StateT, mapStateT)
@@ -315,7 +316,7 @@ logExceptionM
315316logExceptionM action sev = action `catchAny` \e -> f e >> throwM e
316317 where
317318 f e = logFM sev (msg e)
318− msg e = ls ("An exception has occured: " :: Text) Semi.<> showLS e
319+ msg e = ls ("An exception has occurred: " :: Text) Semi.<> showLS e
319320
320321
321322-------------------------------------------------------------------------------
@@ -349,6 +350,7 @@ newtype KatipContextT m a = KatipContextT {
349350 , MonadWriter w
350351 , MonadError e
351352 , MonadPlus
353+ , MonadResource
352354 , Alternative
353355 , MonadFix
354356 , MonadTrans
@@ -395,9 +397,15 @@ instance (MonadIO m) => KatipContext (KatipContextT m) where
395397 localKatipNamespace f (KatipContextT m) = KatipContextT $ local (\s -> s { ltsNamespace = f (ltsNamespace s)}) m
396398
397399instance MonadUnliftIO m => MonadUnliftIO (KatipContextT m) where
400+#if MIN_VERSION_unliftio_core(0, 2, 0)
401+ withRunInIO inner = KatipContextT $ ReaderT $ \lts -> withRunInIO $ \run ->
402+ inner (run . runKatipContextT (ltsLogEnv lts) (ltsContext lts) (ltsNamespace lts))
403+#else
398404 askUnliftIO = KatipContextT $
399− withUnliftIO $ \u ->
400− pure (UnliftIO (unliftIO u . unKatipContextT))
405+ withUnliftIO $ \u ->
406+ pure (UnliftIO (unliftIO u . unKatipContextT))
407+#endif
408+
401409
402410#if MIN_VERSION_base(4, 9, 0)
403411instance MF.MonadFail m => MF.MonadFail (KatipContextT m) where
@@ -482,9 +490,15 @@ instance MonadBaseControl b m => MonadBaseControl b (NoLoggingT m) where
482490 restoreM = NoLoggingT . restoreM
483491
484492instance MonadUnliftIO m => MonadUnliftIO (NoLoggingT m) where
493+#if MIN_VERSION_unliftio_core(0, 2, 0)
494+ withRunInIO inner = NoLoggingT $ withRunInIO $ \run ->
495+ inner (run . runNoLoggingT)
496+#else
485497 askUnliftIO = NoLoggingT $
486− withUnliftIO $ \u ->
487− pure (UnliftIO (unliftIO u . runNoLoggingT))
498+ withUnliftIO $ \u ->
499+ pure (UnliftIO (unliftIO u . runNoLoggingT))
500+#endif
501+
488502
489503instance MonadIO m => Katip (NoLoggingT m) where
490504 getLogEnv = liftIO (initLogEnv "NoLoggingT" "no-logging")
katip/src/Katip/Scribes/Handle.hs+26−43
@@ -3,20 +3,17 @@ module Katip.Scribes.Handle where
33-------------------------------------------------------------------------------
44import Control.Applicative as A
55import Control.Concurrent
6−import Control.Exception (finally)
6+import Control.Exception (bracket_, finally)
77import Data.Aeson
8−import Data.Aeson.Text
9−import Data.ByteString.Builder as B
10−import Data.ByteString.Lazy as BL (hPutStr)
11−import Data.ByteString.Lazy.Char8 as BL (singleton)
8+import Data.Text.Lazy (toStrict)
9+import Data.Text.Lazy.Encoding (decodeUtf8)
10+import qualified Data.HashMap.Strict as HM
1211import Data.Monoid as M
1312import Data.Scientific as S
1413import Data.Text (Text)
15−import Data.Text.Lazy.Builder as TL
16−import Data.Text.Lazy.Encoding (encodeUtf8)
14+import Data.Text.Lazy.Builder
15+import Data.Text.Lazy.IO as T
1716import System.IO
18−import qualified Data.HashMap.Strict as HM
19−
2017-------------------------------------------------------------------------------
2118import Katip.Core
2219import Katip.Format.Time (formatAsLogTime)
@@ -24,20 +21,15 @@ import Katip.Format.Time (formatAsLogTime)
2421
2522
2623-------------------------------------------------------------------------------
27−brackets :: TL.Builder -> TL.Builder
24+brackets :: Builder -> Builder
2825brackets m = fromText "[" M.<> m <> fromText "]"
2926
30−textBuilderToBS :: TL.Builder -> B.Builder
31−textBuilderToBS = B.lazyByteString . encodeUtf8 . toLazyText
32−
33−appendNL :: B.Builder -> B.Builder
34−appendNL b = b <> B.lazyByteString (BL.singleton '\n')
3527
3628-------------------------------------------------------------------------------
37−getKeys :: LogItem s => Verbosity -> s -> [TL.Builder]
29+getKeys :: LogItem s => Verbosity -> s -> [Builder]
3830getKeys verb a = concat (renderPair A.<$> HM.toList (payloadObject verb a))
3931 where
40− renderPair :: (Text, Value) -> [TL.Builder]
32+ renderPair :: (Text, Value) -> [Builder]
4133 renderPair (k,v) =
4234 case v of
4335 Object o -> concat [renderPair (k <> "." <> k', v') | (k', v') <- HM.toList o]
@@ -73,19 +65,6 @@ data ColorStrategy
7365mkHandleScribe :: ColorStrategy -> Handle -> PermitFunc -> Verbosity -> IO Scribe
7466mkHandleScribe = mkHandleScribeWithFormatter bracketFormat
7567
76−
77−mkFileScribeWithFormatter :: (forall a . LogItem a => ItemFormatter a)
78− -> ColorStrategy
79− -> FilePath
80− -> PermitFunc
81− -> Verbosity
82− -> IO Scribe
83−mkFileScribeWithFormatter formatter color f permitF verb = do
84− h <- openBinaryFile f AppendMode
85− Scribe logger finalizer permit <- mkHandleScribeWithFormatter formatter color h permitF verb
86− return (Scribe logger (finalizer `finally` hClose h) permit)
87−
88−
8968-- | Logs to a file handle such as stdout, stderr, or a file. Takes a custom
9069-- `ItemFormatter` that can be used to format `Item` as needed.
9170--
@@ -98,12 +77,14 @@ mkHandleScribeWithFormatter :: (forall a . LogItem a => ItemFormatter a)
9877 -> Verbosity
9978 -> IO Scribe
10079mkHandleScribeWithFormatter itemFormatter cs h permitF verb = do
80+ hSetBuffering h LineBuffering
10181 colorize <- case cs of
10282 ColorIfTerminal -> hIsTerminalDevice h
10383 ColorLog b -> return b
10484 lock <- newMVar ()
105− let logger i@Item{..} = withMVar lock $ \() -> do
106− BL.hPutStr h $ toLazyByteString $ itemFormatter colorize verb i
85+ let logger i@Item{..} = do
86+ bracket_ (takeMVar lock) (putMVar lock ()) $
87+ T.hPutStrLn h $ toLazyText $ itemFormatter colorize verb i
10788 return $ Scribe logger (hFlush h) permitF
10889
10990
@@ -114,17 +95,19 @@ mkHandleScribeWithFormatter itemFormatter cs h permitF verb = do
11495-- 'closeScribe'/'closeScribes'. Does not do log coloring. Sets handle
11596-- to 'LineBuffering' mode.
11697mkFileScribe :: FilePath -> PermitFunc -> Verbosity -> IO Scribe
117−mkFileScribe = mkFileScribeWithFormatter bracketFormat (ColorLog False)
98+mkFileScribe f permitF verb = do
99+ h <- openFile f AppendMode
100+ Scribe logger finalizer permit <- mkHandleScribe (ColorLog False) h permitF verb
101+ return (Scribe logger (finalizer `finally` hClose h) permit)
118102
119103
120104-------------------------------------------------------------------------------
121105-- | A custom ItemFormatter for logging `Item`s. Takes a `Bool` indicating
122106-- whether to colorize the output, `Verbosity` of output, and an `Item` to
123−-- format. Note that formatter is responsible for appending the newline at the
124−-- end of the string if required
107+-- format.
125108--
126109-- See `bracketFormat` and `jsonFormat` for examples.
127−type ItemFormatter a = Bool -> Verbosity -> Item a -> B.Builder
110+type ItemFormatter a = Bool -> Verbosity -> Item a -> Builder
128111
129112
130113formatItem :: LogItem a => ItemFormatter a
@@ -138,10 +121,10 @@ formatItem = bracketFormat
138121-- > [2016-05-11 21:01:15][MyApp.confrabulation][Debug][myhost.example.com][PID 1724][ThreadId 1154][confrab_factor:42.0][main:Helpers.Logging Helpers/Logging.hs:41:9] Confrabulating widgets, with extra namespace and context
139122-- > [2016-05-11 21:01:15][MyApp][Info][myhost.example.com][PID 1724][ThreadId 1154][main:Helpers.Logging Helpers/Logging.hs:43:7] Namespace and context are back to normal
140123bracketFormat :: LogItem a => ItemFormatter a
141−bracketFormat withColor verb Item{..} = appendNL $ textBuilderToBS $
124+bracketFormat withColor verb Item{..} =
142125 brackets nowStr <>
143126 brackets (mconcat $ map fromText $ intercalateNs _itemNamespace) <>
144− brackets (renderSeverity' _itemSeverity) <>
127+ brackets (fromText (renderSeverity' _itemSeverity)) <>
145128 brackets (fromString _itemHost) <>
146129 brackets ("PID " <> fromString (show _itemProcess)) <>
147130 brackets ("ThreadId " <> fromText (getThreadIdText _itemThread)) <>
@@ -152,7 +135,7 @@ bracketFormat withColor verb Item{..} = appendNL $ textBuilderToBS $
152135 nowStr = fromText (formatAsLogTime _itemTime)
153136 ks = map brackets $ getKeys verb _itemPayload
154137 renderSeverity' severity =
155− colorBySeverity withColor severity (fromText $ renderSeverity severity)
138+ colorBySeverity withColor severity (renderSeverity severity)
156139
157140-- | Logs items as JSON. This can be useful in circumstances where you already
158141-- have infrastructure that is expecting JSON to be logged to a standard stream
@@ -162,15 +145,15 @@ bracketFormat withColor verb Item{..} = appendNL $ textBuilderToBS $
162145-- > {"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"}
163146-- > {"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"}
164147jsonFormat :: LogItem a => ItemFormatter a
165−jsonFormat withColor verb i = appendNL $
166− textBuilderToBS $
148+jsonFormat withColor verb i =
149+ fromText $
167150 colorBySeverity withColor (_itemSeverity i) $
168− encodeToTextBuilder $ itemJson verb i
151+ toStrict $ decodeUtf8 $ encode $ itemJson verb i
169152
170153-- | Color a text message based on `Severity`. `ErrorS` and more severe errors
171154-- are colored red, `WarningS` is colored yellow, and all other messages are
172155-- rendered in the default color.
173−colorBySeverity :: Bool -> Severity -> TL.Builder -> TL.Builder
156+colorBySeverity :: Bool -> Severity -> Text -> Text
174157colorBySeverity withColor severity msg = case severity of
175158 EmergencyS -> red msg
176159 AlertS -> red msg
katip/src/Katip/Scribes/RotatingHandler.hsdeleted−126
@@ -1,126 +0,0 @@
1−module Katip.Scribes.RotatingHandler where
2−
3−import Control.Applicative
4−import Control.Concurrent
5−import Control.Concurrent.Async
6−import Control.Concurrent.STM
7−import Control.Debounce
8−import Control.DeepSeq
9−import Control.Exception
10−import Control.Monad
11−import Data.ByteString.Lazy as BL
12−import Data.IORef
13−import GHC.IO.Handle
14−import GHC.IO.Handle.FD
15−import GHC.IO.IOMode
16−
17−-- | File owner struct writing data to the file
18−-- sequentially. Automatic buffer flushing and log rotating.
19−data FileOwner = FileOwner
20− { foDataQueune :: TBQueue BL.ByteString
21− , foControlQueue :: TBQueue ControlMsg
22− , foAsync :: Async ()
23− -- ^ Wait for to be sure that worker thread is closed.
24− }
25−
26−data FileOwnerSettings = FileOwnerSettings
27− { fosDebounceFreq :: Maybe Int
28− , fosDataQueueLen :: Int
29− , fosControlQueueLen :: Int
30− }
31−
32−defaultFileOwnerSettings :: FileOwnerSettings
33−defaultFileOwnerSettings = FileOwnerSettings
34− { fosDebounceFreq = Just 200000 -- every 200ms
35− , fosDataQueueLen = 1000
36− , fosControlQueueLen = 100
37− }
38−
39−data ControlMsg
40− = CloseMsg
41− | FlushMsg
42− | ReopenMsg
43− deriving (Eq, Ord, Show)
44−
45−newFileOwner :: FilePath -> FileOwnerSettings -> IO FileOwner
46−newFileOwner fp s = do
47− dqueue <- newTBQueueIO $ fosDataQueueLen s
48− cqueue <- newTBQueueIO $ fosControlQueueLen s
49− let
50− newResource = do
51− openBinaryFile fp AppendMode
52− ack = newResource >>= newIORef
53− release ref = do
54− h <- readIORef ref
55− hFlush h
56− hClose h
57− go ref = do
58− let
59− readAllData = do
60− a <- readTBQueue dqueue
61− -- flushTBQueue never retries
62− as <- flushTBQueue dqueue
63− return $ a:as
64− readMsg
65− = (Left <$> readTBQueue cqueue)
66− <|> (Right <$> readAllData)
67− debounce action = case fosDebounceFreq s of
68− Nothing -> do
69− return $ return ()
70− Just freq -> mkDebounce $ defaultDebounceSettings
71− { debounceAction = action
72− , debounceFreq = freq }
73− flush <- debounce $ readIORef ref >>= hFlush
74− let
75− recur = atomically readMsg >>= \case
76− Right bs -> do
77− h <- readIORef ref
78− BL.hPutStr h $ mconcat bs
79− flush -- auto debounced flush
80− recur
81− Left c -> case c of
82− CloseMsg -> return () -- release will close the handler
83− FlushMsg -> do
84− readIORef ref >>= hFlush
85− recur
86− ReopenMsg -> do
87− newH <- newResource
88− oldH <- atomicModifyIORef' ref (\oldH -> (newH, oldH))
89− hFlush oldH
90− hClose oldH
91− recur
92− recur
93− worker :: IO ()
94− worker = try (bracket ack release go) >>= \case
95− Left (_ :: SomeException) -> do
96− threadDelay 100000
97− -- to not restart the worker function too often
98− worker
99− -- We dont want the worker thread become unavailable because
100− -- of exceptions. E.g. could not create or write the file.
101− Right () -> return ()
102− asyncRet <- async worker
103− return $ FileOwner
104− { foDataQueune = dqueue
105− , foControlQueue = cqueue
106− , foAsync = asyncRet
107− }
108−
109−
110−
111−fileOwnerControl :: FileOwner -> ControlMsg -> IO ()
112−fileOwnerControl fo msg = do
113− atomically $ writeTBQueue (foControlQueue fo) msg
114− when (msg == CloseMsg) $ do
115− -- Wait for worker thread to finish
116− void $ waitCatch $ foAsync fo
117−
118−writeFileOwner :: FileOwner -> BL.ByteString -> IO ()
119−writeFileOwner fo bs = do
120− a <- return $!! bs
121− -- The deepseq here is to be sure that writing thread will not
122− -- calculate thunks and will not get into the blackhole or
123− -- something. Precalculating is the responsibility of the sending
124− -- thread, because there may be several sending threads and only one
125− -- writing.
126− atomically $ writeTBQueue (foDataQueune fo) $!! a
katip/test/Katip/Tests/Scribes/Handle.hs+8−6
@@ -1,5 +1,5 @@
11{-# LANGUAGE OverloadedStrings #-}
2−{-# LANGUAGE RankNTypes #-}
2+{-# LANGUAGE RankNTypes #-}
33module Katip.Tests.Scribes.Handle
44 ( tests
55 ) where
@@ -7,11 +7,12 @@ module Katip.Tests.Scribes.Handle
77-------------------------------------------------------------------------------
88import Control.Monad
99import Data.Aeson
10−import Data.ByteString.Builder as B
10+import qualified Data.ByteString.Char8 as B
1111import qualified Data.ByteString.Lazy as BL
1212import Data.Monoid as M
1313import Data.Text (Text)
1414import qualified Data.Text as T
15+import qualified Data.Text.Encoding as T
1516import qualified Data.Text.Lazy as LT
1617import qualified Data.Text.Lazy.Builder as LT
1718import Data.Time
@@ -244,13 +245,14 @@ writeJsonLog = writeFormattedLog jsonFormat
244245
245246writeFormattedLog :: (forall a . LogItem a => ItemFormatter a) -> (FilePath, Handle) -> IO (BL.ByteString)
246247writeFormattedLog format (path, h) = do
247− mapM_ put genItems
248− mapM_ put genTypedItems
248+ mapM_ (put . formatOne) genItems
249+ mapM_ (put . formatOne) genTypedItems
249250 hClose h
250251 BL.readFile path
251252 where
252− put :: (LogItem a) => Item a -> IO ()
253− put = BL.hPutStr h . toLazyByteString . format False V3
253+ formatOne :: LogItem a => Item a -> Text
254+ formatOne = LT.toStrict . LT.toLazyText . format False V3
255+ put = B.hPutStrLn h . T.encodeUtf8
254256
255257setupTempFile :: IO (FilePath, Handle)
256258setupTempFile = do
stack.yaml+5−6
@@ -1,15 +1,14 @@
1−nix:
2− packages:
3− - zlib
4−resolver: lts-12.26
1+resolver: lts-16.18
52packages:
63 - katip
74 - katip-elasticsearch
85 - katip-datadog
96 - katip-logzio
107extra-deps:
11− - bloodhound-0.16.0.0
12− - unliftio-core-0.1.2.0
8+ # ghc 8.8 support
9+ - github: wireapp/bloodhound
10+ commit: b409f52b518f20a4c20651b5893c31b7b85cb9b1
11+allow-newer: true
1312flags:
1413 katip:
1514 lib-Werror: true