on 3ffac14 help sign in
.gitignore−1
since splitsnapshots
unifiedsplit
@@ -7,4 +7,3 @@ TAGS
7*.hi
7*.hi
8*.dyn_o
8*.dyn_o
9*.dyn_hi
9*.dyn_hi
10−stack.yaml.lock
.travis.yml+11−8
@@ -9,19 +9,23 @@ addons:
9 apt:
9 apt:
10 packages:
10 packages:
11 - libgmp-dev
11 - libgmp-dev
12+ - oracle-java8-installer
12
13
13# The different configurations we want to test. You could also do things like
14# The different configurations we want to test. You could also do things like
14# change flags or use --stack-yaml to point to a different file.
15# change flags or use --stack-yaml to point to a different file.
15matrix:
16matrix:
16 include:
17 include:
18+ - env: ARGS="--resolver=lts-8" 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-9" ESVERSION=1.5.2 ESURL=https://download.elastic.co/elasticsearch/elasticsearch ESTESTARGS="--es-version 1"
20+ - env: ARGS="--resolver=lts-10" 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"
21+ - env: ARGS="--resolver=lts-11" ESVERSION=1.5.2 ESURL=https://download.elastic.co/elasticsearch/elasticsearch ESTESTARGS="--es-version 1"
22+ - env: ARGS="--resolver=lts-12" ESVERSION=1.5.2 ESURL=https://download.elastic.co/elasticsearch/elasticsearch ESTESTARGS="--es-version 1"
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"
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" 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"
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" JAVA_HOME=/usr/lib/jvm/java-8-oracle
21− # nightlies may fail usually due to lagging dependencies
25+ # nightlies may fail from time to time
22 allow_failures:
26 allow_failures:
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"
27+ - 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
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"
28+ - 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
25
29
26before_install:
30before_install:
27# Download and unpack the stack executable
31# Download and unpack the stack executable
@@ -34,7 +38,6 @@ install:
34 - tar xzf elasticsearch-$ESVERSION.tar.gz
38 - tar xzf elasticsearch-$ESVERSION.tar.gz
35 # set up a repo for snapshot testing. Required in ES >= 1.6
39 # set up a repo for snapshot testing. Required in ES >= 1.6
36 - echo "path.repo = [\"/tmp\"]" >> ./elasticsearch-$ESVERSION/elasticsearch.yml
40 - echo "path.repo = [\"/tmp\"]" >> ./elasticsearch-$ESVERSION/elasticsearch.yml
37− - java -version
38 - ./elasticsearch-$ESVERSION/bin/elasticsearch &
41 - ./elasticsearch-$ESVERSION/bin/elasticsearch &
39 # Bloodhound seems to take a while to build and can sometimes stall out the build when travis detects no output.
42 # Bloodhound seems to take a while to build and can sometimes stall out the build when travis detects no output.
40
43
katip-datadog/README.md+5−3
@@ -1,6 +1,8 @@
1# Katip Datadog [![Build Status](https://travis-ci.org/Soostone/katip.svg?branch=master)](https://travis-ci.org/Soostone/katip)
1# Katip Datadog [![Build Status](https://travis-ci.org/Soostone/katip.svg?branch=master)](https://travis-ci.org/Soostone/katip)
2
2
3katip-datadog is a scribe for the Katip logging framework that sends
3katip-datadog is a scribe for the Katip logging framework that sends
4−structured logs to the Datadog logging service. It supports both
4+structured logs to the Datadog logging service.
5−directly sending to the ingestion API and through a locally installed
5+
6−datadog agent.
6+## Warning
7+
8+This is an unreleased library and is not yet production-ready.
katip-datadog/changelog.md+1−6
@@ -1,7 +1,2 @@
1−0.2.0.0
1+Unreleased
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−2
@@ -1,6 +1,5 @@
1name: katip-datadog
1name: katip-datadog
2−version: 0.2.0.0
2+version: 0.0.1.0
3−synopsis: Datadog scribe for the Katip logging framework
4description: See README.md for more details.
3description: See README.md for more details.
5license: BSD3
4license: BSD3
6license-file: LICENSE
5license-file: LICENSE
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
36import qualified Network.Connection as C
37import 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.Bloodhound.Types
18+import Database.V1.Bloodhound.Types
19import Numeric
19import Numeric
20-------------------------------------------------------------------------------
20-------------------------------------------------------------------------------
21import Katip.Scribes.ElasticSearch
21import Katip.Scribes.ElasticSearch
22−import Katip.Scribes.ElasticSearch.Internal (ESV5)
22+import Katip.Scribes.ElasticSearch.Internal (ESV1)
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 ESV5))
37+ bench "mkDocId (randomIO)" $ nfIO (mkDocId (Proxy :: Proxy ESV1))
38 , bench "mkDocId' (shared )" $ nfIO mkDocId'
38 , bench "mkDocId' (shared )" $ nfIO mkDocId'
39 ]
39 ]
40
40
katip-elasticsearch/changelog.md−21
@@ -1,24 +1,3 @@
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−
11−0.6.0.0
12−=======
13−* Update to katip-0.8.0.0 `PermitFunc` convention. To update, for
14− example, if you were passing `InfoS` to `mkEsScribe` to filter
15− severities, instead you should pass `(permitItem InfoS)`.
16−* Update examples to add necessary type signature for the default
17− scribe config.
18−* Bugfix: the default error retry policy was much more rapid than
19− documented.
20−* Internally switch to safe-exceptions from encolosed-exceptions.
21−
220.5.1.1
10.5.1.1
23=======
2=======
24* Loosen katip dep
3* Loosen katip dep
katip-elasticsearch/docker-compose.ymldeleted−10
@@ -1,10 +0,0 @@
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.Bloodhound
9+import Database.V5.Bloodhound
10import Network.HTTP.Client
10import Network.HTTP.Client
11-------------------------------------------------------------------------------
11-------------------------------------------------------------------------------
12import Katip
12import Katip
katip-elasticsearch/katip-elasticsearch.cabal+18−15
@@ -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.7.0.0
4+version: 0.6.0.0
5license: BSD3
5license: BSD3
6license-file: LICENSE
6license-file: LICENSE
7author: Ozgun Ataman, Michael Xavier
7author: Ozgun Ataman, Michael Xavier
@@ -35,23 +35,23 @@ library
35 Katip.Scribes.ElasticSearch.Internal
35 Katip.Scribes.ElasticSearch.Internal
36 build-depends:
36 build-depends:
37 base >=4.6 && <5
37 base >=4.6 && <5
38− , katip >= 0.8.0.0
38+ , katip >= 0.2.0.0 && < 0.9
39− , bloodhound >= 0.13.0.0
39+ , bloodhound >= 0.13.0.0 && < 0.17
40− , uuid >= 1.3.12
40+ , uuid >= 1.3.12 && < 1.4
41 , aeson >=0.6
41 , aeson >=0.6
42− , stm >= 2.4.3
42+ , stm >= 2.4.3 && < 2.6
43− , stm-chans >= 3.0.0.2
43+ , stm-chans >= 3.0.0.2 && < 3.1
44− , async >= 2.0.1.0
44+ , async >= 2.0.1.0 && < 3.0
45 , safe-exceptions >= 0.1.0.0
45 , safe-exceptions >= 0.1.0.0
46− , http-client >= 0.3
46+ , http-client >= 0.3 && < 0.6
47− , text >= 0.11
47+ , text >= 0.11 && < 1.3
48− , retry >= 0.7
48+ , retry >= 0.7 && < 0.8
49 , exceptions
49 , exceptions
50− , scientific >= 0.3.0.0
50+ , scientific >= 0.3.0.0 && < 0.4
51− , unordered-containers >= 0.1.0.0
51+ , unordered-containers >= 0.1.0.0 && < 0.3
52− , transformers >= 0.2
52+ , transformers >= 0.2 && < 0.6
53− , http-types >= 0.8
53+ , http-types >= 0.8 && < 0.13
54− , time >= 1
54+ , time >= 1 && < 1.9
55 , bytestring
55 , bytestring
56 , semigroups
56 , semigroups
57 hs-source-dirs: src
57 hs-source-dirs: src
@@ -108,4 +108,7 @@ test-suite test
108 , bytestring
108 , bytestring
109 , tagged
109 , tagged
110
110
111+ if flag(lib-Werror)
112+ ghc-options: -Wall -Werror
113+
111 ghc-options: -threaded -rtsopts
114 ghc-options: -threaded -rtsopts
katip-elasticsearch/src/Katip/Scribes/ElasticSearch.hs−5
@@ -1,4 +1,3 @@
1−{-# LANGUAGE CPP #-}
2-- | Includes a scribe that can be used to log structured, JSON log
1-- | Includes a scribe that can be used to log structured, JSON log
3-- messages to ElasticSearch. These logs can be explored easily using
2-- messages to ElasticSearch. These logs can be explored easily using
4-- <https://www.elastic.co/products/kibana kibana> or your tool of
3-- <https://www.elastic.co/products/kibana kibana> or your tool of
@@ -68,16 +67,12 @@ module Katip.Scribes.ElasticSearch
68 , essIndexSettings
67 , essIndexSettings
69 , essIndexSharding
68 , essIndexSharding
70 , defaultEsScribeCfg
69 , defaultEsScribeCfg
71−#if !MIN_VERSION_bloodhound(0,17,0)
72 , defaultEsScribeCfgV1
70 , defaultEsScribeCfgV1
73−#endif
74 , defaultEsScribeCfgV5
71 , defaultEsScribeCfgV5
75 -- ** Version-Proxied APIS
72 -- ** Version-Proxied APIS
76 -- $versionproxies
73 -- $versionproxies
77 , defaultEsScribeCfg'
74 , defaultEsScribeCfg'
78−#if !MIN_VERSION_bloodhound(0,17,0)
79 , ESV1
75 , ESV1
80−#endif
81 , ESV5
76 , ESV5
82 -- * Utilities
77 -- * Utilities
83 , mkDocId
78 , mkDocId
katip-elasticsearch/src/Katip/Scribes/ElasticSearch/Internal.hs+7−18
@@ -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 as Monoid
31+import Data.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,12 +37,8 @@ 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
43import qualified Database.V1.Bloodhound as V1
40import qualified Database.V1.Bloodhound as V1
44import qualified Database.V5.Bloodhound as V5
41import qualified Database.V5.Bloodhound as V5
45−#endif
46import Network.HTTP.Client
42import Network.HTTP.Client
47import Network.HTTP.Types.Status
43import Network.HTTP.Types.Status
48import Text.Printf (printf)
44import Text.Printf (printf)
@@ -99,7 +95,7 @@ data EsScribeCfg v = EsScribeCfg {
99-- * DailyIndexSharding
95-- * DailyIndexSharding
100defaultEsScribeCfg' :: ESVersion v => proxy v -> EsScribeCfg v
96defaultEsScribeCfg' :: ESVersion v => proxy v -> EsScribeCfg v
101defaultEsScribeCfg' prx = EsScribeCfg {
97defaultEsScribeCfg' prx = EsScribeCfg {
102− essRetryPolicy = exponentialBackoff 25000 Monoid.<> limitRetries 5
98+ essRetryPolicy = exponentialBackoff 25000 <> limitRetries 5
103 , essQueueSize = EsQueueSize 1000
99 , essQueueSize = EsQueueSize 1000
104 , essPoolSize = EsPoolSize 2
100 , essPoolSize = EsPoolSize 2
105 , essAnnotateTypes = False
101 , essAnnotateTypes = False
@@ -108,22 +104,19 @@ defaultEsScribeCfg' prx = EsScribeCfg {
108 }
104 }
109
105
110
106
111−
112−
113-------------------------------------------------------------------------------
107-------------------------------------------------------------------------------
114−-- | Alias of 'defaultEsScribeCfgV5' to minimize API
108+-- | Alias of 'defaultEsScribeCfgV1' to minimize API
115-- breakage. Previous versions of katip-elasticsearch only supported
109-- breakage. Previous versions of katip-elasticsearch only supported
116−-- ES version 1 and defaulted to it.
110+-- ES version 1.
117−defaultEsScribeCfg :: EsScribeCfg ESV5
111+defaultEsScribeCfg :: EsScribeCfg ESV1
118−defaultEsScribeCfg = defaultEsScribeCfgV5
112+defaultEsScribeCfg = defaultEsScribeCfgV1
119
113
120
114
121-------------------------------------------------------------------------------
115-------------------------------------------------------------------------------
122−#if !MIN_VERSION_bloodhound(0,17,0)
123-- | EsScribeCfg that will use ElasticSearch V1
116-- | EsScribeCfg that will use ElasticSearch V1
124defaultEsScribeCfgV1 :: EsScribeCfg ESV1
117defaultEsScribeCfgV1 :: EsScribeCfg ESV1
125defaultEsScribeCfgV1 = defaultEsScribeCfg' (Typeable.Proxy :: Typeable.Proxy ESV1)
118defaultEsScribeCfgV1 = defaultEsScribeCfg' (Typeable.Proxy :: Typeable.Proxy ESV1)
126−#endif
119+
127
120
128-------------------------------------------------------------------------------
121-------------------------------------------------------------------------------
129-- | EsScribeCfg that will use ElasticSearch V5
122-- | EsScribeCfg that will use ElasticSearch V5
@@ -491,10 +484,7 @@ class ESVersion v where
491
484
492
485
493
486
494−#if !MIN_VERSION_bloodhound(0,17,0)
495data ESV1 = ESV1
487data ESV1 = ESV1
496−{-# DEPRECATED ESV1 "ESV1 is deprecated and removed in bloodhound >= 0.17.0" #-}
497−
498
488
499instance ESVersion ESV1 where
489instance ESVersion ESV1 where
500 type BHEnv ESV1 = V1.BHEnv
490 type BHEnv ESV1 = V1.BHEnv
@@ -534,7 +524,6 @@ instance ESVersion ESV1 where
534 [ "type" .= String "string"
524 [ "type" .= String "string"
535 , "index" .= String "analyzed"
525 , "index" .= String "analyzed"
536 ]
526 ]
537−#endif
538
527
539
528
540data ESV5 = ESV5
529data ESV5 = ESV5
katip-elasticsearch/test/Main.hs+7−23
@@ -34,12 +34,8 @@ 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
40import qualified Database.V1.Bloodhound as V1
37import qualified Database.V1.Bloodhound as V1
41import qualified Database.V5.Bloodhound as V5
38import qualified Database.V5.Bloodhound as V5
42−#endif
43import Network.HTTP.Client
39import Network.HTTP.Client
44import Network.HTTP.Types.Status
40import Network.HTTP.Types.Status
45import Test.QuickCheck.Instances ()
41import Test.QuickCheck.Instances ()
@@ -58,10 +54,8 @@ main :: IO ()
58main = defaultMainWithIngredients ings $ askOption $ \vers -> testGroup "katip-elasticsearch"
54main = defaultMainWithIngredients ings $ askOption $ \vers -> testGroup "katip-elasticsearch"
59 [
55 [
60 case vers of
56 case vers of
61−#if !MIN_VERSION_bloodhound(0,17,0)
62− TestV1 -> esTests (Typeable.Proxy :: Typeable.Proxy ESV1)
57+ TestV1 -> esTests (Typeable.Proxy :: Typeable.Proxy ESV1)
63−#endif
64− TestV5 -> esTests (Typeable.Proxy :: Typeable.Proxy ESV5)
58+ TestV5 -> esTests (Typeable.Proxy :: Typeable.Proxy ESV5)
65 , typeAnnotatedTests
59 , typeAnnotatedTests
66 , roundToSundayTests
60 , roundToSundayTests
67 ]
61 ]
@@ -70,26 +64,18 @@ main = defaultMainWithIngredients ings $ askOption $ \vers -> testGroup "katip-e
70
64
71
65
72-------------------------------------------------------------------------------
66-------------------------------------------------------------------------------
73−data TestWithESVersion = TestV5
67+data TestWithESVersion = TestV1
74−#if !MIN_VERSION_bloodhound(0,17,0)
68+ | TestV5
75− | TestV1
76−#endif
77− deriving (Typeable)
69+ deriving (Typeable)
78
70
79
71
80instance IsOption TestWithESVersion where
72instance IsOption TestWithESVersion where
81− defaultValue = TestV5
73+ defaultValue = TestV1
82−#if !MIN_VERSION_bloodhound(0,17,0)
83 parseValue "1" = Just TestV1
74 parseValue "1" = Just TestV1
84−#endif
85 parseValue "5" = Just TestV5
75 parseValue "5" = Just TestV5
86 parseValue _ = Nothing
76 parseValue _ = Nothing
87 optionName = Tagged "es-version"
77 optionName = Tagged "es-version"
88−#if MIN_VERSION_bloodhound(0,17,0)
89− optionHelp = Tagged "Version of ES to test against, either 1 or 5, defaulting to 5."
78+ optionHelp = Tagged "Version of ES to test against, either 1 or 5, defaulting to 1."
90−#else
91− optionHelp = Tagged "Version of ES to test against, only v5 is supported, but should work for higher versions."
92−#endif
93
79
94
80
95class ESVersion v => TestESVersion v where
81class ESVersion v => TestESVersion v where
@@ -115,7 +101,6 @@ class ESVersion v => TestESVersion v where
115 searchByIndex :: proxy v -> IndexName v -> Search v -> BH v IO (Response ByteString)
101 searchByIndex :: proxy v -> IndexName v -> Search v -> BH v IO (Response ByteString)
116
102
117
103
118−#if !MIN_VERSION_bloodhound(0,17,0)
119instance TestESVersion ESV1 where
104instance TestESVersion ESV1 where
120 type Server ESV1 = V1.Server
105 type Server ESV1 = V1.Server
121 toServer _ = V1.Server
106 toServer _ = V1.Server
@@ -137,7 +122,6 @@ instance TestESVersion ESV1 where
137 refreshIndex _ = V1.refreshIndex
122 refreshIndex _ = V1.refreshIndex
138 withBH _ = V1.withBH
123 withBH _ = V1.withBH
139 searchByIndex _ = V1.searchByIndex
124 searchByIndex _ = V1.searchByIndex
140−#endif
141
125
142
126
143instance TestESVersion ESV5 where
127instance TestESVersion ESV5 where
katip-logzio/README.md+4
@@ -2,3 +2,7 @@
2
2
3katip-logzio is a scribe for the Katip logging framework that sends
3katip-logzio is a scribe for the Katip logging framework that sends
4structured logs to the logz.io centralized logging platform.
4structured logs to the logz.io centralized logging platform.
5+
6+## Warning
7+
8+This is an unreleased library and is not yet production-ready.
katip-logzio/changelog.md+1−8
@@ -1,9 +1,2 @@
1−0.1.1.0
1+Unreleased
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
8==========
2==========
9−* Initial release
katip-logzio/katip-logzio.cabal+3−6
@@ -1,6 +1,5 @@
1name: katip-logzio
1name: katip-logzio
2−version: 0.1.1.0
2+version: 0.0.1.0
3−synopsis: Logz.IO scribe for the Katip logging framework
4description: See README.md for more details.
3description: See README.md for more details.
5license: BSD3
4license: BSD3
6license-file: LICENSE
5license-file: LICENSE
@@ -48,12 +47,10 @@ library
48 , http-types
47 , http-types
49 , text
48 , text
50 , bytestring
49 , bytestring
51− , scientific
52− , stm-chans >= 2.0.0
53 hs-source-dirs: src
50 hs-source-dirs: src
54 default-language: Haskell2010
51 default-language: Haskell2010
55 hs-source-dirs: src
52 hs-source-dirs: src
56− ghc-options: -Wall -Wall -Wnoncanonical-monad-instances
53+ ghc-options: -Wall -j -Wall -Wnoncanonical-monad-instances
57 if flag(lib-Werror)
54 if flag(lib-Werror)
58 ghc-options: -Werror
55 ghc-options: -Werror
59
56
@@ -89,6 +86,6 @@ test-suite test
89 , uri-bytestring
86 , uri-bytestring
90 , warp
87 , warp
91 , http-types
88 , http-types
92− ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N -Wnoncanonical-monad-instances
89+ ghc-options: -j -Wall -threaded -rtsopts -with-rtsopts=-N -Wnoncanonical-monad-instances
93 if flag(lib-Werror)
90 if flag(lib-Werror)
94 ghc-options: -Werror
91 ghc-options: -Werror
katip-logzio/src/Katip/Scribes/LogzIO/HTTPS.hs+152−172
@@ -1,5 +1,4 @@
1{-# LANGUAGE BangPatterns #-}
1{-# LANGUAGE BangPatterns #-}
2−{-# LANGUAGE GADTs #-}
3{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2{-# LANGUAGE GeneralizedNewtypeDeriving #-}
4{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE OverloadedStrings #-}
5{-# LANGUAGE RankNTypes #-}
4{-# LANGUAGE RankNTypes #-}
@@ -39,34 +38,31 @@ module Katip.Scribes.LogzIO.HTTPS
39
38
40-------------------------------------------------------------------------------
39-------------------------------------------------------------------------------
41import Control.Applicative
40import Control.Applicative
42−import qualified Control.Concurrent.Async as Async
41+import qualified Control.Concurrent.Async as Async
43−import qualified Control.Concurrent.STM as STM
42+import qualified Control.Concurrent.STM as STM
44−import qualified Control.Concurrent.STM.TBMQueue as STM
45−import qualified Control.Error as E
43+import qualified Control.Error as E
46−import qualified Control.Exception.Safe as EX
44+import qualified Control.Exception.Safe as EX
47−import Control.Monad
48−import qualified Control.Retry as Retry
45+import qualified Control.Retry as Retry
49−import qualified Data.Aeson as A
46+import qualified Data.Aeson as A
50−import qualified Data.ByteString.Builder as BB
47+import qualified Data.ByteString.Builder as BB
51−import qualified Data.ByteString.Lazy as LBS
48+import qualified Data.ByteString.Lazy as LBS
52−import qualified Data.ByteString.Lazy.Char8 as LBS8
49+import qualified Data.ByteString.Lazy.Char8 as LBS8
53−import qualified Data.HashMap.Strict as HM
50+import qualified Data.HashMap.Strict as HM
54import Data.Int
51import Data.Int
55−import qualified Data.Scientific as Scientific
56−import Data.Semigroup as Semigroup
57−import Data.String (IsString)
52+import Data.String (IsString)
58−import qualified Data.Text as T
53+import qualified Data.Text as T
59−import qualified Data.Text.Encoding as TE
54+import qualified Data.Text.Encoding as TE
60−import qualified Data.Text.Lazy as TL
55+import qualified Data.Text.Lazy as TL
61−import qualified Data.Text.Lazy.Builder as TB
56+import qualified Data.Text.Lazy.Builder as TB
62−import qualified Data.Time as Time
57+import qualified Data.Time as Time
63−import qualified Katip as K
58+import qualified Katip as K
64−import Katip.Core (LocJs (..))
59+import Katip.Core (LocJs (..))
65−import qualified Network.HTTP.Client as HTTP
60+import qualified Network.HTTP.Client as HTTP
66−import qualified Network.HTTP.Client.TLS as HTTPS
61+import qualified Network.HTTP.Client.TLS as HTTPS
67−import qualified Network.HTTP.Types as HTypes
62+import qualified Network.HTTP.Types as HTypes
68−import qualified System.Posix.Types as POSIX
63+import qualified System.Posix.Types as POSIX
69−import qualified URI.ByteString as URIBS
64+import qualified URI.ByteString as URIBS
65+-------------------------------------------------------------------------------
70-------------------------------------------------------------------------------
66-------------------------------------------------------------------------------
71
67
72
68
@@ -200,7 +196,7 @@ httpPort = URIBS.Port 8070
200-- | A reasonable retry policy: exponential backoff with 25ms base
196-- | A reasonable retry policy: exponential backoff with 25ms base
201-- delay up to 5 retries, for a total cumulative delay of 775ms.
197-- delay up to 5 retries, for a total cumulative delay of 775ms.
202defaultRetryPolicy :: (Monad m) => Retry.RetryPolicyM m
198defaultRetryPolicy :: (Monad m) => Retry.RetryPolicyM m
203−defaultRetryPolicy = Retry.exponentialBackoff 25000 `mappend` Retry.limitRetries 5
199+defaultRetryPolicy = Retry.exponentialBackoff 25000 <> Retry.limitRetries 5
204
200
205-------------------------------------------------------------------------------
201-------------------------------------------------------------------------------
206mkLogzIOScribe
202mkLogzIOScribe
@@ -209,115 +205,132 @@ mkLogzIOScribe
209 -> K.Verbosity
205 -> K.Verbosity
210 -> IO K.Scribe
206 -> IO K.Scribe
211mkLogzIOScribe config permitItem verbosity = do
207mkLogzIOScribe config permitItem verbosity = do
212− -- This size is actually somewhat arbitrary. We're just making sure
208+ -- Accumulating buffer for each item
213− -- it isn't infinite so we don't consume the whole backlog right
209+ bufferState <- STM.newTVarIO (mempty :: BulkBuffer)
214− -- away and take up lots of memory.. Katip above us does bounded
210+ -- Single-slot TMVar when something is ready to write. Katip buffers
215− -- buffering and load-shedding when there's too much of a
211+ -- for us upstream so we can simplify shutdown and flush guarantees
216− -- backlog. Our writes are blocking to apply backpressure up to
212+ -- by synchronously writing when we need to.
217− -- katip. This value just holds onto values temporarily while we
213+ readyMVar <- STM.newEmptyTMVarIO :: IO (STM.TMVar BulkBuffer)
218− -- concatenate them into a buffer.
214+
219− ingestionQueue <- STM.newTBMQueueIO (itemBufferSize * 10)
215+ -- We create a TVar that is set to ShutDown when its time to stop
220−
216+ killSwitch <- STM.newTVarIO Continue
217+
218+ -- Create a mutable ref to whether the timer has expired. This lets
219+ -- us replace the timer when its time to start timing again. We
220+ -- reset the timer __after__ a write goes out, not as soon as it expires
221− let newTimer = STM.registerDelay itemBufferTimeoutMicros
221+ timerRef <- STM.newTVarIO =<< STM.registerDelay itemBufferTimeoutMicros
222− timerRef <- STM.newTVarIO =<< newTimer
223
222
224 -- Set up a connection manager for requests
223 -- Set up a connection manager for requests
225 mgr <- case scheme of
224 mgr <- case scheme of
226 HTTPS -> HTTPS.newTlsManager
225 HTTPS -> HTTPS.newTlsManager
227 HTTP -> HTTP.newManager HTTP.defaultManagerSettings
226 HTTP -> HTTP.newManager HTTP.defaultManagerSettings
228
227
229− -- An STM transaction that will return true when writes are stopped
228+ -- In STM: resolve an action with the buffers
230− -- and backlog is emptied.
229+ let processLogAction :: LogAction BulkBuffer -> STM.STM ()
231− let workExhausted :: STM.STM Bool
230+ processLogAction logAction = case logAction of
232− workExhausted = (&&)
231+ -- No write needed right now
233− <$> STM.isClosedTBMQueue ingestionQueue
232+ Buffered !newBuffer -> STM.writeTVar bufferState newBuffer
234− <*> STM.isEmptyTBMQueue ingestionQueue
233+ -- Time to flush and put excess in the next buffer
235− -- Block until there's no more work
234+ FlushNow !toFlush !newBuffer -> do
236− let waitWorkExhausted :: STM.STM ()
235+ STM.writeTVar bufferState newBuffer
237− waitWorkExhausted = STM.check =<< workExhausted
236+ STM.putTMVar readyMVar toFlush
238− let pop :: STM.STM (Tick AnyLogItem)
237+
239− pop = maybe WorkExhausted NewItem <$> STM.readTBMQueue ingestionQueue
238+ -- Recompute the new buffer state from a new log item and take action
240−
239+ let push :: (K.LogItem a) => K.Item a -> STM.STM ()
241− let timeExpired :: STM.STM (Tick a)
240+ push !logItem = do
242− timeExpired = do
241+ !curBuffer <- STM.readTVar bufferState
243− isExpired <- STM.readTVar =<< STM.readTVar timerRef
242+ processLogAction (bufferItem itemBufferSize verbosity logItem curBuffer)
244− STM.check isExpired
243+
245− pure TimeExpired
244+
246−
245+ -- A transaction that retries until its time to shutdown
247− -- Circular transaction that checks for completion of work, time
246+ let waitShutdown :: STM.STM ()
248− -- expiration, or new events.
247+ waitShutdown = do
249− let nextTick :: STM.STM (Tick AnyLogItem)
248+ killStatus <- STM.readTVar killSwitch
250− nextTick =
249+ STM.check (killStatus == ShutDown)
251− timeExpired <|>
250+
252− pop <|>
251+ -- Retry transaction until timer has expired. When it does, take action on the buffer.
253− (WorkExhausted <$ waitWorkExhausted)
254−
255− -- Blocking push. This applies backpressure upstream to katip, which does its own buffering
256− let push :: AnyLogItem -> STM.STM ()
252+ let waitTimer :: STM.STM ()
257− push = void . STM.writeTBMQueue ingestionQueue
253+ waitTimer = do
258−
254+ -- get the timer we'll be using
259− let sealQueue = STM.atomically (STM.closeTBMQueue ingestionQueue)
255+ timer <- STM.readTVar timerRef
260−
256+ -- do not proceed until its ready
261− -- Replace the timer with a new one
257+ timerExpired <- STM.readTVar timer
262− let resetTimer = STM.atomically . STM.writeTVar timerRef =<< newTimer
258+ STM.check timerExpired
263−
259+ -- do not wake again until this message is out the door
264− -- Send the buffer and then reset the timer
260+ STM.writeTVar timer False
265− let flush curBuffer = do
261+ -- we waited long enough, grab the current buffer
266− res <- flushBuffer config mgr curBuffer
262+ !curBuffer <- STM.readTVar bufferState
263+ -- and tell it to flush right now
264+ processLogAction (forceFlush curBuffer)
265+
266+ -- run the timer in a loop until its time to shut down
267+ let timedFlushLoop :: IO ()
268+ timedFlushLoop = do
269+ res <- STM.atomically $
270+ raceAlt
271+ waitShutdown
272+ waitTimer
267 case res of
273 case res of
274+ Left () -> pure () -- exit loop
275+ Right () -> timedFlushLoop -- wait for another timer or shutdown
276+
277+ timedFlusher <- Async.async timedFlushLoop
278+
279+ -- flush the buffer until its time to shutdown and we're out of items to log
280+ let flushLoop :: IO ()
281+ flushLoop = do
282+ -- 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
283+ readyBufferOrDie <- STM.atomically $
284+ raceAlt
285+ (STM.takeTMVar readyMVar)
286+ waitShutdown
287+ case readyBufferOrDie of
288+ Right () -> pure () -- we caught shutdown before any new data arrived
289+ -- There's some logs to write
290+ Left readyBuffer -> do
291+ -- flush in IO
292+ res <- flushBuffer config mgr readyBuffer
293+ case res of
268− Left e -> onErrorSafe e
294+ Left ex -> onErrorSafe ex
269− Right () -> pure ()
295+ Right () -> pure ()
270− resetTimer
296+ -- reset the timeout before the next flush on each write
271−
297+ !newTimer <- STM.registerDelay itemBufferTimeoutMicros
272− let flushLoop :: BulkBuffer -> IO ()
273− flushLoop curBuffer = do
274− tick <- STM.atomically nextTick
298+ STM.atomically $ do
275− case tick of
299+ STM.writeTVar timerRef newTimer
276− WorkExhausted -> do
300+ -- start over
277− flush curBuffer -- flush what you've got
301+ flushLoop
278− pure () -- stop looping
302+ flusher <- Async.async flushLoop
279− TimeExpired -> do
303+
280− flush curBuffer
304+ -- Blocking call which sends a poison pill to the workers and waits
281− flushLoop mempty
305+ -- for them to exit, swallowing exceptions. This follows the
282− NewItem (AnyLogItem item) -> do
306+ -- semantics that when katip calls the finalizer, no more log
283− case bufferItem (logzIOScribeConfiguration_bufferItems config) verbosity item curBuffer of
307+ -- entries will be sent.
284− Buffered newBuffer -> flushLoop newBuffer
308+ let shutdown :: IO ()
285− FlushNow flushThis newBuffer -> do
309+ shutdown = do
286− flush flushThis
310+ -- tell workers this is the last loop
287− flushLoop newBuffer
311+ STM.atomically (STM.writeTVar killSwitch ShutDown)
288−
312+ -- wait for workers to finish
289− flushThread <- Async.async (flushLoop mempty)
313+ _ <- Async.waitCatch timedFlusher
290−
291− let close = do
292− sealQueue
293− _ <- Async.waitCatch flushThread
314+ _ <- Async.waitCatch flusher
315+ -- stop blocking
294 pure ()
316 pure ()
295
317
318+
296 pure $ K.Scribe
319 pure $ K.Scribe
297− { K.liPush = STM.atomically . push . AnyLogItem
320+ { K.liPush = STM.atomically . push
298− , K.scribeFinalizer = close
321+ , K.scribeFinalizer = shutdown
299 , K.scribePermitItem = permitItem
322 , K.scribePermitItem = permitItem
300 }
323 }
301 where
324 where
302 itemBufferSize = logzIOScribeConfiguration_bufferItems config
325 itemBufferSize = logzIOScribeConfiguration_bufferItems config
303 itemBufferTimeoutMicros = ndtToMicros (logzIOScribeConfiguration_bufferTimeout config)
326 itemBufferTimeoutMicros = ndtToMicros (logzIOScribeConfiguration_bufferTimeout config)
304 scheme = logzIOScribeConfiguration_scheme config
327 scheme = logzIOScribeConfiguration_scheme config
328+ -- should this be async?
305 onErrorSafe ex = do
329 onErrorSafe ex = do
306 _ <- EX.tryAny (logzIOScribeConfiguration_onError config ex)
330 _ <- EX.tryAny (logzIOScribeConfiguration_onError config ex)
307 pure ()
331 pure ()
308
332
309
333
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−
321-------------------------------------------------------------------------------
334-------------------------------------------------------------------------------
322-- Match the native resolution of NominalDiffTime, which is excessive
335-- Match the native resolution of NominalDiffTime, which is excessive
323-- for our needs
336-- for our needs
@@ -335,6 +348,23 @@ ndtToMicros t = round (((fromIntegral (ndtPicos t)) :: Double) / picosInMicro)
335 picosInMicro = 10 ^ (3 :: Int)
348 picosInMicro = 10 ^ (3 :: Int)
336
349
337
350
351+-------------------------------------------------------------------------------
352+-- | An internal mode flag used to shut down worker
353+-- threads. Internally, we assume htere is no going back from
354+-- ShutDown.
355+data KillSwitch =
356+ Continue
357+ | ShutDown
358+ deriving (Eq)
359+
360+
361+-------------------------------------------------------------------------------
362+-- | When applied to STM, it will try the left side first and if that
363+-- retries, the right, and if that retries, start from the beginning.
364+raceAlt :: (Alternative m) => m a -> m b -> m (Either a b)
365+raceAlt a b = (Left <$> a) <|> (Right <$> b)
366+
367+
338-------------------------------------------------------------------------------
368-------------------------------------------------------------------------------
339data LoggingError =
369data LoggingError =
340 URIError HTTP.HttpException
370 URIError HTTP.HttpException
@@ -411,7 +441,7 @@ flushBuffer config mgr bulkBuffer
411-------------------------------------------------------------------------------
441-------------------------------------------------------------------------------
412newtype Bytes = Bytes
442newtype Bytes = Bytes
413 { bytes :: Int64
443 { bytes :: Int64
414− } deriving (Show, Eq, Num, Ord, Bounded)
444+ } deriving (Show, Eq, Num, Ord)
415
445
416
446
417-- | How big of a body can we send? The limit is defined
447-- | How big of a body can we send? The limit is defined
@@ -442,7 +472,7 @@ fullItemObject verbosity item = HM.fromList
442 , "thread" A..= K.getThreadIdText (K._itemThread item)
472 , "thread" A..= K.getThreadIdText (K._itemThread item)
443 , "host" A..= K._itemHost item
473 , "host" A..= K._itemHost item
444 , "pid" A..= pidInt
474 , "pid" A..= pidInt
445− , "data" A..= annotateKeys (K.payloadObject verbosity (K._itemPayload item))
475+ , "data" A..= K.payloadObject verbosity (K._itemPayload item)
446 -- Slight deviation, logz.io uses "message" instead of "msg"
476 -- Slight deviation, logz.io uses "message" instead of "msg"
447 , "message" A..= TB.toLazyText (K.unLogStr (K._itemMessage item))
477 , "message" A..= TB.toLazyText (K.unLogStr (K._itemMessage item))
448 -- Another slight deviation, logz.io uses "@timestamp" instead of
478 -- Another slight deviation, logz.io uses "@timestamp" instead of
@@ -452,7 +482,7 @@ fullItemObject verbosity item = HM.fromList
452 -- past. They seem to support 3 decimal places of
482 -- past. They seem to support 3 decimal places of
453 -- precision. Formatting like this requires time 1.8.0.2, which is
483 -- precision. Formatting like this requires time 1.8.0.2, which is
454 -- reflected in the cabal file.
484 -- reflected in the cabal file.
455− , "@timestamp" A..= A.String (T.pack (Time.formatTime Time.defaultTimeLocale "%Y-%m-%dT%H:%M:%S%03QZ" (K._itemTime item)))
485+ , "@timestamp" A..= A.String (T.pack (Time.formatTime Time.defaultTimeLocale "%Y-%m-%dT%H:%M:%03QZ" (K._itemTime item)))
456 , "ns" A..= K._itemNamespace item
486 , "ns" A..= K._itemNamespace item
457 , "loc" A..= (LocJs <$> K._itemLoc item)
487 , "loc" A..= (LocJs <$> K._itemLoc item)
458 ]
488 ]
@@ -513,7 +543,7 @@ data BulkBuffer = BulkBuffer
513 }
543 }
514
544
515
545
516−instance Semigroup.Semigroup BulkBuffer where
546+instance Semigroup BulkBuffer where
517 (BulkBuffer bytesUsedA bufferA itemCountA) <>
547 (BulkBuffer bytesUsedA bufferA itemCountA) <>
518 (BulkBuffer bytesUsedB bufferB itemCountB) = BulkBuffer
548 (BulkBuffer bytesUsedB bufferB itemCountB) = BulkBuffer
519 (bytesUsedA + bytesUsedB)
549 (bytesUsedA + bytesUsedB)
@@ -567,7 +597,7 @@ bufferItem' customMaxPayload customMaxItem maxItems verb item bulkBuffer =
567 let (encodedLine, spaceNeeded) = renderLineTruncated' customMaxItem verb item
597 let (encodedLine, spaceNeeded) = renderLineTruncated' customMaxItem verb item
568 newBytesUsed = bulkBuffer_bytesUsed bulkBuffer + spaceNeeded
598 newBytesUsed = bulkBuffer_bytesUsed bulkBuffer + spaceNeeded
569 newItemCount = bulkBuffer_itemCount bulkBuffer + 1
599 newItemCount = bulkBuffer_itemCount bulkBuffer + 1
570− in if newItemCount >= maxItems || newBytesUsed >= customMaxPayload
600+ in if newItemCount > maxItems || newBytesUsed > customMaxPayload
571 then FlushNow
601 then FlushNow
572 bulkBuffer
602 bulkBuffer
573 BulkBuffer
603 BulkBuffer
@@ -587,53 +617,3 @@ bufferItem' customMaxPayload customMaxItem maxItems verb item bulkBuffer =
587-- will always return 'FlushNow' with an empty new buffer.
617-- will always return 'FlushNow' with an empty new buffer.
588forceFlush :: (Monoid buf) => buf -> LogAction buf
618forceFlush :: (Monoid buf) => buf -> LogAction buf
589forceFlush buf = FlushNow buf mempty
619forceFlush buf = FlushNow buf mempty
590−
591−
592−-------------------------------------------------------------------------------
593−-- Annotation borrowed from katip-elasticsearch. There are fixed
594−-- fields in katip logs which should stay the same type forever and
595−-- thus won't need annotation. However, any code in userland may
596−-- choose to add akey to their log's metadata with a type that's
597−-- incompatible with the mapping. If the first value that's picked up
598−-- restrictive (e.g. a long), subsequent values will be rejected. By
599−-- differentiating types by their name, this is guaranteed not to
600−-- happen.
601−
602−annotateValue :: A.Value -> A.Value
603−annotateValue (A.Object o) = A.Object (annotateKeys o)
604−annotateValue (A.Array a) = A.Array (annotateValue <$> a)
605−annotateValue x = x
606−
607−
608−annotateKeys :: A.Object -> A.Object
609−annotateKeys = HM.fromList . map go . HM.toList
610− where
611− go (k, A.Object o) = (k, A.Object (annotateKeys o))
612− go (k, A.Array a) = (k, A.Array (annotateValue <$> a))
613− go (k, s@(A.String _)) = (k <> stringAnn, s)
614− go (k, n@(A.Number sci)) = if Scientific.isFloating sci
615− then (k <> doubleAnn, n)
616− else (k <> longAnn, n)
617− go (k, b@(A.Bool _)) = (k <> booleanAnn, b)
618− go (k, A.Null) = (k <> nullAnn, A.Null)
619−
620−
621−-------------------------------------------------------------------------------
622−-- Annotation Constants
623−-------------------------------------------------------------------------------
624−
625−
626−stringAnn :: T.Text
627−stringAnn = "::s"
628−
629−doubleAnn :: T.Text
630−doubleAnn = "::d"
631−
632−longAnn :: T.Text
633−longAnn = "::l"
634−
635−booleanAnn :: T.Text
636−booleanAnn = "::b"
637−
638−nullAnn :: T.Text
639−nullAnn = "::n"
katip-logzio/test/Katip/Tests/Scribes/LogzIO/HTTPS.hs−18
@@ -108,15 +108,6 @@ 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"]
120 ]
111 ]
121 where
112 where
122 second = 1000000
113 second = 1000000
@@ -232,15 +223,6 @@ bufferItemTests = testGroup "bufferItem"
232 case logAction of
223 case logAction of
233 FlushNow _ newBuffer -> bulkBuffer_itemCount newBuffer === 1
224 FlushNow _ newBuffer -> bulkBuffer_itemCount newBuffer === 1
234 _ -> pure ()
225 _ -> pure ()
235− , testProperty "flushes when the buffer is exactly at the limit" $ property $ do
236− maxItems <- forAll (Gen.int (Range.linear 1 20))
237− item <- forAllWith showSimplePayloadItem genSimplePayloadItem
238− bulkBuffer <- forAllWith inspectBulkBuffer ((\b -> b { bulkBuffer_itemCount = maxItems - 1 }) <$> genBulkBuffer)
239− verbosity <- forAll genVerbosity
240− let logAction = bufferItem' maxBound maxBound maxItems verbosity item bulkBuffer
241− case logAction of
242− FlushNow _ _ -> pure ()
243− Buffered _ -> fail "Expected a FlushNow but got a Buffered"
244 ]
226 ]
245 where
227 where
246 assertFlushNow (FlushNow _ _) = pure ()
228 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 Integration:* Katip was designed to be easily integrated
19+* *Easy to 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−37
@@ -1,40 +1,3 @@
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−
22−0.8.0.0
23−=======
24−* **Breaking change**: switch from severity based log level filtering to
25− user-definable `PermitFunc`. To upgrade, any time you initialize one
26− of the standard scribes, rather than providing a severity like
27− `InfoS`, instead pass in `(permitItem InfoS)`. Credit to
28− [vlatkoB](https://github.com/vlatkoB).
29−* Update some misformatted and outdated docs.
30−* Set lower bound of base to 4.9.0.0, the version shipped with GHC
31− 8.0.2. Support for GHC versions older than that is removed.
32−* Update default formatter of Handle scribe to format pid as `[PID
33− 1234]` instead of `[1234]` and `[ThreadId 1234]` instead of
34− `[1234]`.
35−* Add missing `Bounded` instance for `Verbosity`. This allows you to
36− easily enumerate all verbosities via `[minBound..maxBound]`.
37−
380.7.0.0
10.7.0.0
39=======
2=======
40* Exclusively use HasCallstack for location reporting in errors. Credit to [Domen Kožar](https://github.com/domenkozar)
3* Exclusively use HasCallstack for location reporting in errors. Credit to [Domen Kožar](https://github.com/domenkozar)
katip/katip.cabal+22−22
@@ -1,5 +1,5 @@
1name: katip
1name: katip
2−version: 0.8.5.0
2+version: 0.8.0.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.
@@ -56,29 +56,29 @@ library
56 build-depends: base >=4.9.0.0 && <5
56 build-depends: base >=4.9.0.0 && <5
57 , aeson >=0.6
57 , aeson >=0.6
58 , async < 3.0.0.0
58 , async < 3.0.0.0
59− , auto-update >= 0.1
59+ , auto-update >= 0.1 && < 0.2
60− , bytestring >= 0.9
60+ , bytestring >= 0.9 && < 0.11
61− , containers >=0.4
61+ , containers >=0.4 && <0.7
62− , either >= 4
62+ , either >= 4 && < 5.1
63 , safe-exceptions >= 0.1.0.0
63 , safe-exceptions >= 0.1.0.0
64− , hostname >=1.0
64+ , hostname >=1.0 && <1.1
65− , old-locale >= 1.0
65+ , old-locale >= 1.0 && < 1.1
66− , string-conv >= 0.1
66+ , string-conv >= 0.1 && < 0.2
67− , template-haskell >= 2.8
67+ , template-haskell >= 2.8 && < 2.15
68− , text >= 0.11
68+ , text >= 0.11 && <1.3
69− , time >= 1
69+ , time >= 1 && < 1.9
70− , transformers >= 0.3
70+ , transformers >= 0.3 && < 0.6
71 , transformers-compat
71 , transformers-compat
72− , unordered-containers >= 0.2
72+ , unordered-containers >= 0.2 && < 0.3
73− , monad-control >= 1.0
73+ , monad-control >= 1.0 && < 1.1
74− , mtl >= 2.0
74+ , mtl >= 2.0 && < 2.3
75− , transformers-base >= 0.3
75+ , transformers-base >= 0.3 && < 0.6
76− , resourcet >= 1.1
76+ , resourcet >= 1.1 && < 1.3
77 , scientific >= 0.3.3.0
77 , scientific >= 0.3.3.0
78− , microlens >= 0.2.0.0
78+ , microlens >= 0.2.0.0 && < 0.5
79− , microlens-th >= 0.1.0.0
79+ , microlens-th >= 0.1.0.0 && < 0.5
80 , semigroups
80 , semigroups
81− , unliftio-core >= 0.1
81+ , unliftio-core >= 0.1 && < 0.2
82 , stm >= 2.4
82 , stm >= 2.4
83
83
84 hs-source-dirs: src
84 hs-source-dirs: src
@@ -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.9
90+ build-depends: Win32 >=2.3 && <2.6
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
@@ -114,7 +114,7 @@ test-suite test
114 , template-haskell
114 , template-haskell
115 , text
115 , text
116 , time
116 , time
117− , time-locale-compat >= 0.1.0.1
117+ , time-locale-compat >= 0.1.0.1 && < 0.2
118 , directory
118 , directory
119 , regex-tdfa
119 , regex-tdfa
120 , unordered-containers
120 , unordered-containers
katip/src/Katip.hs+1−3
@@ -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, MonadIO, MonadReader Config) -- these are necessary
47+-- } deriving (Functor, Applicative, Monad) -- more instances as needed
48--
48--
49--
49--
50-- -- These instances get even easier with lenses!
50-- -- These instances get even easier with lenses!
@@ -159,9 +159,7 @@ module Katip
159 , logF
159 , logF
160 , logMsg
160 , logMsg
161 , logT
161 , logT
162− , logLoc
163 , logItem
162 , logItem
164− , logKatipItem
165 , logException
163 , logException
166 -- ** 'KatipContext': Logging With Context
164 -- ** 'KatipContext': Logging With Context
167 -- $katipcontextlogging
165 -- $katipcontextlogging
katip/src/Katip/Core.hs+19−45
@@ -31,9 +31,6 @@ 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
37import Control.Monad.IO.Class
34import Control.Monad.IO.Class
38import Control.Monad.IO.Unlift
35import Control.Monad.IO.Unlift
39import Control.Monad.Trans.Class
36import Control.Monad.Trans.Class
@@ -44,8 +41,7 @@ import Control.Monad.Trans.Either
44import Control.Monad.Trans.Except
41import Control.Monad.Trans.Except
45import Control.Monad.Trans.Maybe
42import Control.Monad.Trans.Maybe
46import Control.Monad.Trans.Reader
43import Control.Monad.Trans.Reader
47−import Control.Monad.Trans.Resource (MonadResource, ResourceT,
44+import Control.Monad.Trans.Resource (ResourceT, transResourceT)
48− transResourceT)
49import Control.Monad.Trans.RWS.Lazy (RWST, mapRWST)
45import Control.Monad.Trans.RWS.Lazy (RWST, mapRWST)
50import qualified Control.Monad.Trans.RWS.Strict as Strict (RWST, mapRWST)
46import qualified Control.Monad.Trans.RWS.Strict as Strict (RWST, mapRWST)
51import Control.Monad.Trans.State.Lazy (StateT, mapStateT)
47import Control.Monad.Trans.State.Lazy (StateT, mapStateT)
@@ -665,7 +661,7 @@ makeLenses ''LogEnv
665
661
666
662
667-------------------------------------------------------------------------------
663-------------------------------------------------------------------------------
668−-- | Create a reasonable default InitLogEnv. Uses an 'AutoUpdate' which
664+-- | Create a reasonable default InitLogEnv. Uses an 'AutoUdate' which
669-- updates the timer every 1ms. If you need even more timestamp
665-- updates the timer every 1ms. If you need even more timestamp
670-- precision at the cost of performance, consider setting
666-- precision at the cost of performance, consider setting
671-- '_logEnvTimer' with 'getCurrentTime'.
667-- '_logEnvTimer' with 'getCurrentTime'.
@@ -880,8 +876,7 @@ instance (Katip m) => Katip (ResourceT m) where
880-- opposed to implementing 'Katip' for your monad.
876-- opposed to implementing 'Katip' for your monad.
881newtype KatipT m a = KatipT { unKatipT :: ReaderT LogEnv m a }
877newtype KatipT m a = KatipT { unKatipT :: ReaderT LogEnv m a }
882 deriving ( Functor, Applicative, Monad, MonadIO
878 deriving ( Functor, Applicative, Monad, MonadIO
883− , MonadMask, MonadCatch, MonadThrow, MonadResource, MonadTrans
879+ , MonadMask, MonadCatch, MonadThrow, MonadTrans, MonadBase b)
884− , MonadBase b)
885
880
886
881
887instance MonadIO m => Katip (KatipT m) where
882instance MonadIO m => Katip (KatipT m) where
@@ -903,20 +898,9 @@ instance (MonadBaseControl b m) => MonadBaseControl b (KatipT m) where
903 restoreM = defaultRestoreM
898 restoreM = defaultRestoreM
904
899
905instance MonadUnliftIO m => MonadUnliftIO (KatipT m) where
900instance 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
910 askUnliftIO = KatipT $
901 askUnliftIO = KatipT $
911− withUnliftIO $ \u ->
902+ withUnliftIO $ \u ->
912− pure (UnliftIO (unliftIO u . unKatipT))
903+ 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
920
904
921-------------------------------------------------------------------------------
905-------------------------------------------------------------------------------
922-- | Execute 'KatipT' on a log env.
906-- | Execute 'KatipT' on a log env.
@@ -948,29 +932,19 @@ logItem
948 -> m ()
932 -> m ()
949logItem a ns loc sev msg = do
933logItem a ns loc sev msg = do
950 LogEnv{..} <- getLogEnv
934 LogEnv{..} <- getLogEnv
951− logKatipItem =<< liftIO
935+ liftIO $ do
936+ item <- Item
952− (Item <$> pure _logEnvApp
937+ <$> pure _logEnvApp
953− <*> pure _logEnvEnv
938+ <*> pure _logEnvEnv
954− <*> pure sev
939+ <*> pure sev
955− <*> (mkThreadIdText <$> myThreadId)
940+ <*> (mkThreadIdText <$> myThreadId)
956− <*> pure _logEnvHost
941+ <*> pure _logEnvHost
957− <*> pure _logEnvPid
942+ <*> pure _logEnvPid
958− <*> pure a
943+ <*> pure a
959− <*> pure msg
944+ <*> pure msg
960− <*> _logEnvTimer
945+ <*> _logEnvTimer
961− <*> pure (_logEnvApp <> ns)
946+ <*> pure (_logEnvApp <> ns)
962− <*> pure loc)
947+ <*> 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 $
974 FT.forM_ (M.elems _logEnvScribes) $ \ ScribeHandle {..} -> do
948 FT.forM_ (M.elems _logEnvScribes) $ \ ScribeHandle {..} -> do
975 whenM (scribePermitItem shScribe item) $
949 whenM (scribePermitItem shScribe item) $
976 void $ atomically (tryWriteTBQueue shChan (NewItem item))
950 void $ atomically (tryWriteTBQueue shChan (NewItem item))
@@ -1019,7 +993,7 @@ logException
1019logException a ns sev action = action `catchAny` \e -> f e >> throwM e
993logException a ns sev action = action `catchAny` \e -> f e >> throwM e
1020 where
994 where
1021 f e = logF a ns sev (msg e)
995 f e = logF a ns sev (msg e)
1022− msg e = ls (T.pack "An exception has occurred: ") <> showLS e
996+ msg e = ls (T.pack "An exception has occured: ") <> showLS e
1023
997
1024
998
1025-------------------------------------------------------------------------------
999-------------------------------------------------------------------------------
katip/src/Katip/Monadic.hs+6−28
@@ -44,9 +44,6 @@ 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
50import Control.Monad.IO.Class
47import Control.Monad.IO.Class
51import Control.Monad.IO.Unlift
48import Control.Monad.IO.Unlift
52import Control.Monad.Reader
49import Control.Monad.Reader
@@ -58,8 +55,7 @@ import Control.Monad.Trans.Either (EitherT, mapEitherT)
58import Control.Monad.Trans.Except (ExceptT, mapExceptT)
55import Control.Monad.Trans.Except (ExceptT, mapExceptT)
59import Control.Monad.Trans.Identity (IdentityT, mapIdentityT)
56import Control.Monad.Trans.Identity (IdentityT, mapIdentityT)
60import Control.Monad.Trans.Maybe (MaybeT, mapMaybeT)
57import Control.Monad.Trans.Maybe (MaybeT, mapMaybeT)
61−import Control.Monad.Trans.Resource (MonadResource,
58+import Control.Monad.Trans.Resource (ResourceT, transResourceT)
62− ResourceT, transResourceT)
63import Control.Monad.Trans.RWS (RWST, mapRWST)
59import Control.Monad.Trans.RWS (RWST, mapRWST)
64import qualified Control.Monad.Trans.RWS.Strict as Strict (RWST, mapRWST)
60import qualified Control.Monad.Trans.RWS.Strict as Strict (RWST, mapRWST)
65import qualified Control.Monad.Trans.State.Strict as Strict (StateT, mapStateT)
61import qualified Control.Monad.Trans.State.Strict as Strict (StateT, mapStateT)
@@ -316,7 +312,7 @@ logExceptionM
316logExceptionM action sev = action `catchAny` \e -> f e >> throwM e
312logExceptionM action sev = action `catchAny` \e -> f e >> throwM e
317 where
313 where
318 f e = logFM sev (msg e)
314 f e = logFM sev (msg e)
319− msg e = ls ("An exception has occurred: " :: Text) Semi.<> showLS e
315+ msg e = ls ("An exception has occured: " :: Text) Semi.<> showLS e
320
316
321
317
322-------------------------------------------------------------------------------
318-------------------------------------------------------------------------------
@@ -350,7 +346,6 @@ newtype KatipContextT m a = KatipContextT {
350 , MonadWriter w
346 , MonadWriter w
351 , MonadError e
347 , MonadError e
352 , MonadPlus
348 , MonadPlus
353− , MonadResource
354 , Alternative
349 , Alternative
355 , MonadFix
350 , MonadFix
356 , MonadTrans
351 , MonadTrans
@@ -397,21 +392,10 @@ instance (MonadIO m) => KatipContext (KatipContextT m) where
397 localKatipNamespace f (KatipContextT m) = KatipContextT $ local (\s -> s { ltsNamespace = f (ltsNamespace s)}) m
392 localKatipNamespace f (KatipContextT m) = KatipContextT $ local (\s -> s { ltsNamespace = f (ltsNamespace s)}) m
398
393
399instance MonadUnliftIO m => MonadUnliftIO (KatipContextT m) where
394instance 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
404 askUnliftIO = KatipContextT $
395 askUnliftIO = KatipContextT $
405− withUnliftIO $ \u ->
396+ withUnliftIO $ \u ->
406− pure (UnliftIO (unliftIO u . unKatipContextT))
397+ pure (UnliftIO (unliftIO u . unKatipContextT))
407−#endif
408−
409
398
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
415
399
416-------------------------------------------------------------------------------
400-------------------------------------------------------------------------------
417runKatipContextT :: (LogItem c) => LogEnv -> c -> Namespace -> KatipContextT m a -> m a
401runKatipContextT :: (LogItem c) => LogEnv -> c -> Namespace -> KatipContextT m a -> m a
@@ -490,15 +474,9 @@ instance MonadBaseControl b m => MonadBaseControl b (NoLoggingT m) where
490 restoreM = NoLoggingT . restoreM
474 restoreM = NoLoggingT . restoreM
491
475
492instance MonadUnliftIO m => MonadUnliftIO (NoLoggingT m) where
476instance 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
497 askUnliftIO = NoLoggingT $
477 askUnliftIO = NoLoggingT $
498− withUnliftIO $ \u ->
478+ withUnliftIO $ \u ->
499− pure (UnliftIO (unliftIO u . runNoLoggingT))
479+ pure (UnliftIO (unliftIO u . runNoLoggingT))
500−#endif
501−
502
480
503instance MonadIO m => Katip (NoLoggingT m) where
481instance MonadIO m => Katip (NoLoggingT m) where
504 getLogEnv = liftIO (initLogEnv "NoLoggingT" "no-logging")
482 getLogEnv = liftIO (initLogEnv "NoLoggingT" "no-logging")
stack.yaml+3−5
@@ -1,14 +1,12 @@
1−resolver: lts-16.18
1+resolver: lts-12.26
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
9− - github: wireapp/bloodhound
8+ - bloodhound-0.16.0.0
10− commit: b409f52b518f20a4c20651b5893c31b7b85cb9b1
9+ - unliftio-core-0.1.2.0
11−allow-newer: true
12flags:
10flags:
13 katip:
11 katip:
14 lib-Werror: true
12 lib-Werror: true