on master help sign in
.gitignore+1
since splitsnapshots
unifiedsplit
@@ -7,3 +7,4 @@ TAGS
7*.hi
7*.hi
8*.dyn_o
8*.dyn_o
9*.dyn_hi
9*.dyn_hi
10+stack.yaml.lock
.travis.yml+8−9
@@ -9,21 +9,19 @@ addons:
9 apt:
9 apt:
10 packages:
10 packages:
11 - libgmp-dev
11 - libgmp-dev
12− - oracle-java8-installer
13
12
14# The different configurations we want to test. You could also do things like
13# The different configurations we want to test. You could also do things like
15# change flags or use --stack-yaml to point to a different file.
14# change flags or use --stack-yaml to point to a different file.
16matrix:
15matrix:
17 include:
16 include:
18− - env: ARGS="--resolver=lts-10" ESVERSION=1.5.2 ESURL=https://download.elastic.co/elasticsearch/elasticsearch ESTESTARGS="--es-version 1"
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"
19− - env: ARGS="--resolver=lts-11" ESVERSION=1.5.2 ESURL=https://download.elastic.co/elasticsearch/elasticsearch ESTESTARGS="--es-version 1"
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"
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
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"
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
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"
23− # nightlies may fail from time to time
21+ # nightlies may fail usually due to lagging dependencies
24 allow_failures:
22 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
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"
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
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"
27
25
28before_install:
26before_install:
29# Download and unpack the stack executable
27# Download and unpack the stack executable
@@ -36,6 +34,7 @@ install:
36 - tar xzf elasticsearch-$ESVERSION.tar.gz
34 - tar xzf elasticsearch-$ESVERSION.tar.gz
37 # set up a repo for snapshot testing. Required in ES >= 1.6
35 # set up a repo for snapshot testing. Required in ES >= 1.6
38 - echo "path.repo = [\"/tmp\"]" >> ./elasticsearch-$ESVERSION/elasticsearch.yml
36 - echo "path.repo = [\"/tmp\"]" >> ./elasticsearch-$ESVERSION/elasticsearch.yml
37+ - java -version
39 - ./elasticsearch-$ESVERSION/bin/elasticsearch &
38 - ./elasticsearch-$ESVERSION/bin/elasticsearch &
40 # Bloodhound seems to take a while to build and can sometimes stall out the build when travis detects no output.
39 # Bloodhound seems to take a while to build and can sometimes stall out the build when travis detects no output.
41
40
katip-datadog/changelog.md+6−1
@@ -1,2 +1,7 @@
1−Unreleased
1+0.2.0.0
2==========
2==========
3+* Remove import of deprecated Network module
4+
5+0.1.0.0
6+==========
7+* Initial release
katip-datadog/katip-datadog.cabal+1−1
@@ -1,5 +1,5 @@
1name: katip-datadog
1name: katip-datadog
2−version: 0.0.1.0
2+version: 0.2.0.0
3synopsis: Datadog scribe for the Katip logging framework
3synopsis: Datadog scribe for the Katip logging framework
4description: See README.md for more details.
4description: See README.md for more details.
5license: BSD3
5license: BSD3
katip-datadog/src/Katip/Scribes/Datadog/TCP.hs+1−1
@@ -33,8 +33,8 @@ import qualified Data.Text.Lazy.Builder as B
33import Data.Time (NominalDiffTime)
33import Data.Time (NominalDiffTime)
34import Katip
34import Katip
35import Katip.Core (LocJs (..))
35import Katip.Core (LocJs (..))
36−import qualified Network as Net
37import qualified Network.Connection as C
36import qualified Network.Connection as C
37+import qualified Network.Socket as Net
38import qualified System.Posix.Types as POSIX
38import qualified System.Posix.Types as POSIX
39-------------------------------------------------------------------------------
39-------------------------------------------------------------------------------
40
40
katip-elasticsearch/bench/Main.hs+3−3
@@ -15,11 +15,11 @@ import qualified Data.HashMap.Strict as HM
15import Data.Proxy (Proxy (..))
15import Data.Proxy (Proxy (..))
16import System.Random
16import System.Random
17import qualified Data.Text as T
17import qualified Data.Text as T
18−import Database.V1.Bloodhound.Types
18+import Database.Bloodhound.Types
19import Numeric
19import Numeric
20-------------------------------------------------------------------------------
20-------------------------------------------------------------------------------
21import Katip.Scribes.ElasticSearch
21import Katip.Scribes.ElasticSearch
22−import Katip.Scribes.ElasticSearch.Internal (ESV1)
22+import Katip.Scribes.ElasticSearch.Internal (ESV5)
23-------------------------------------------------------------------------------
23-------------------------------------------------------------------------------
24
24
25main :: IO ()
25main :: IO ()
@@ -34,7 +34,7 @@ main = do
34mkDocIdBenchmark :: Benchmark
34mkDocIdBenchmark :: Benchmark
35mkDocIdBenchmark = bgroup "mkDocId"
35mkDocIdBenchmark = bgroup "mkDocId"
36 [
36 [
37− bench "mkDocId (randomIO)" $ nfIO (mkDocId (Proxy :: Proxy ESV1))
37+ bench "mkDocId (randomIO)" $ nfIO (mkDocId (Proxy :: Proxy ESV5))
38 , bench "mkDocId' (shared )" $ nfIO mkDocId'
38 , bench "mkDocId' (shared )" $ nfIO mkDocId'
39 ]
39 ]
40
40
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+
10.6.0.0
110.6.0.0
2=======
12=======
3* Update to katip-0.8.0.0 `PermitFunc` convention. To update, for
13* 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
6
6
7-------------------------------------------------------------------------------
7-------------------------------------------------------------------------------
8import Control.Exception
8import Control.Exception
9−import Database.V5.Bloodhound
9+import Database.Bloodhound
10import Network.HTTP.Client
10import Network.HTTP.Client
11-------------------------------------------------------------------------------
11-------------------------------------------------------------------------------
12import Katip
12import Katip
katip-elasticsearch/katip-elasticsearch.cabal+1−4
@@ -1,7 +1,7 @@
1name: katip-elasticsearch
1name: katip-elasticsearch
2synopsis: ElasticSearch scribe for the Katip logging framework.
2synopsis: ElasticSearch scribe for the Katip logging framework.
3description: See README.md for more details.
3description: See README.md for more details.
4−version: 0.6.0.0
4+version: 0.7.0.0
5license: BSD3
5license: BSD3
6license-file: LICENSE
6license-file: LICENSE
7author: Ozgun Ataman, Michael Xavier
7author: Ozgun Ataman, Michael Xavier
@@ -108,7 +108,4 @@ test-suite test
108 , bytestring
108 , bytestring
109 , tagged
109 , tagged
110
110
111− if flag(lib-Werror)
112− ghc-options: -Wall -Werror
113−
114 ghc-options: -threaded -rtsopts
111 ghc-options: -threaded -rtsopts
katip-elasticsearch/src/Katip/Scribes/ElasticSearch.hs+5
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
1-- | Includes a scribe that can be used to log structured, JSON log
2-- | Includes a scribe that can be used to log structured, JSON log
2-- messages to ElasticSearch. These logs can be explored easily using
3-- messages to ElasticSearch. These logs can be explored easily using
3-- <https://www.elastic.co/products/kibana kibana> or your tool of
4-- <https://www.elastic.co/products/kibana kibana> or your tool of
@@ -67,12 +68,16 @@ module Katip.Scribes.ElasticSearch
67 , essIndexSettings
68 , essIndexSettings
68 , essIndexSharding
69 , essIndexSharding
69 , defaultEsScribeCfg
70 , defaultEsScribeCfg
71+#if !MIN_VERSION_bloodhound(0,17,0)
70 , defaultEsScribeCfgV1
72 , defaultEsScribeCfgV1
73+#endif
71 , defaultEsScribeCfgV5
74 , defaultEsScribeCfgV5
72 -- ** Version-Proxied APIS
75 -- ** Version-Proxied APIS
73 -- $versionproxies
76 -- $versionproxies
74 , defaultEsScribeCfg'
77 , defaultEsScribeCfg'
78+#if !MIN_VERSION_bloodhound(0,17,0)
75 , ESV1
79 , ESV1
80+#endif
76 , ESV5
81 , ESV5
77 -- * Utilities
82 -- * Utilities
78 , mkDocId
83 , mkDocId
katip-elasticsearch/src/Katip/Scribes/ElasticSearch/Internal.hs+18−7
@@ -28,7 +28,7 @@ import Control.Retry (RetryPolicy,
28import Data.Aeson
28import Data.Aeson
29import Data.ByteString.Lazy (ByteString)
29import Data.ByteString.Lazy (ByteString)
30import Data.List.NonEmpty (NonEmpty (..))
30import Data.List.NonEmpty (NonEmpty (..))
31−import Data.Monoid ((<>))
31+import Data.Monoid as Monoid
32import Data.Text (Text)
32import Data.Text (Text)
33import qualified Data.Text as T
33import qualified Data.Text as T
34import qualified Data.Text.Encoding as T
34import qualified Data.Text.Encoding as T
@@ -37,8 +37,12 @@ import Data.Time.Calendar.WeekDate
37import Data.Typeable as Typeable
37import Data.Typeable as Typeable
38import Data.UUID
38import Data.UUID
39import qualified Data.UUID.V4 as UUID4
39import qualified Data.UUID.V4 as UUID4
40+#if MIN_VERSION_bloodhound(0,17,0)
41+import qualified Database.Bloodhound as V5
42+#else
40import qualified Database.V1.Bloodhound as V1
43import qualified Database.V1.Bloodhound as V1
41import qualified Database.V5.Bloodhound as V5
44import qualified Database.V5.Bloodhound as V5
45+#endif
42import Network.HTTP.Client
46import Network.HTTP.Client
43import Network.HTTP.Types.Status
47import Network.HTTP.Types.Status
44import Text.Printf (printf)
48import Text.Printf (printf)
@@ -95,7 +99,7 @@ data EsScribeCfg v = EsScribeCfg {
95-- * DailyIndexSharding
99-- * DailyIndexSharding
96defaultEsScribeCfg' :: ESVersion v => proxy v -> EsScribeCfg v
100defaultEsScribeCfg' :: ESVersion v => proxy v -> EsScribeCfg v
97defaultEsScribeCfg' prx = EsScribeCfg {
101defaultEsScribeCfg' prx = EsScribeCfg {
98− essRetryPolicy = exponentialBackoff 25000 <> limitRetries 5
102+ essRetryPolicy = exponentialBackoff 25000 Monoid.<> limitRetries 5
99 , essQueueSize = EsQueueSize 1000
103 , essQueueSize = EsQueueSize 1000
100 , essPoolSize = EsPoolSize 2
104 , essPoolSize = EsPoolSize 2
101 , essAnnotateTypes = False
105 , essAnnotateTypes = False
@@ -104,19 +108,22 @@ defaultEsScribeCfg' prx = EsScribeCfg {
104 }
108 }
105
109
106
110
111+
112+
107-------------------------------------------------------------------------------
113-------------------------------------------------------------------------------
108−-- | Alias of 'defaultEsScribeCfgV1' to minimize API
114+-- | Alias of 'defaultEsScribeCfgV5' to minimize API
109-- breakage. Previous versions of katip-elasticsearch only supported
115-- breakage. Previous versions of katip-elasticsearch only supported
110−-- ES version 1.
116+-- ES version 1 and defaulted to it.
111−defaultEsScribeCfg :: EsScribeCfg ESV1
117+defaultEsScribeCfg :: EsScribeCfg ESV5
112−defaultEsScribeCfg = defaultEsScribeCfgV1
118+defaultEsScribeCfg = defaultEsScribeCfgV5
113
119
114
120
115-------------------------------------------------------------------------------
121-------------------------------------------------------------------------------
122+#if !MIN_VERSION_bloodhound(0,17,0)
116-- | EsScribeCfg that will use ElasticSearch V1
123-- | EsScribeCfg that will use ElasticSearch V1
117defaultEsScribeCfgV1 :: EsScribeCfg ESV1
124defaultEsScribeCfgV1 :: EsScribeCfg ESV1
118defaultEsScribeCfgV1 = defaultEsScribeCfg' (Typeable.Proxy :: Typeable.Proxy ESV1)
125defaultEsScribeCfgV1 = defaultEsScribeCfg' (Typeable.Proxy :: Typeable.Proxy ESV1)
119−
126+#endif
120
127
121-------------------------------------------------------------------------------
128-------------------------------------------------------------------------------
122-- | EsScribeCfg that will use ElasticSearch V5
129-- | EsScribeCfg that will use ElasticSearch V5
@@ -484,7 +491,10 @@ class ESVersion v where
484
491
485
492
486
493
494+#if !MIN_VERSION_bloodhound(0,17,0)
487data ESV1 = ESV1
495data ESV1 = ESV1
496+{-# DEPRECATED ESV1 "ESV1 is deprecated and removed in bloodhound >= 0.17.0" #-}
497+
488
498
489instance ESVersion ESV1 where
499instance ESVersion ESV1 where
490 type BHEnv ESV1 = V1.BHEnv
500 type BHEnv ESV1 = V1.BHEnv
@@ -524,6 +534,7 @@ instance ESVersion ESV1 where
524 [ "type" .= String "string"
534 [ "type" .= String "string"
525 , "index" .= String "analyzed"
535 , "index" .= String "analyzed"
526 ]
536 ]
537+#endif
527
538
528
539
529data ESV5 = ESV5
540data ESV5 = ESV5
katip-elasticsearch/test/Main.hs+23−7
@@ -34,8 +34,12 @@ import Data.Time
34import Data.Time.Calendar.WeekDate
34import Data.Time.Calendar.WeekDate
35import Data.Typeable as Typeable
35import Data.Typeable as Typeable
36import qualified Data.Vector as V
36import qualified Data.Vector as V
37+#if MIN_VERSION_bloodhound(0,17,0)
38+import qualified Database.Bloodhound as V5
39+#else
37import qualified Database.V1.Bloodhound as V1
40import qualified Database.V1.Bloodhound as V1
38import qualified Database.V5.Bloodhound as V5
41import qualified Database.V5.Bloodhound as V5
42+#endif
39import Network.HTTP.Client
43import Network.HTTP.Client
40import Network.HTTP.Types.Status
44import Network.HTTP.Types.Status
41import Test.QuickCheck.Instances ()
45import Test.QuickCheck.Instances ()
@@ -54,8 +58,10 @@ main :: IO ()
54main = defaultMainWithIngredients ings $ askOption $ \vers -> testGroup "katip-elasticsearch"
58main = defaultMainWithIngredients ings $ askOption $ \vers -> testGroup "katip-elasticsearch"
55 [
59 [
56 case vers of
60 case vers of
61+#if !MIN_VERSION_bloodhound(0,17,0)
57− TestV1 -> esTests (Typeable.Proxy :: Typeable.Proxy ESV1)
62+ TestV1 -> esTests (Typeable.Proxy :: Typeable.Proxy ESV1)
63+#endif
58− TestV5 -> esTests (Typeable.Proxy :: Typeable.Proxy ESV5)
64+ TestV5 -> esTests (Typeable.Proxy :: Typeable.Proxy ESV5)
59 , typeAnnotatedTests
65 , typeAnnotatedTests
60 , roundToSundayTests
66 , roundToSundayTests
61 ]
67 ]
@@ -64,18 +70,26 @@ main = defaultMainWithIngredients ings $ askOption $ \vers -> testGroup "katip-e
64
70
65
71
66-------------------------------------------------------------------------------
72-------------------------------------------------------------------------------
67−data TestWithESVersion = TestV1
73+data TestWithESVersion = TestV5
68− | TestV5
74+#if !MIN_VERSION_bloodhound(0,17,0)
75+ | TestV1
76+#endif
69− deriving (Typeable)
77+ deriving (Typeable)
70
78
71
79
72instance IsOption TestWithESVersion where
80instance IsOption TestWithESVersion where
73− defaultValue = TestV1
81+ defaultValue = TestV5
82+#if !MIN_VERSION_bloodhound(0,17,0)
74 parseValue "1" = Just TestV1
83 parseValue "1" = Just TestV1
84+#endif
75 parseValue "5" = Just TestV5
85 parseValue "5" = Just TestV5
76 parseValue _ = Nothing
86 parseValue _ = Nothing
77 optionName = Tagged "es-version"
87 optionName = Tagged "es-version"
88+#if MIN_VERSION_bloodhound(0,17,0)
78− optionHelp = Tagged "Version of ES to test against, either 1 or 5, defaulting to 1."
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
79
93
80
94
81class ESVersion v => TestESVersion v where
95class ESVersion v => TestESVersion v where
@@ -101,6 +115,7 @@ class ESVersion v => TestESVersion v where
101 searchByIndex :: proxy v -> IndexName v -> Search v -> BH v IO (Response ByteString)
115 searchByIndex :: proxy v -> IndexName v -> Search v -> BH v IO (Response ByteString)
102
116
103
117
118+#if !MIN_VERSION_bloodhound(0,17,0)
104instance TestESVersion ESV1 where
119instance TestESVersion ESV1 where
105 type Server ESV1 = V1.Server
120 type Server ESV1 = V1.Server
106 toServer _ = V1.Server
121 toServer _ = V1.Server
@@ -122,6 +137,7 @@ instance TestESVersion ESV1 where
122 refreshIndex _ = V1.refreshIndex
137 refreshIndex _ = V1.refreshIndex
123 withBH _ = V1.withBH
138 withBH _ = V1.withBH
124 searchByIndex _ = V1.searchByIndex
139 searchByIndex _ = V1.searchByIndex
140+#endif
125
141
126
142
127instance TestESVersion ESV5 where
143instance TestESVersion ESV5 where
katip-logzio/changelog.md+8−1
@@ -1,2 +1,9 @@
1−Unreleased
1+0.1.1.0
2+=======
3+* Fixed bug where on scribe close, any items left in the buffer that
4+ hadn't timed out or been flushed already would be dropped rather
5+ than flushed. All users are encouraged to upgrade.
6+
7+0.1.0.0
2==========
8==========
9+* Initial release
katip-logzio/katip-logzio.cabal+2−1
@@ -1,5 +1,5 @@
1name: katip-logzio
1name: katip-logzio
2−version: 0.0.1.0
2+version: 0.1.1.0
3synopsis: Logz.IO scribe for the Katip logging framework
3synopsis: Logz.IO scribe for the Katip logging framework
4description: See README.md for more details.
4description: See README.md for more details.
5license: BSD3
5license: BSD3
@@ -49,6 +49,7 @@ library
49 , text
49 , text
50 , bytestring
50 , bytestring
51 , scientific
51 , scientific
52+ , stm-chans >= 2.0.0
52 hs-source-dirs: src
53 hs-source-dirs: src
53 default-language: Haskell2010
54 default-language: Haskell2010
54 hs-source-dirs: src
55 hs-source-dirs: src
katip-logzio/src/Katip/Scribes/LogzIO/HTTPS.hs+116−148
@@ -1,4 +1,5 @@
1{-# LANGUAGE BangPatterns #-}
1{-# LANGUAGE BangPatterns #-}
2+{-# LANGUAGE GADTs #-}
2{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3{-# LANGUAGE OverloadedStrings #-}
4{-# LANGUAGE OverloadedStrings #-}
4{-# LANGUAGE RankNTypes #-}
5{-# LANGUAGE RankNTypes #-}
@@ -38,33 +39,34 @@ module Katip.Scribes.LogzIO.HTTPS
38
39
39-------------------------------------------------------------------------------
40-------------------------------------------------------------------------------
40import Control.Applicative
41import Control.Applicative
41−import qualified Control.Concurrent.Async as Async
42+import qualified Control.Concurrent.Async as Async
42−import qualified Control.Concurrent.STM as STM
43+import qualified Control.Concurrent.STM as STM
44+import qualified Control.Concurrent.STM.TBMQueue as STM
43−import qualified Control.Error as E
45+import qualified Control.Error as E
44−import qualified Control.Exception.Safe as EX
46+import qualified Control.Exception.Safe as EX
47+import Control.Monad
45−import qualified Control.Retry as Retry
48+import qualified Control.Retry as Retry
46−import qualified Data.Aeson as A
49+import qualified Data.Aeson as A
47−import qualified Data.ByteString.Builder as BB
50+import qualified Data.ByteString.Builder as BB
48−import qualified Data.ByteString.Lazy as LBS
51+import qualified Data.ByteString.Lazy as LBS
49−import qualified Data.ByteString.Lazy.Char8 as LBS8
52+import qualified Data.ByteString.Lazy.Char8 as LBS8
50−import qualified Data.HashMap.Strict as HM
53+import qualified Data.HashMap.Strict as HM
51import Data.Int
54import Data.Int
52−import qualified Data.Scientific as Scientific
55+import qualified Data.Scientific as Scientific
53−import Data.Semigroup as Semigroup
56+import Data.Semigroup as Semigroup
54−import Data.String (IsString)
57+import Data.String (IsString)
55−import qualified Data.Text as T
58+import qualified Data.Text as T
56−import qualified Data.Text.Encoding as TE
59+import qualified Data.Text.Encoding as TE
57−import qualified Data.Text.Lazy as TL
60+import qualified Data.Text.Lazy as TL
58−import qualified Data.Text.Lazy.Builder as TB
61+import qualified Data.Text.Lazy.Builder as TB
59−import qualified Data.Time as Time
62+import qualified Data.Time as Time
60−import qualified Katip as K
63+import qualified Katip as K
61−import Katip.Core (LocJs (..))
64+import Katip.Core (LocJs (..))
62−import qualified Network.HTTP.Client as HTTP
65+import qualified Network.HTTP.Client as HTTP
63−import qualified Network.HTTP.Client.TLS as HTTPS
66+import qualified Network.HTTP.Client.TLS as HTTPS
64−import qualified Network.HTTP.Types as HTypes
67+import qualified Network.HTTP.Types as HTypes
65−import qualified System.Posix.Types as POSIX
68+import qualified System.Posix.Types as POSIX
66−import qualified URI.ByteString as URIBS
69+import qualified URI.ByteString as URIBS
67−-------------------------------------------------------------------------------
68-------------------------------------------------------------------------------
70-------------------------------------------------------------------------------
69
71
70
72
@@ -207,132 +209,115 @@ mkLogzIOScribe
207 -> K.Verbosity
209 -> K.Verbosity
208 -> IO K.Scribe
210 -> IO K.Scribe
209mkLogzIOScribe config permitItem verbosity = do
211mkLogzIOScribe config permitItem verbosity = do
210− -- Accumulating buffer for each item
212+ -- This size is actually somewhat arbitrary. We're just making sure
211− bufferState <- STM.newTVarIO (mempty :: BulkBuffer)
213+ -- it isn't infinite so we don't consume the whole backlog right
212− -- Single-slot TMVar when something is ready to write. Katip buffers
214+ -- away and take up lots of memory.. Katip above us does bounded
213− -- for us upstream so we can simplify shutdown and flush guarantees
215+ -- buffering and load-shedding when there's too much of a
214− -- by synchronously writing when we need to.
216+ -- backlog. Our writes are blocking to apply backpressure up to
215− readyMVar <- STM.newEmptyTMVarIO :: IO (STM.TMVar BulkBuffer)
217+ -- katip. This value just holds onto values temporarily while we
216−
218+ -- concatenate them into a buffer.
217− -- We create a TVar that is set to ShutDown when its time to stop
219+ ingestionQueue <- STM.newTBMQueueIO (itemBufferSize * 10)
218− killSwitch <- STM.newTVarIO Continue
220+
219−
221+ let newTimer = STM.registerDelay itemBufferTimeoutMicros
220− -- Create a mutable ref to whether the timer has expired. This lets
221− -- us replace the timer when its time to start timing again. We
222− -- reset the timer __after__ a write goes out, not as soon as it expires
223− timerRef <- STM.newTVarIO =<< STM.registerDelay itemBufferTimeoutMicros
222+ timerRef <- STM.newTVarIO =<< newTimer
224
223
225 -- Set up a connection manager for requests
224 -- Set up a connection manager for requests
226 mgr <- case scheme of
225 mgr <- case scheme of
227 HTTPS -> HTTPS.newTlsManager
226 HTTPS -> HTTPS.newTlsManager
228 HTTP -> HTTP.newManager HTTP.defaultManagerSettings
227 HTTP -> HTTP.newManager HTTP.defaultManagerSettings
229
228
230− -- In STM: resolve an action with the buffers
229+ -- An STM transaction that will return true when writes are stopped
231− let processLogAction :: LogAction BulkBuffer -> STM.STM ()
230+ -- and backlog is emptied.
232− processLogAction logAction = case logAction of
231+ let workExhausted :: STM.STM Bool
233− -- No write needed right now
232+ workExhausted = (&&)
234− Buffered !newBuffer -> STM.writeTVar bufferState newBuffer
233+ <$> STM.isClosedTBMQueue ingestionQueue
235− -- Time to flush and put excess in the next buffer
234+ <*> STM.isEmptyTBMQueue ingestionQueue
236− FlushNow !toFlush !newBuffer -> do
235+ -- Block until there's no more work
237− STM.writeTVar bufferState newBuffer
236+ let waitWorkExhausted :: STM.STM ()
238− STM.putTMVar readyMVar toFlush
237+ waitWorkExhausted = STM.check =<< workExhausted
239−
238+ let pop :: STM.STM (Tick AnyLogItem)
240− -- Recompute the new buffer state from a new log item and take action
239+ pop = maybe WorkExhausted NewItem <$> STM.readTBMQueue ingestionQueue
241− let push :: (K.LogItem a) => K.Item a -> STM.STM ()
240+
242− push !logItem = do
241+ let timeExpired :: STM.STM (Tick a)
243− !curBuffer <- STM.readTVar bufferState
242+ timeExpired = do
244− processLogAction (bufferItem itemBufferSize verbosity logItem curBuffer)
243+ isExpired <- STM.readTVar =<< STM.readTVar timerRef
245−
244+ STM.check isExpired
246−
245+ pure TimeExpired
247− -- A transaction that retries until its time to shutdown
246+
248− let waitShutdown :: STM.STM ()
247+ -- Circular transaction that checks for completion of work, time
249− waitShutdown = do
248+ -- expiration, or new events.
250− killStatus <- STM.readTVar killSwitch
249+ let nextTick :: STM.STM (Tick AnyLogItem)
251− STM.check (killStatus == ShutDown)
250+ nextTick =
252−
251+ timeExpired <|>
253− -- Retry transaction until timer has expired. When it does, take action on the buffer.
252+ pop <|>
253+ (WorkExhausted <$ waitWorkExhausted)
254+
255+ -- Blocking push. This applies backpressure upstream to katip, which does its own buffering
254− let waitTimer :: STM.STM ()
256+ let push :: AnyLogItem -> STM.STM ()
255− waitTimer = do
257+ push = void . STM.writeTBMQueue ingestionQueue
256− -- get the timer we'll be using
258+
257− timer <- STM.readTVar timerRef
259+ let sealQueue = STM.atomically (STM.closeTBMQueue ingestionQueue)
258− -- do not proceed until its ready
260+
259− timerExpired <- STM.readTVar timer
261+ -- Replace the timer with a new one
260− STM.check timerExpired
262+ let resetTimer = STM.atomically . STM.writeTVar timerRef =<< newTimer
261− -- do not wake again until this message is out the door
263+
262− STM.writeTVar timer False
264+ -- Send the buffer and then reset the timer
263− -- we waited long enough, grab the current buffer
265+ let flush curBuffer = do
264− !curBuffer <- STM.readTVar bufferState
266+ res <- flushBuffer config mgr curBuffer
265− -- and tell it to flush right now
266− processLogAction (forceFlush curBuffer)
267−
268− -- run the timer in a loop until its time to shut down
269− let timedFlushLoop :: IO ()
270− timedFlushLoop = do
271− res <- STM.atomically $
272− raceAlt
273− waitShutdown
274− waitTimer
275 case res of
267 case res of
276− Left () -> pure () -- exit loop
268+ Left e -> onErrorSafe e
277− Right () -> timedFlushLoop -- wait for another timer or shutdown
269+ Right () -> pure ()
278−
270+ resetTimer
279− timedFlusher <- Async.async timedFlushLoop
271+
280−
281− -- flush the buffer until its time to shutdown and we're out of items to log
282− let flushLoop :: IO ()
272+ let flushLoop :: BulkBuffer -> IO ()
283− flushLoop = do
273+ flushLoop curBuffer = do
284− -- hold until something comes in to flush or we're told to stop. If we're told to stop but get a log first, we'll catch it on the next loop
285− readyBufferOrDie <- STM.atomically $
274+ tick <- STM.atomically nextTick
286− raceAlt
275+ case tick of
287− (STM.takeTMVar readyMVar)
276+ WorkExhausted -> do
288− waitShutdown
277+ flush curBuffer -- flush what you've got
289− case readyBufferOrDie of
278+ pure () -- stop looping
290− Right () -> pure () -- we caught shutdown before any new data arrived
279+ TimeExpired -> do
291− -- There's some logs to write
280+ flush curBuffer
292− Left readyBuffer -> do
281+ flushLoop mempty
293− -- flush in IO
282+ NewItem (AnyLogItem item) -> do
294− res <- flushBuffer config mgr readyBuffer
283+ case bufferItem (logzIOScribeConfiguration_bufferItems config) verbosity item curBuffer of
295− case res of
284+ Buffered newBuffer -> flushLoop newBuffer
296− Left ex -> onErrorSafe ex
285+ FlushNow flushThis newBuffer -> do
297− Right () -> pure ()
286+ flush flushThis
298− -- reset the timeout before the next flush on each write
287+ flushLoop newBuffer
299− !newTimer <- STM.registerDelay itemBufferTimeoutMicros
288+
300− STM.atomically $ do
301− STM.writeTVar timerRef newTimer
302− -- start over
303− flushLoop
304− flusher <- Async.async flushLoop
289+ flushThread <- Async.async (flushLoop mempty)
305−
290+
306− -- Blocking call which sends a poison pill to the workers and waits
291+ let close = do
307− -- for them to exit, swallowing exceptions. This follows the
292+ sealQueue
308− -- semantics that when katip calls the finalizer, no more log
309− -- entries will be sent.
310− let shutdown :: IO ()
311− shutdown = do
312− -- tell workers this is the last loop
313− STM.atomically (STM.writeTVar killSwitch ShutDown)
314− -- wait for workers to finish
315− _ <- Async.waitCatch timedFlusher
293+ _ <- Async.waitCatch flushThread
316− _ <- Async.waitCatch flusher
317− -- stop blocking
318 pure ()
294 pure ()
319
295
320−
321 pure $ K.Scribe
296 pure $ K.Scribe
322− { K.liPush = STM.atomically . push
297+ { K.liPush = STM.atomically . push . AnyLogItem
323− , K.scribeFinalizer = shutdown
298+ , K.scribeFinalizer = close
324 , K.scribePermitItem = permitItem
299 , K.scribePermitItem = permitItem
325 }
300 }
326 where
301 where
327 itemBufferSize = logzIOScribeConfiguration_bufferItems config
302 itemBufferSize = logzIOScribeConfiguration_bufferItems config
328 itemBufferTimeoutMicros = ndtToMicros (logzIOScribeConfiguration_bufferTimeout config)
303 itemBufferTimeoutMicros = ndtToMicros (logzIOScribeConfiguration_bufferTimeout config)
329 scheme = logzIOScribeConfiguration_scheme config
304 scheme = logzIOScribeConfiguration_scheme config
330− -- should this be async?
331 onErrorSafe ex = do
305 onErrorSafe ex = do
332 _ <- EX.tryAny (logzIOScribeConfiguration_onError config ex)
306 _ <- EX.tryAny (logzIOScribeConfiguration_onError config ex)
333 pure ()
307 pure ()
334
308
335
309
310+data AnyLogItem where
311+ AnyLogItem :: K.LogItem a => K.Item a -> AnyLogItem
312+
313+
314+-------------------------------------------------------------------------------
315+data Tick a =
316+ TimeExpired
317+ | NewItem !a
318+ | WorkExhausted
319+
320+
336-------------------------------------------------------------------------------
321-------------------------------------------------------------------------------
337-- Match the native resolution of NominalDiffTime, which is excessive
322-- Match the native resolution of NominalDiffTime, which is excessive
338-- for our needs
323-- for our needs
@@ -350,23 +335,6 @@ ndtToMicros t = round (((fromIntegral (ndtPicos t)) :: Double) / picosInMicro)
350 picosInMicro = 10 ^ (3 :: Int)
335 picosInMicro = 10 ^ (3 :: Int)
351
336
352
337
353−-------------------------------------------------------------------------------
354−-- | An internal mode flag used to shut down worker
355−-- threads. Internally, we assume htere is no going back from
356−-- ShutDown.
357−data KillSwitch =
358− Continue
359− | ShutDown
360− deriving (Eq)
361−
362−
363−-------------------------------------------------------------------------------
364−-- | When applied to STM, it will try the left side first and if that
365−-- retries, the right, and if that retries, start from the beginning.
366−raceAlt :: (Alternative m) => m a -> m b -> m (Either a b)
367−raceAlt a b = (Left <$> a) <|> (Right <$> b)
368−
369−
370-------------------------------------------------------------------------------
338-------------------------------------------------------------------------------
371data LoggingError =
339data LoggingError =
372 URIError HTTP.HttpException
340 URIError HTTP.HttpException
katip-logzio/test/Katip/Tests/Scribes/LogzIO/HTTPS.hs+10−1
@@ -108,6 +108,15 @@ scribeTests = withLock $ \mkSem -> testGroup "scribe"
108 case loggingError of
108 case loggingError of
109 BadToken -> pure ()
109 BadToken -> pure ()
110 _ -> assertFailure ("Expected BadToken error but got " <> show loggingError)
110 _ -> assertFailure ("Expected BadToken error but got " <> show loggingError)
111+ , testCase "flushes all queued logs on close" $ do
112+ sem <- mkSem
113+ withServer sem $ \receivedMessages -> do
114+ withScribe (\cfg -> cfg { logzIOScribeConfiguration_bufferItems = 100, logzIOScribeConfiguration_bufferTimeout = 100}) $ \scribe -> do
115+ (liPush scribe) (genericLog "message 1")
116+ (liPush scribe) (genericLog "message 2")
117+ messages <- atomically (flushTQueue receivedMessages)
118+ let allLogs = receivedLog_message <$> mconcat (requestLog_logs <$> messages)
119+ allLogs @?= ["message 1", "message 2"]
111 ]
120 ]
112 where
121 where
113 second = 1000000
122 second = 1000000
@@ -231,7 +240,7 @@ bufferItemTests = testGroup "bufferItem"
231 let logAction = bufferItem' maxBound maxBound maxItems verbosity item bulkBuffer
240 let logAction = bufferItem' maxBound maxBound maxItems verbosity item bulkBuffer
232 case logAction of
241 case logAction of
233 FlushNow _ _ -> pure ()
242 FlushNow _ _ -> pure ()
234− Buffered _ -> fail "Expected a FlushNow but got a Buffered"
243+ Buffered _ -> fail "Expected a FlushNow but got a Buffered"
235 ]
244 ]
236 where
245 where
237 assertFlushNow (FlushNow _ _) = pure ()
246 assertFlushNow (FlushNow _ _) = pure ()
katip/README.md+1−1
@@ -16,7 +16,7 @@ Kâtip (pronounced kah-tip) is the Turkish word for scribe.
16 add context that will be automatically merged in with existing log
16 add context that will be automatically merged in with existing log
17 context.
17 context.
18
18
19−* *Easy to Integration:* Katip was designed to be easily integrated
19+* *Easy Integration:* Katip was designed to be easily integrated
20 into existing monads. By using typeclasses for logging facilities,
20 into existing monads. By using typeclasses for logging facilities,
21 individual subsystems and even libraries can easily add their own
21 individual subsystems and even libraries can easily add their own
22 namespacing and context without having any knowledge of their
22 namespacing and context without having any knowledge of their
katip/changelog.md+21
@@ -1,3 +1,24 @@
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+
14+0.8.2.0
15+=======
16+* Add `MonadFail` instances for `base` >= 4.9.0.0 [Koray Al](https://github.com/korayal)
17+
18+0.8.1.0
19+=======
20+* Export `logLoc`. Credit to [Brian McKenna](https://github.com/puffnfresh)
21+
10.8.0.0
220.8.0.0
2=======
23=======
3* **Breaking change**: switch from severity based log level filtering to
24* **Breaking change**: switch from severity based log level filtering to
katip/katip.cabal+2−2
@@ -1,5 +1,5 @@
1name: katip
1name: katip
2−version: 0.8.0.0
2+version: 0.8.5.0
3synopsis: A structured logging framework.
3synopsis: A structured logging framework.
4description:
4description:
5 Katip is a structured logging framework. See README.md for more details.
5 Katip is a structured logging framework. See README.md for more details.
@@ -87,7 +87,7 @@ library
87 if flag(lib-Werror)
87 if flag(lib-Werror)
88 ghc-options: -Werror
88 ghc-options: -Werror
89 if os(windows)
89 if os(windows)
90− build-depends: Win32 >=2.3 && <2.6
90+ build-depends: Win32 >=2.3 && <2.9
91 exposed-modules: Katip.Compat
91 exposed-modules: Katip.Compat
92 else
92 else
93 build-depends: unix >= 2.5 && <2.8
93 build-depends: unix >= 2.5 && <2.8
katip/src/Katip.hs+3−1
@@ -44,7 +44,7 @@
44--
44--
45-- newtype App m a = App {
45-- newtype App m a = App {
46-- unApp :: ReaderT Config m a
46-- unApp :: ReaderT Config m a
47−-- } deriving (Functor, Applicative, Monad) -- more instances as needed
47+-- } deriving (Functor, Applicative, Monad, MonadIO, MonadReader Config) -- these are necessary
48--
48--
49--
49--
50-- -- These instances get even easier with lenses!
50-- -- These instances get even easier with lenses!
@@ -159,7 +159,9 @@ module Katip
159 , logF
159 , logF
160 , logMsg
160 , logMsg
161 , logT
161 , logT
162+ , logLoc
162 , logItem
163 , logItem
164+ , logKatipItem
163 , logException
165 , logException
164 -- ** 'KatipContext': Logging With Context
166 -- ** 'KatipContext': Logging With Context
165 -- $katipcontextlogging
167 -- $katipcontextlogging
katip/src/Katip/Core.hs+45−19
@@ -31,6 +31,9 @@ import qualified Control.Concurrent.STM.TBQueue as BQ
31import Control.Exception.Safe
31import Control.Exception.Safe
32import Control.Monad (unless, void, when)
32import Control.Monad (unless, void, when)
33import Control.Monad.Base
33import Control.Monad.Base
34+#if MIN_VERSION_base(4, 9, 0)
35+import qualified Control.Monad.Fail as MF
36+#endif
34import Control.Monad.IO.Class
37import Control.Monad.IO.Class
35import Control.Monad.IO.Unlift
38import Control.Monad.IO.Unlift
36import Control.Monad.Trans.Class
39import Control.Monad.Trans.Class
@@ -41,7 +44,8 @@ import Control.Monad.Trans.Either
41import Control.Monad.Trans.Except
44import Control.Monad.Trans.Except
42import Control.Monad.Trans.Maybe
45import Control.Monad.Trans.Maybe
43import Control.Monad.Trans.Reader
46import Control.Monad.Trans.Reader
44−import Control.Monad.Trans.Resource (ResourceT, transResourceT)
47+import Control.Monad.Trans.Resource (MonadResource, ResourceT,
48+ transResourceT)
45import Control.Monad.Trans.RWS.Lazy (RWST, mapRWST)
49import Control.Monad.Trans.RWS.Lazy (RWST, mapRWST)
46import qualified Control.Monad.Trans.RWS.Strict as Strict (RWST, mapRWST)
50import qualified Control.Monad.Trans.RWS.Strict as Strict (RWST, mapRWST)
47import Control.Monad.Trans.State.Lazy (StateT, mapStateT)
51import Control.Monad.Trans.State.Lazy (StateT, mapStateT)
@@ -661,7 +665,7 @@ makeLenses ''LogEnv
661
665
662
666
663-------------------------------------------------------------------------------
667-------------------------------------------------------------------------------
664−-- | Create a reasonable default InitLogEnv. Uses an 'AutoUdate' which
668+-- | Create a reasonable default InitLogEnv. Uses an 'AutoUpdate' which
665-- updates the timer every 1ms. If you need even more timestamp
669-- updates the timer every 1ms. If you need even more timestamp
666-- precision at the cost of performance, consider setting
670-- precision at the cost of performance, consider setting
667-- '_logEnvTimer' with 'getCurrentTime'.
671-- '_logEnvTimer' with 'getCurrentTime'.
@@ -876,7 +880,8 @@ instance (Katip m) => Katip (ResourceT m) where
876-- opposed to implementing 'Katip' for your monad.
880-- opposed to implementing 'Katip' for your monad.
877newtype KatipT m a = KatipT { unKatipT :: ReaderT LogEnv m a }
881newtype KatipT m a = KatipT { unKatipT :: ReaderT LogEnv m a }
878 deriving ( Functor, Applicative, Monad, MonadIO
882 deriving ( Functor, Applicative, Monad, MonadIO
879− , MonadMask, MonadCatch, MonadThrow, MonadTrans, MonadBase b)
883+ , MonadMask, MonadCatch, MonadThrow, MonadResource, MonadTrans
884+ , MonadBase b)
880
885
881
886
882instance MonadIO m => Katip (KatipT m) where
887instance MonadIO m => Katip (KatipT m) where
@@ -898,9 +903,20 @@ instance (MonadBaseControl b m) => MonadBaseControl b (KatipT m) where
898 restoreM = defaultRestoreM
903 restoreM = defaultRestoreM
899
904
900instance MonadUnliftIO m => MonadUnliftIO (KatipT m) where
905instance 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
901 askUnliftIO = KatipT $
910 askUnliftIO = KatipT $
902− withUnliftIO $ \u ->
911+ withUnliftIO $ \u ->
903− pure (UnliftIO (unliftIO u . unKatipT))
912+ pure (UnliftIO (unliftIO u . unKatipT))
913+#endif
914+
915+#if MIN_VERSION_base(4, 9, 0)
916+instance MF.MonadFail m => MF.MonadFail (KatipT m) where
917+ fail msg = lift (MF.fail msg)
918+ {-# INLINE fail #-}
919+#endif
904
920
905-------------------------------------------------------------------------------
921-------------------------------------------------------------------------------
906-- | Execute 'KatipT' on a log env.
922-- | Execute 'KatipT' on a log env.
@@ -932,19 +948,29 @@ logItem
932 -> m ()
948 -> m ()
933logItem a ns loc sev msg = do
949logItem a ns loc sev msg = do
934 LogEnv{..} <- getLogEnv
950 LogEnv{..} <- getLogEnv
935− liftIO $ do
951+ logKatipItem =<< liftIO
936− item <- Item
937− <$> pure _logEnvApp
952+ (Item <$> pure _logEnvApp
938− <*> pure _logEnvEnv
953+ <*> pure _logEnvEnv
939− <*> pure sev
954+ <*> pure sev
940− <*> (mkThreadIdText <$> myThreadId)
955+ <*> (mkThreadIdText <$> myThreadId)
941− <*> pure _logEnvHost
956+ <*> pure _logEnvHost
942− <*> pure _logEnvPid
957+ <*> pure _logEnvPid
943− <*> pure a
958+ <*> pure a
944− <*> pure msg
959+ <*> pure msg
945− <*> _logEnvTimer
960+ <*> _logEnvTimer
946− <*> pure (_logEnvApp <> ns)
961+ <*> pure (_logEnvApp <> ns)
947− <*> pure loc
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 $
948 FT.forM_ (M.elems _logEnvScribes) $ \ ScribeHandle {..} -> do
974 FT.forM_ (M.elems _logEnvScribes) $ \ ScribeHandle {..} -> do
949 whenM (scribePermitItem shScribe item) $
975 whenM (scribePermitItem shScribe item) $
950 void $ atomically (tryWriteTBQueue shChan (NewItem item))
976 void $ atomically (tryWriteTBQueue shChan (NewItem item))
@@ -993,7 +1019,7 @@ logException
993logException a ns sev action = action `catchAny` \e -> f e >> throwM e
1019logException a ns sev action = action `catchAny` \e -> f e >> throwM e
994 where
1020 where
995 f e = logF a ns sev (msg e)
1021 f e = logF a ns sev (msg e)
996− msg e = ls (T.pack "An exception has occured: ") <> showLS e
1022+ msg e = ls (T.pack "An exception has occurred: ") <> showLS e
997
1023
998
1024
999-------------------------------------------------------------------------------
1025-------------------------------------------------------------------------------
katip/src/Katip/Monadic.hs+28−6
@@ -44,6 +44,9 @@ import Control.Applicative
44import Control.Exception.Safe
44import Control.Exception.Safe
45import Control.Monad.Base
45import Control.Monad.Base
46import Control.Monad.Error.Class
46import Control.Monad.Error.Class
47+#if MIN_VERSION_base(4, 9, 0)
48+import qualified Control.Monad.Fail as MF
49+#endif
47import Control.Monad.IO.Class
50import Control.Monad.IO.Class
48import Control.Monad.IO.Unlift
51import Control.Monad.IO.Unlift
49import Control.Monad.Reader
52import Control.Monad.Reader
@@ -55,7 +58,8 @@ import Control.Monad.Trans.Either (EitherT, mapEitherT)
55import Control.Monad.Trans.Except (ExceptT, mapExceptT)
58import Control.Monad.Trans.Except (ExceptT, mapExceptT)
56import Control.Monad.Trans.Identity (IdentityT, mapIdentityT)
59import Control.Monad.Trans.Identity (IdentityT, mapIdentityT)
57import Control.Monad.Trans.Maybe (MaybeT, mapMaybeT)
60import Control.Monad.Trans.Maybe (MaybeT, mapMaybeT)
58−import Control.Monad.Trans.Resource (ResourceT, transResourceT)
61+import Control.Monad.Trans.Resource (MonadResource,
62+ ResourceT, transResourceT)
59import Control.Monad.Trans.RWS (RWST, mapRWST)
63import Control.Monad.Trans.RWS (RWST, mapRWST)
60import qualified Control.Monad.Trans.RWS.Strict as Strict (RWST, mapRWST)
64import qualified Control.Monad.Trans.RWS.Strict as Strict (RWST, mapRWST)
61import qualified Control.Monad.Trans.State.Strict as Strict (StateT, mapStateT)
65import qualified Control.Monad.Trans.State.Strict as Strict (StateT, mapStateT)
@@ -312,7 +316,7 @@ logExceptionM
312logExceptionM action sev = action `catchAny` \e -> f e >> throwM e
316logExceptionM action sev = action `catchAny` \e -> f e >> throwM e
313 where
317 where
314 f e = logFM sev (msg e)
318 f e = logFM sev (msg e)
315− msg e = ls ("An exception has occured: " :: Text) Semi.<> showLS e
319+ msg e = ls ("An exception has occurred: " :: Text) Semi.<> showLS e
316
320
317
321
318-------------------------------------------------------------------------------
322-------------------------------------------------------------------------------
@@ -346,6 +350,7 @@ newtype KatipContextT m a = KatipContextT {
346 , MonadWriter w
350 , MonadWriter w
347 , MonadError e
351 , MonadError e
348 , MonadPlus
352 , MonadPlus
353+ , MonadResource
349 , Alternative
354 , Alternative
350 , MonadFix
355 , MonadFix
351 , MonadTrans
356 , MonadTrans
@@ -392,10 +397,21 @@ instance (MonadIO m) => KatipContext (KatipContextT m) where
392 localKatipNamespace f (KatipContextT m) = KatipContextT $ local (\s -> s { ltsNamespace = f (ltsNamespace s)}) m
397 localKatipNamespace f (KatipContextT m) = KatipContextT $ local (\s -> s { ltsNamespace = f (ltsNamespace s)}) m
393
398
394instance MonadUnliftIO m => MonadUnliftIO (KatipContextT m) where
399instance 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
395 askUnliftIO = KatipContextT $
404 askUnliftIO = KatipContextT $
396− withUnliftIO $ \u ->
405+ withUnliftIO $ \u ->
397− pure (UnliftIO (unliftIO u . unKatipContextT))
406+ pure (UnliftIO (unliftIO u . unKatipContextT))
407+#endif
408+
398
409
410+#if MIN_VERSION_base(4, 9, 0)
411+instance MF.MonadFail m => MF.MonadFail (KatipContextT m) where
412+ fail msg = lift (MF.fail msg)
413+ {-# INLINE fail #-}
414+#endif
399
415
400-------------------------------------------------------------------------------
416-------------------------------------------------------------------------------
401runKatipContextT :: (LogItem c) => LogEnv -> c -> Namespace -> KatipContextT m a -> m a
417runKatipContextT :: (LogItem c) => LogEnv -> c -> Namespace -> KatipContextT m a -> m a
@@ -474,9 +490,15 @@ instance MonadBaseControl b m => MonadBaseControl b (NoLoggingT m) where
474 restoreM = NoLoggingT . restoreM
490 restoreM = NoLoggingT . restoreM
475
491
476instance MonadUnliftIO m => MonadUnliftIO (NoLoggingT m) where
492instance 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
477 askUnliftIO = NoLoggingT $
497 askUnliftIO = NoLoggingT $
478− withUnliftIO $ \u ->
498+ withUnliftIO $ \u ->
479− pure (UnliftIO (unliftIO u . runNoLoggingT))
499+ pure (UnliftIO (unliftIO u . runNoLoggingT))
500+#endif
501+
480
502
481instance MonadIO m => Katip (NoLoggingT m) where
503instance MonadIO m => Katip (NoLoggingT m) where
482 getLogEnv = liftIO (initLogEnv "NoLoggingT" "no-logging")
504 getLogEnv = liftIO (initLogEnv "NoLoggingT" "no-logging")
stack.yaml+5−3
@@ -1,12 +1,14 @@
1−resolver: lts-12.26
1+resolver: lts-16.18
2packages:
2packages:
3 - katip
3 - katip
4 - katip-elasticsearch
4 - katip-elasticsearch
5 - katip-datadog
5 - katip-datadog
6 - katip-logzio
6 - katip-logzio
7extra-deps:
7extra-deps:
8+ # ghc 8.8 support
8− - bloodhound-0.16.0.0
9+ - github: wireapp/bloodhound
9− - unliftio-core-0.1.2.0
10+ commit: b409f52b518f20a4c20651b5893c31b7b85cb9b1
11+allow-newer: true
10flags:
12flags:
11 katip:
13 katip:
12 lib-Werror: true
14 lib-Werror: true