datadog-tracing 1.1.0 → 1.2.0
raw patch · 2 files changed
+64/−15 lines, 2 filesdep +ffunctordep +mtlPVP ok
version bump matches the API change (PVP)
Dependencies added: ffunctor, mtl
API changes (from Hackage documentation)
- Datadog.Client: traces :: NonEmpty Trace -> ClientM ()
- Datadog.Client: validate' :: (Typeable t, Monad m, Show a) => t -> (a -> Bool) -> a -> RefineT m ()
+ Datadog.Client: Agent :: (NonEmpty Trace -> m ()) -> Agent m
+ Datadog.Client: [putTraces] :: Agent m -> NonEmpty Trace -> m ()
+ Datadog.Client: instance Data.FFunctor.FFunctor Datadog.Client.Agent
+ Datadog.Client: instance GHC.Classes.Eq Datadog.Client.MetaValue
+ Datadog.Client: instance GHC.Classes.Eq Datadog.Client.ServiceName
+ Datadog.Client: instance GHC.Classes.Eq Datadog.Client.Span
+ Datadog.Client: instance GHC.Classes.Eq Datadog.Client.SpanId
+ Datadog.Client: instance GHC.Classes.Eq Datadog.Client.SpanName
+ Datadog.Client: instance GHC.Classes.Eq Datadog.Client.Trace
+ Datadog.Client: instance GHC.Classes.Eq Datadog.Client.TraceId
+ Datadog.Client: instance GHC.Show.Show Datadog.Client.MetaKey
+ Datadog.Client: instance GHC.Show.Show Datadog.Client.MetaValue
+ Datadog.Client: instance GHC.Show.Show Datadog.Client.ServiceName
+ Datadog.Client: instance GHC.Show.Show Datadog.Client.Span
+ Datadog.Client: instance GHC.Show.Show Datadog.Client.SpanId
+ Datadog.Client: instance GHC.Show.Show Datadog.Client.SpanName
+ Datadog.Client: instance GHC.Show.Show Datadog.Client.Trace
+ Datadog.Client: instance GHC.Show.Show Datadog.Client.TraceId
+ Datadog.Client: newServantAgent :: (MonadIO m, MonadError ServantError m) => ClientEnv -> Agent m
+ Datadog.Client: newtype Agent m
+ Datadog.Client: type AgentT m = Agent (ExceptT ServantError m)
Files
- datadog-tracing.cabal +4/−2
- library/Datadog/Client.hs +60/−13
datadog-tracing.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: datadog-tracing-version: 1.1.0+version: 1.2.0 synopsis: Datadog tracing client and mock agent. license: BSD-3-Clause license-file: LICENSE@@ -29,6 +29,7 @@ build-depends: , base ^>= 4.11.1.0 || ^>= 4.12.0.0 , bytestring ^>= 0.10.8.2 , containers ^>= 0.5.11.0 || ^>= 0.6.0.1+ , mtl ^>= 2.2.2 , text ^>= 1.2.3.1 , aeson ^>= 1.4.1.0 , servant ^>= 0.14.1@@ -42,7 +43,8 @@ exposed-modules: Datadog.Agent , Datadog.Client , Datadog.Jaeger- build-depends: , generic-random ^>= 1.2.0.0+ build-depends: , ffunctor ^>= 1.1.0+ , generic-random ^>= 1.2.0.0 , refined ^>= 0.2.3.0 , prettyprinter ^>= 1.2.1 , servant-client ^>= 0.14
library/Datadog/Client.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeApplications #-}@@ -9,10 +10,28 @@ -- -- Many of our refinements are stricter than the actual requirements, to err on -- the side of caution, and because the actual requirements are very complex.-module Datadog.Client where+module Datadog.Client (+ Agent(..)+ , AgentT+ , DDText+ , HasAlpha+ , MetaKey(..)+ , MetaValue(..)+ , ServiceName(..)+ , Span(..)+ , SpanId(..)+ , SpanName(..)+ , Tag+ , Trace(..)+ , TraceId(..)+ , newServantAgent+) where import Control.Monad (unless, void)+import Control.Monad.Except (ExceptT, MonadError, MonadIO,+ liftEither, liftIO) import Data.Char (isAlpha, isAsciiLower, isDigit)+import Data.FFunctor (FFunctor, ffmap) import Data.Int (Int64) import qualified Data.List.NonEmpty as NEL import Data.Map.Strict (Map)@@ -25,26 +44,47 @@ import Data.Time.Clock.POSIX (utcTimeToPOSIXSeconds) import Data.Typeable (Proxy (..), Typeable, typeOf) import Data.Word (Word64)-import Refined-import Servant.Client (ClientM, client)+import Refined hiding (NonEmpty)+import qualified Refined+import Servant.Client (ClientEnv, ClientM, ServantError,+ client, runClientM) import qualified Datadog.Agent as API -type DDText = NonEmpty && (SizeLessThan 101)+-- | The Datadog Agent API, independent of any HTTP framework.+newtype Agent m = Agent+ { putTraces :: NEL.NonEmpty Trace -> m ()+ } -newtype SpanId = SpanId (Refined NonZero Word64)-newtype TraceId = TraceId (Refined NonZero Word64)-newtype ServiceName = ServiceName (Refined (DDText && Tag) Text)+-- | Allows users to opt-out of having a MonadError in their Monad stack. They+-- opt-in to error handling at the points when calling the Agent. Requires+-- users to handle errors at the point of use.+--+-- See https://discourse.haskell.org/t/local-capabilities-with-mtl/231+type AgentT m = Agent (ExceptT ServantError m) +instance FFunctor Agent where+ ffmap nt (Agent p1) = Agent (nt . p1)++-- | An Agent (or AgentT) implemented by Servant.+newServantAgent :: (MonadIO m, MonadError ServantError m) => ClientEnv -> Agent m+newServantAgent env = ffmap (liftClientM env) (Agent traces)++type DDText = Refined.NonEmpty && (SizeLessThan 101)++newtype SpanId = SpanId (Refined NonZero Word64) deriving (Eq, Show)+newtype TraceId = TraceId (Refined NonZero Word64) deriving (Eq, Show)+newtype ServiceName = ServiceName (Refined (DDText && Tag) Text) deriving (Eq, Show)+ data Trace = Trace { tService :: ServiceName , tId :: TraceId- , tSpans :: (Refined NonEmpty (Map SpanId Span))- }+ , tSpans :: (Refined (Refined.NonEmpty) (Map SpanId Span))+ } deriving (Eq, Show) -newtype SpanName = SpanName (Refined (DDText && HasAlpha) Text)-newtype MetaKey = MetaKey (Refined (DDText && Tag) Text) deriving (Eq, Ord)-newtype MetaValue = MetaValue (Refined DDText Text)+newtype SpanName = SpanName (Refined (DDText && HasAlpha) Text) deriving (Eq, Show)+newtype MetaKey = MetaKey (Refined (DDText && Tag) Text) deriving (Eq, Ord, Show)+newtype MetaValue = MetaValue (Refined DDText Text) deriving (Eq, Show) data Span = Span { sName :: SpanName@@ -52,7 +92,7 @@ , sStart :: UTCTime , sDuration :: NominalDiffTime , sMeta :: Maybe (Map MetaKey MetaValue)- }+ } deriving (Eq, Show) traces :: NEL.NonEmpty Trace -> ClientM () traces (NEL.toList -> ts) = void . raw $ toAPI <$> ts@@ -117,3 +157,10 @@ validate' t p a = unless (p a) $ throwRefineOtherException (typeOf t) ("failed predicate: " <> (viaShow a))++-- | Converts ClientM signatures into MTL, pushing errors into the stack.+liftClientM :: (MonadIO m, MonadError ServantError m)+ => ClientEnv+ -> ClientM a+ -> m a+liftClientM env ca = liftEither =<< (liftIO $ runClientM ca env)