log-elasticsearch 0.7 → 0.8
raw patch · 4 files changed
+96/−22 lines, 4 filesdep +http-client-tlsPVP ok
version bump matches the API change (PVP)
Dependencies added: http-client-tls
API changes (from Hackage documentation)
- Log.Backend.ElasticSearch: ElasticSearchConfig :: !Text -> !Text -> !Text -> ElasticSearchConfig
- Log.Backend.ElasticSearch: [esIndex] :: ElasticSearchConfig -> !Text
- Log.Backend.ElasticSearch: [esMapping] :: ElasticSearchConfig -> !Text
- Log.Backend.ElasticSearch: [esServer] :: ElasticSearchConfig -> !Text
- Log.Backend.ElasticSearch: instance GHC.Classes.Eq Log.Backend.ElasticSearch.ElasticSearchConfig
- Log.Backend.ElasticSearch: instance GHC.Show.Show Log.Backend.ElasticSearch.ElasticSearchConfig
+ Log.Backend.ElasticSearch: esIndex :: ElasticSearchConfig -> Text
+ Log.Backend.ElasticSearch: esLogin :: ElasticSearchConfig -> Maybe (EsUsername, EsPassword)
+ Log.Backend.ElasticSearch: esLoginInsecure :: ElasticSearchConfig -> Bool
+ Log.Backend.ElasticSearch: esMapping :: ElasticSearchConfig -> Text
+ Log.Backend.ElasticSearch: esServer :: ElasticSearchConfig -> Text
+ Log.Backend.ElasticSearch.Internal: ElasticSearchConfig :: !Text -> !Text -> !Text -> Maybe (EsUsername, EsPassword) -> !Bool -> ElasticSearchConfig
+ Log.Backend.ElasticSearch.Internal: [esIndex] :: ElasticSearchConfig -> !Text
+ Log.Backend.ElasticSearch.Internal: [esLoginInsecure] :: ElasticSearchConfig -> !Bool
+ Log.Backend.ElasticSearch.Internal: [esLogin] :: ElasticSearchConfig -> Maybe (EsUsername, EsPassword)
+ Log.Backend.ElasticSearch.Internal: [esMapping] :: ElasticSearchConfig -> !Text
+ Log.Backend.ElasticSearch.Internal: [esServer] :: ElasticSearchConfig -> !Text
+ Log.Backend.ElasticSearch.Internal: data ElasticSearchConfig
+ Log.Backend.ElasticSearch.Internal: defaultElasticSearchConfig :: ElasticSearchConfig
+ Log.Backend.ElasticSearch.Internal: instance GHC.Classes.Eq Log.Backend.ElasticSearch.Internal.ElasticSearchConfig
+ Log.Backend.ElasticSearch.Internal: instance GHC.Show.Show Log.Backend.ElasticSearch.Internal.ElasticSearchConfig
+ Log.Backend.ElasticSearch.Lens: data ElasticSearchConfig
+ Log.Backend.ElasticSearch.Lens: defaultElasticSearchConfig :: ElasticSearchConfig
+ Log.Backend.ElasticSearch.Lens: esIndex :: Lens' ElasticSearchConfig Text
+ Log.Backend.ElasticSearch.Lens: esLogin :: Lens' ElasticSearchConfig (Maybe (EsUsername, EsPassword))
+ Log.Backend.ElasticSearch.Lens: esLoginInsecure :: Lens' ElasticSearchConfig Bool
+ Log.Backend.ElasticSearch.Lens: esMapping :: Lens' ElasticSearchConfig Text
+ Log.Backend.ElasticSearch.Lens: esServer :: Lens' ElasticSearchConfig Text
+ Log.Backend.ElasticSearch.Lens: withElasticSearchLogger :: ElasticSearchConfig -> IO Word32 -> (Logger -> IO r) -> IO r
Files
- log-elasticsearch.cabal +5/−2
- src/Log/Backend/ElasticSearch.hs +25/−20
- src/Log/Backend/ElasticSearch/Internal.hs +26/−0
- src/Log/Backend/ElasticSearch/Lens.hs +40/−0
log-elasticsearch.cabal view
@@ -1,5 +1,5 @@ name: log-elasticsearch-version: 0.7+version: 0.8 synopsis: Structured logging solution (Elasticsearch back end) description: Elasticsearch back end for the 'log' library.@@ -25,15 +25,18 @@ library exposed-modules: Log.Backend.ElasticSearch+ Log.Backend.ElasticSearch.Internal+ Log.Backend.ElasticSearch.Lens build-depends: base <5, log-base >= 0.7, aeson >=0.11.0.0, aeson-pretty >=0.8.2, bytestring, base64-bytestring,- bloodhound >= 0.11.1,+ bloodhound >= 0.11.1 && < 0.13, deepseq, http-client,+ http-client-tls, semigroups, text, text-show >= 2,
src/Log/Backend/ElasticSearch.hs view
@@ -1,10 +1,14 @@ -- | Elasticsearch logging back-end. module Log.Backend.ElasticSearch (- ElasticSearchConfig(..)+ ElasticSearchConfig+ , esServer+ , esIndex+ , esMapping+ , esLogin+ , esLoginInsecure , defaultElasticSearchConfig , withElasticSearchLogger , elasticSearchLogger- ) where import Control.Applicative@@ -17,6 +21,7 @@ import Data.Aeson.Encode.Pretty import Data.Bits import Data.IORef+import Data.Maybe (isJust) import Data.Semigroup import Data.Time import Data.Time.Clock.POSIX@@ -25,6 +30,7 @@ import Log import Log.Internal.Logger import Network.HTTP.Client+import Network.HTTP.Client.TLS (tlsManagerSettings) import Prelude import TextShow import qualified Data.ByteString as BS@@ -36,23 +42,7 @@ import qualified Data.Traversable as F import qualified Data.Vector as V --- | Configuration for the Elasticsearch 'Logger'. See--- <https://www.elastic.co/guide/en/elasticsearch/reference/current/glossary.html>--- for the explanation of terms.-data ElasticSearchConfig = ElasticSearchConfig {- esServer :: !T.Text -- ^ Elasticsearch server address.- , esIndex :: !T.Text -- ^ Elasticsearch index name.- , esMapping :: !T.Text -- ^ Elasticsearch mapping name.- } deriving (Eq, Show)---- | Sensible defaults for 'ElasticSearchConfig'.-defaultElasticSearchConfig :: ElasticSearchConfig-defaultElasticSearchConfig = ElasticSearchConfig {- esServer = "http://localhost:9200",- esIndex = "logs",- esMapping = "log"- }-+import Log.Backend.ElasticSearch.Internal ---------------------------------------- -- | Create an 'elasticSearchLogger' for the duration of the given@@ -77,6 +67,7 @@ -- document IDs. -> IO Logger elasticSearchLogger ElasticSearchConfig{..} genRandomWord = do+ checkElasticSearchLogin checkElasticSearchConnection indexRef <- newIORef $ IndexName T.empty mkBulkLogger "ElasticSearch" (\msgs -> do@@ -159,6 +150,15 @@ indexName <- readIORef indexRef void . runBH_ $ refreshIndex indexName + checkElasticSearchLogin :: IO ()+ checkElasticSearchLogin =+ when (isJust esLogin+ && not esLoginInsecure+ && not ("https:" `T.isPrefixOf` esServer)) $+ error $ "ElasticSearch: insecure login: "+ <> "Attempting to send login credentials over an insecure connection. "+ <> "Set esLoginInsecure = True to disable this check."+ checkElasticSearchConnection :: IO () checkElasticSearchConnection = try (void $ runBH_ listIndices) >>= \case Left (ex::HttpException) -> error $ "ElasticSearch: unexpected error: "@@ -179,7 +179,12 @@ timeToDouble = realToFrac . utcTimeToPOSIXSeconds runBH_ :: forall r. BH IO r -> IO r- runBH_ = withBH defaultManagerSettings server+ runBH_ f = do+ mgr <- newManager tlsManagerSettings+ let hook = maybe return (uncurry basicAuthHook) esLogin+ let env = (mkBHEnv server mgr) { bhRequestHook = hook }+ runBH env f+ jsonToBSL :: Value -> BSL.ByteString jsonToBSL = encodePretty' defConfig { confIndent = Spaces 2 }
+ src/Log/Backend/ElasticSearch/Internal.hs view
@@ -0,0 +1,26 @@+module Log.Backend.ElasticSearch.Internal where++import Database.Bloodhound hiding (Status)+import Prelude+import qualified Data.Text as T++-- | Configuration for the Elasticsearch 'Logger'. See+-- <https://www.elastic.co/guide/en/elasticsearch/reference/current/glossary.html>+-- for the explanation of terms.+data ElasticSearchConfig = ElasticSearchConfig {+ esServer :: !T.Text -- ^ Elasticsearch server address.+ , esIndex :: !T.Text -- ^ Elasticsearch index name.+ , esMapping :: !T.Text -- ^ Elasticsearch mapping name.+ , esLogin :: Maybe (EsUsername, EsPassword) -- ^ Elasticsearch basic authentication username and password.+ , esLoginInsecure :: !Bool -- ^ Allow basic authentication over non-TLS connections.+ } deriving (Eq, Show)++-- | Sensible defaults for 'ElasticSearchConfig'.+defaultElasticSearchConfig :: ElasticSearchConfig+defaultElasticSearchConfig = ElasticSearchConfig {+ esServer = "http://localhost:9200",+ esIndex = "logs",+ esMapping = "log",+ esLogin = Nothing,+ esLoginInsecure = False+ }
+ src/Log/Backend/ElasticSearch/Lens.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE RankNTypes #-}+-- | Lensified version of "Log.Backend.ElasticSearch".+module Log.Backend.ElasticSearch.Lens (+ I.ElasticSearchConfig+ , esServer+ , esIndex+ , esMapping+ , esLogin+ , esLoginInsecure+ , I.defaultElasticSearchConfig+ , I.withElasticSearchLogger+ ) where++import Database.Bloodhound hiding (Status)+import Prelude+import qualified Data.Text as T+import qualified Log.Backend.ElasticSearch as I+import qualified Log.Backend.ElasticSearch.Internal ()++type Lens' s a = forall f. Functor f => (a -> f a) -> s -> f s++-- | Elasticsearch server address.+esServer :: Lens' I.ElasticSearchConfig T.Text+esServer f esc = fmap (\x -> esc { I.esServer = x }) $ f (I.esServer esc)++-- | Elasticsearch index name.+esIndex :: Lens' I.ElasticSearchConfig T.Text+esIndex f esc = fmap (\x -> esc { I.esIndex = x }) $ f (I.esIndex esc)++-- | Elasticsearch mapping name.+esMapping :: Lens' I.ElasticSearchConfig T.Text+esMapping f esc = fmap (\x -> esc { I.esMapping = x }) $ f (I.esMapping esc)++-- | Elasticsearch basic authentication username and password.+esLogin :: Lens' I.ElasticSearchConfig (Maybe (EsUsername, EsPassword))+esLogin f esc = fmap (\x -> esc { I.esLogin = x }) $ f (I.esLogin esc)++-- | Allow basic authentication over non-TLS connections.+esLoginInsecure :: Lens' I.ElasticSearchConfig Bool+esLoginInsecure f esc = fmap (\x -> esc { I.esLoginInsecure = x }) $ f (I.esLoginInsecure esc)